DemoQE LCD

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DemoQE LCD

Jump to solution
2,694 Views
trav
Contributor III

I have a DEMOQE board and I'm trying to drive an LCD with.  I'm having problems initializing it in 4-bit mode.  I've gone over the HD44780U datasheet, over and over and still could use some help.

 

I know I don't have any delays in there, as I have been stepping thru it in the simulator.  Also I'm not sure if I'm suppose to strobe the Enable line at the initial passing of 0x03 three times?  Either way it doesn't work.

 

Travis 

#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations *//* Define a shortname for variable types */ typedef unsigned char    UINT8;  /*  8 bits */typedef unsigned short int UINT16; /* 16 bits */typedef unsigned long int  UINT32; /* 32 bits */typedef signed char     INT8;   /*  8 bits */typedef signed short int  INT16;  /* 16 bits */typedef signed long int   INT32;  /* 32 bits */typedef volatile UINT8   VUINT8;  /*  8 bits */typedef volatile UINT16   VUINT16; /* 16 bits */typedef volatile UINT32   VUINT32; /* 32 bits */#define LCD_STROBE_E ((PTCD_PTCD6 = 1),(PTCD_PTCD6=0));//Register select line#define LCD_RSH (PTCD_PTCD4= 1);#define LCD_RSL (PTCD_PTCD4= 0);//Read/Write#define LCD_RWH (PTCD_PTCD5= 1);#define LCD_RWL (PTCD_PTCD5= 0);//Enable line#define LCD_EH (PTCD_PTCD6 = 1);#define LCD_EL (PTCD_PTCD6 = 0);void initLCD(void), LCDCmd(UINT8), LCDChar(UINT8), dsplyString(UINT8 *), chkLCDbusy(void);void delay(int);void main(void) {  initLCD();  LCDChar('a');  while(1){           }   }/***************************  LCD Connections  ****************************4-bit modePTC0-PTC3 = DB4-DB7   Data busPTC4      = RS        Register selectPTC5      = R/W       Read / WritePTC6      = E         EnablePORTC 0b00000000         |||||||         |||---- data bus  0x0F         |||---- RS        0x10         ||----- R/W       0x20         |------ Enable    0x40  */        /***************************  Initialization of LCD  ************************/void initLCD(void) {     PTCDD = 0xFF; //Set PortC as output    PTCD = 0x00;  //Set PortC outputs to 0x00        PTCD=0x03;        PTCD=0x03;            PTCD=0x03;                    LCDCmd(0x28);        LCDCmd(0x08);    LCDCmd(0x01);    LCDCmd(0x06);    LCDCmd(0x0C);  }/****************************  LCD Commands  ****************************//*0x01;    clears screen0x38; sets up the display initalization0x0F; turns display on0x06; sets the cursor on and blinking0x02; move cursor to start and don't destroy data0x18;  shifts cursor to the left when a char is entered0x1C;  shifts cursor to the right when a char is entered0x10;    moves 1 char to the left0x14;    moves 1 char to the right0x80; add this to the address of the display to set the cursor position wanted*/void LCDCmd(UINT8 ch) {    UINT8 ln, un;    //lower and upper nibble    ln = ch & 0x0F;    un = ch >>4;    //chkLCDbusy();        PTCD = un;    LCD_EH;    LCD_EL;       PTCD = ln;    LCD_EH;    LCD_EL;}/**********************  Places a Char on LCD screen  ***********************/void LCDChar(UINT8 ch) {    UINT8 ln, un;    //lower and upper nibble    ln = ch & 0x0F;    un = ch >>4;        //chkLCDbusy();            PTCD = un;    LCD_EH;    LCD_EL;    PTCD = ln;    LCD_EH;    LCD_EL;            }/************************  Places a String on LCD screen  ********************/void dsplyString(UINT8 *msgptr) {  do    {    LCDChar( *msgptr);  }while( *msgptr++ != 0);}/**************************  Checks the LCD Busy line  **********************/void chkLCDbusy(void){    PTCDD = 0xF0;        //make PTC an input    LCD_RWH;               //read mode  while((PTCD & 0x08) == 0x08){;}      PTCD = 0x00;        PTCDD = 0xFF;        //make porta an output }//delay codevoid delay(int cnt)     //accepts value for the amount of delay wanted{ int i;  for(i=0;i<cnt;i++){  }} 
Labels (1)
0 Kudos
1 Solution
660 Views
JSpec
Contributor I
I added longer delay and it worked great, I changed the delay to a short int and changed the delays from 0xff to 65000 and 0x0f to 250

View solution in original post

0 Kudos
7 Replies
659 Views
bigmac
Specialist III

Hello Travis,

 

An old application note AN1745 may be of some interest. While the assembly code within the document is likely of little use, and is intended for an obsolete HC705 device, the LCD initialisation process is described in some detail, and flow diagrams are shown.

 

A further application note AN2940 is less descriptive about the operational details of the LCD, but does have associated code for a LCD driver, written in C.

 

Regards,

Mac

 

Message Edited by bigmac on 2009-03-17 01:31 PM
0 Kudos
660 Views
trav
Contributor III

Ya I've looked at those before with some more understanding but feel I'm doing it right as I had it working earlier.  I think I've stumbled upon something that I'm not used to dealing with, as I've usually using an HC12.  The QE128 shows multiple modules on one pin, and I figured they would all be disabled by default.  Well they were not or so it seems.  I checked my RS pin with a constant signal on it, along with all my other pins when they should have been at rest.  Once I used the processor expert to initialize stuff it has seems to go away.  It's late now, but I'm assuming some variation of my code will work tomorrow.  Atleast I hope.

 

Travis

0 Kudos
660 Views
bigmac
Specialist III

Hello Travis,

 

The alternate RSTO function on the PTC4 pin, that you have allocated to the LCD pin RS, is controlled by the SOPT1 register. This is a write once register, so it is probably a good idea that your initialisation code explicitly writes to this register, possibly with the power up default value.

 

The initLCD() function should strobe the display when the data value 0x3 is present. The strobe pulse should occur three times, with a minimum delay of 4.1ms between the first and second strobes, and a minimum delay of 100us between the second and third strobes, (according to AN1745). The application note also suggests that the value 0x2 be strobed to the display immediately following the third strobe pulse above.

 

I also notice that your code for the functions LCDCmd() and LCDChar() seems identical. You appear not to explicitly clear or set the RS bit, as required. Since RS belongs to the same port as the data nybble, the default value will be clear following the write to the port register, so must be set (when required), prior to each strobe pulse.

 

I would assume that the MCU operates from a supply of 3 volts, and the LCD display from a supply of 5 volts. Additionally, I assume that you do not have additional level shifting circuitry between the the two units. My understanding is that the 3 volt logic swing originating from the MCU will just meet the input logic-high lower limit for the LCD interface, so should be satisfactory. However, if the read of data from the LCD module should be attempted, this is likely to be problematic for the MCU because of over-voltage.

 

I suggest that you do not attempt to read the busy flag, but rely on suitable timing delays for the completion of each command. A 40 us delay should probably be included before the LCDCmd() and LCDChar functions terminate. But note that the Clear Dispay and Home Cursor command require considerably more delay. If delays are used, the RW line might be permanently tied low.

 

Regards,

Mac

Message Edited by bigmac on 2009-03-17 05:49 PM
0 Kudos
660 Views
trav
Contributor III

I got it working, here is my code... I'm just using a for loop as a delay.  I used the Device Initialization tool so I wouldn't have random stuff on the port I used.

 

#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations *//* Define a shortname for variable types */ typedef unsigned char    UINT8;  /*  8 bits */typedef unsigned short int UINT16; /* 16 bits */typedef unsigned long int  UINT32; /* 32 bits */typedef signed char     INT8;   /*  8 bits */typedef signed short int  INT16;  /* 16 bits */typedef signed long int   INT32;  /* 32 bits */typedef volatile UINT8   VUINT8;  /*  8 bits */typedef volatile UINT16   VUINT16; /* 16 bits */typedef volatile UINT32   VUINT32; /* 32 bits *///Register select line#define LCD_RSH (PTDD_PTDD4= 1);#define LCD_RSL (PTDD_PTDD4= 0);//Read/Write#define LCD_RWH (PTDD_PTDD5= 1);#define LCD_RWL (PTDD_PTDD5= 0);//Enable line#define LCD_EH (PTDD_PTDD6 = 1);#define LCD_EL (PTDD_PTDD6 = 0);#define LCD_STROBE_E ((PTDD_PTDD6 = 1),(delay(0xF)),(PTDD_PTDD6=0));void initLCD(void), LCDCmd(UINT8), LCDChar(UINT8), dsplyString(UINT8 *);void delay(UINT8);void main(void) {  MCU_init();  initLCD();    dsplyString("Hello World!");      while(1){         } }/***************************  LCD Connections  ****************************4-bit modePTD0-PTD3 = DB4-DB7   Data busPTD4      = RS        Register selectPTD5      = R/W       Read / WritePTD6      = E         EnablePORTD 0b00000000         |||||||         |||---- data bus  0x0F         |||---- RS        0x10         ||----- R/W       0x20         |------ Enable    0x40  */        /***************************  Initialization of LCD  ************************/void initLCD(void) {     PTDDD = 0xFF; //Set PortC as output    PTDD = 0x00;  //Set PortC outputs to 0x00    LCD_RWL;      //Make sure it's in Write mode        PTDD=0x03;    LCD_STROBE_E;    delay(0xFF);        PTDD=0x03;    LCD_STROBE_E;    delay(0xF);            PTDD=0x03;    LCD_STROBE_E;    delay(0xF);        PTDD=0x02;                    LCD_STROBE_E;    delay(0xF);            LCDCmd(0x28);    LCDCmd(0x08);    LCDCmd(0x01);    LCDCmd(0x06);    LCDCmd(0x0F);}/****************************  LCD Commands  ****************************//*0x01;    clears screen0x38; sets up the display initalization0x0F; turns display on0x06; sets the cursor on and blinking0x02; move cursor to start and don't destroy data0x18;  shifts cursor to the left when a char is entered0x1C;  shifts cursor to the right when a char is entered0x10;    moves 1 char to the left0x14;    moves 1 char to the right0x80; add this to the address of the display to set the cursor position wanted*/void LCDCmd(UINT8 ch) {    UINT8 ln, un;    //lower and upper nibble    ln = ch & 0x0F;    un = ch >>4;    delay(0xFF);    PTDD = un;    LCD_STROBE_E;           delay(0xFF);          PTDD = ln;    LCD_STROBE_E;    }/**********************  Places a Char on LCD screen  ***********************/void LCDChar(UINT8 ch) {    UINT8 ln, un;    //lower and upper nibble    ln = ch & 0x0F;    un = ch >>4;        PTDD = un;       //upper nibble first    LCD_RSH;    LCD_STROBE_E            PTDD = ln;       //lower nibble    LCD_RSH;    LCD_STROBE_E;                LCD_RSL;}/************************  Places a String on LCD screen  ********************/void dsplyString(UINT8 *msgptr) {  while(*msgptr){    LCDChar( *msgptr);    msgptr++;  }}/*************************   delay code  ***************************/void delay(UINT8 cnt){ int i;  for(i=0;i<cnt;i++){  }} 

 

Message Edited by trav on 2009-03-17 12:53 PM
0 Kudos
660 Views
JSpec
Contributor I

I know this an old thread, but I was wondering which micocontroller you used with the DEMOQE baord ... was it the MC9S08QE128 or the MCF51QE128? I tried using the code in codewarrioir 6.2 and nothing seems to be put into the LCD at any time, I am wondering if the device initialization needs to be set in a certain way??

 

Any input would be greatly appreciated!

0 Kudos
660 Views
tlytle
Contributor I

 

I used the MC9S08QE128 device.  I have not used this code in awhile, but I remember having problems with it.  Mainly it was due to not enough delay in the initialization of the LCD.  I remember the code working on a LCD fine, but I tried a VFD and it didn't work or vice versa.  It all depends on the LCD and how much delay it wants.  I just used a generic delay(0xFF) loop for delay, which is going to vary upon the processor speed.  The fast the speed, the faster it will go thru the loop and not give a long enough delay.  Try adding some extra delays to the InitLCD in between LCDcmds.

 

Travis
0 Kudos
661 Views
JSpec
Contributor I
I added longer delay and it worked great, I changed the delay to a short int and changed the delays from 0xff to 65000 and 0x0f to 250
0 Kudos