HD44780 'C' Initialization Code

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

HD44780 'C' Initialization Code

4,718 Views
jonathan_abbati
Contributor III

Hello Friends!

 

I am working with the HD44780 LCD display with the MC9S12DG128 and I was wondering if anyone might know where I may be able to find a set of initialization code for this LCD in 'C'? Thank you so very much for your time and I wish you a most wondrous day.

 

Sincerely,

Jon

Labels (1)
0 Kudos
Reply
8 Replies

1,953 Views
JimDon
Senior Contributor III

Here is code for 4 bit mode.. it is written for the JM but you should be able to get what you need. Teak the delays for you clock speed....

 

 

/* *  LCD - Writes to LCD  *   *  This assumes an HD44780 or compatible LCD. 4 bit interface *  It's been tested on several, and some LCDs seem to need more delay time *  If you get garbage characters, try increasing the delay. *  PTA0 = RS (data/command) (Pin 4 on LCD module) *  PTA1 = EN  (Write pulse) (Pin 6, also called E) *  PTA2 = Data 4  (Pin 11)     *  PTA3 = Data 5  (Pin 12) *  PTA4 = Data 6  (Pin 13)  *  PTA5 = Data 7  (Pin 14) *  Pins 1 & 5 should be 0V on the LCD module *  Pin 5 is R/W and we only use W so ground it *  Pin 3 should go to ground thru a 1K resistor *  Pin 15 is the positive side of the back light LED and can be connected to +5 *  Pin 16 is the ground side of the back light LED, and should go to ground thru a  *  100OHM or higher resistor. You could also hook up a PWM signal here. *  (note: The resistor can be on either side of the LED. You MUST have a resistor) *  thru a transistor for variable back light. *   *  jdonelson 12/10  */// Delay constants for 48MHz clock.// Set to work with CF, too long for 08.#define ENBIT (0x02)#define DELAY40US (104)#define DELAY4_1MS (10761)#define DELAY100US (262)#define LCDWIDTH (16)#define EN_DELAY    (90)static int lcd_width = 0;static int lcd_lines = 0;static void lcd_delay(word count); void InitLCD(int width); static void LCDWrite8BitMode(byte data);void LCDWriteByte(byte data, byte rs);void LCDWriteLine(char *string, byte line);void LCDClear(void);void SetCursorLCD( byte pos);/* *  */static void lcd_delay(word count) {   word i  = 0;   for( i = 0; i < count ; ++i) {      asm {         nop         nop         nop         nop         nop         nop         nop         nop         nop      }   }}int LCDGetWidth(void){ return lcd_width;}/* *  */void LCDInit(int width,int lines) {   int i;   lcd_width = width;  lcd_lines = lines;  // Set bits to output  // PTA0 = RS (0=cmd,1=data) PTA1=EN lo-high-lo to write  // PTA2-5 =Data bits 4-7  PTADD |= 0x3F;  // Enable pull ups.     PTAPE |= 0x3F;  // Write all low;  PTAD &= ~0x3f;    // Need to do this in case still powering up.  // Should be 20MS  for( i = 0 ; i < 250 ; ++i)    lcd_delay(DELAY100US);  // See HD44780 spec. It tells you to do this...  LCDWrite8BitMode(0x30);  // tell it once  lcd_delay(DELAY4_1MS);  LCDWrite8BitMode(0x30);  // tell it twice  lcd_delay(DELAY4_1MS);  LCDWrite8BitMode(0x30);  // tell it thrice  lcd_delay(DELAY4_1MS);  // This sets 4 bit mode, but you can't write the low nibble yet.  LCDWrite8BitMode(0x20);  lcd_delay(DELAY4_1MS);   // Now it's set to 4 bit mode.  // 0 0 1 DL | N F X X  // N = 2/1 line, DL = 8/4 bit F=5x10/5x8  LCDWriteByte(0x28, 0); // last function set: 4-bit mode, 2 lines, 5x8 matrix  lcd_delay(DELAY4_1MS);  // 0 0 0 0 | 1 D C B  // D= Display on off, C = Cursor, B-Blink  LCDWriteByte(0x0c, 0); // display on, cursor off, blink off  lcd_delay(DELAY4_1MS);  LCDWriteByte(0x01, 0); // display clear  lcd_delay(DELAY4_1MS);  // 0 0 0 0 | 0 1 I/D  S  // I/D = Increment/Decrement S = Shift  LCDWriteByte(0x06, 0); // cursor auto-increment, disable display shift  lcd_delay(DELAY4_1MS);  for( i = 0 ; i < lines ; ++i)  {   LCDWriteLine("",(byte) i);  }  }//// Used to write while LCD is still in 8 bit mode.//static void LCDWrite8BitMode(byte data) {  byte shifted;  // Shift the high nibble into proper place  shifted =(byte) (data >> 2);   // Pulse EN line  PTAD = shifted;   // raise the strobe  PTAD |= ENBIT;  // We need thighs because we are too fast.  lcd_delay(EN_DELAY);  // Lower the strobe  PTAD &= ~ENBIT;   // Delay for command to complete.  lcd_delay(DELAY40US);} //// Write 8 bits, 4 bits at a time.//void LCDWriteByte(byte data, byte rs) {  byte high, low;    // Need to do 2x 4 bit writes  // Extract the high nibble and the lo nibble and  // shift them into proper bit positions.  // 'or' in the command/data flag.  high =(byte) (((data & 0xf0) >> 2) | (rs & 0x01)) ;  // Write, sets EN=0  PTAD = high;   // Raise EN bit to strobe data.  PTAD |= ENBIT;   lcd_delay(EN_DELAY);  // Clear EN bit  PTAD &= ~ENBIT;   // Now do lo nibble.  low = (byte) (((data & 0x0f) << 2) | (rs & 0x01)) ;  PTAD = low;   PTAD |= ENBIT;   lcd_delay(EN_DELAY);  PTAD &= ~ENBIT;   // Delay for command to complete.  lcd_delay(DELAY40US);} void LCDWriteLine(char *string, byte line) { byte i=0; byte cmd=0; // Set up which line to write on. // Set "Cursor Address" command. // 1 A A A | A A A A // AAAAAAA can be 00H to 27H  // for the first line, and 40H to 67H for the second line. switch(line)  {  case 0:   cmd = 0x80;   break;  case 1:   cmd = 0xc0;   break;  case 2:   cmd = 0x94;   break;  case 3:   cmd = 0xD4;  default:   ; }  LCDWriteByte( cmd, 0);  // write as command // Clear the line first for( i = 0 ; i < lcd_width ; ++i)  LCDWriteByte( ' ', 1); LCDWriteByte( cmd, 0);  // write as command  // Send out the whole line... for( i = 0; string[i]  &&  i < lcd_width; i++)  {  if( string[i] == '\r' || string[i] == '\n')   continue;  LCDWriteByte( string[i], 1);  }}void LCDWriteBuffer(char *string, int count, byte line) { byte i=0; byte cmd=0; // Set up which line to write on. // Set "Cursor Address" command. // 1 A A A | A A A A // AAAAAAA can be 00H to 27H  // for the first line, and 40H to 67H for the second line. switch(line)  {  case 0:   cmd = 0x80;   break;  case 1:   cmd = 0xc0;   break;  case 2:   cmd = 0x94;   break;  case 3:   cmd = 0xD4;  default:   ; }  LCDWriteByte( cmd, 0);  // write as command // Clear the line first for( i = 0 ; i < lcd_width ; ++i)  LCDWriteByte( ' ', 1); LCDWriteByte( cmd, 0);  // write as command // Send out the whole line... for( i = 0; i < count  &&  i < lcd_width; i++)  {  if( string[i] == '\r' || string[i] == '\n')   continue;  LCDWriteByte( string[i], 1);  }} void SetCursorLCD( byte pos){ LCDWriteByte( pos | 0x80, 0);}

 

0 Kudos
Reply

1,953 Views
bigmac
Specialist III

Hello,

 

I would have one criticism of the attached code.  The LCD connections occupy PTA0 to PTA5 in the example.  This leaves PTA6 and PTA7 that may be used for other purposes.  However, the sample code does not preserve the previous state of these bits but always writes a zero.

 

This problem can be avoided by first clearing bit 0 to 5, and then or-ing the required new state of these bits.  The following modified code sample shows this process.

 

Additionally, the naming of the function LCDWrite8bitMode() seems a little confused to me, since only the upper nybble is actually being written (the LCD inputs for the lower nybble are actually unconnected or grounded).  I prefer the alternative function name LCDWriteInit() that is used only during initialisation of the display.

 

/**********************************************************************/ // Used for LCD initialisation, prior to 4-bit mode currentvoid LCDWriteInit( byte data) {   byte shifted;      PTAD &= 0xC0;               // Clear bits 0-5   PTAD |= (byte)(data >> 2);  // Align data nibble to proper location   PTAD |= ENBIT;              // Raise EN line   lcd_delay( EN_DELAY);   PTAD &= ~ENBIT;             // Lower EN line   lcd_delay( DELAY40US);      // Delay for command completion}  /**********************************************************************/ // Write command/data byte// rs = 0 for command byte, otherwise data bytevoid LCDWriteByte( byte data, byte rs) {   byte high, low;      // Two nybbles must be separately written   // High nybble:   PTAD &= 0xC0;                       // Clear bits 0-5   if (rs)      PTAD |= 0x01;                    // Set RS line   PTAD |= (byte)((data & 0xf0) >> 2); // High nybble   PTAD |= ENBIT;                      // Raise EN line   lcd_delay( EN_DELAY);   PTAD &= ~ENBIT;                     // Lower EN line    // Low nybble:   PTAD &= 0xC1;                       // Clear bits 1-5 (RS unchanged)   PTAD |= (byte)((data & 0x0F) << 2); // Low nybble   PTAD |= ENBIT;                      // Raise EN line   lcd_delay( EN_DELAY);   PTAD &= ~ENBIT;                     // Lower EN line   lcd_delay( DELAY40US);              // Delay for command completion}

 

Regards,

Mac

 

0 Kudos
Reply

1,953 Views
JimDon
Senior Contributor III

While it's generally not a bad idea to do this in general, bits A6/A7 are not pinned on the 64 pin JM, which this code was orginally written for. So it was not really an ovesight, though perhaps not the best method

It's called LCDWrite8bitMode() because the chip is still in 8 bit mode and it is actually writing 8 bit commands, so I found it to be clear. I supppose LCDSet4bitMode would have been even better.

 

 

 

 

0 Kudos
Reply

1,953 Views
abicash
Contributor III

Hello

 

I am trying to run this on a QG8 and a HD44780 but am unable to get it up.

 

I am using PTA3,PTA2,PTA1,PTA0 as data pins and PTB7 = RS , PTB6 = EN

 

I dont understand if i am missing the initialisation or data?

 

Can someone help?

 

Thanks and regards

 

EDIT : have changed the delay for 8MHz bus

0 Kudos
Reply

1,953 Views
bigmac
Specialist III

Hello,

 

The code will obviously need to be modified to reflect that different pins on PTA are used for the data, and the RS and EN control signals originate from a different port.  Perhaps you should post the modified code.

 

Regards,

Mac

 

0 Kudos
Reply

1,953 Views
abicash
Contributor III

Hi Jim

 

Apology to Jon for hijacking his thread.

 

I am interested in using this initialisation for a HD44780 module.

Forgive me if i sound very amateurish..

 

I included this file as LCD.c in my project and from main i init the LCD and when i add the

LCDWriteLine(char *string,byte line)  inside my main ,my compiler posts a syntax error.

I declared a char string[ ] = {"test"} ;  (is that right?)

Can you please educate me with the correct syntax of LCDWriteLine in main() ?

 

will be much appreciated

Thanks and regards

 

 

0 Kudos
Reply

1,953 Views
abicash
Contributor III

I got it...silly mistake...

 

Thanks if you took a look

0 Kudos
Reply

1,953 Views
jonathan_abbati
Contributor III

Thank you so much Jim! I greatly appreciate it. I am going to work with it and see if I can get it to work.

0 Kudos
Reply