krzyk2 11 Posted February 4, 2012 Share Posted February 4, 2012 Hi, I bought a 16x2 LCD from ebay and wanted to use it in 4 bit mode, with no shift register (I'm waiting for them to come). Maybe it will be useful to someone. The LCD is LMB162ABC-1 which uses ST7066U but it should work on HD44780 drivers. There is a bug in ST7066U documentation regarding 4 bit operation that was very annoying (looked for it about 2 hours). When initializing the 4 bit mode, in documentation it says that DB7/6/5/4 should be set to 0011, but actually DB4 should be set to 0, so nibble should be 0010. The interface is quite simple, just three public functions demonstrated in main.c: lcd_init(); lcd_goto(0,4); lcd_show("Hello"); lcd_goto(1,9); lcd_show("world"); The connections to the uC: * RS - P1.0 * R/W - P2.0 * E - P1.1 * DB4 - P1.2 * DB5 - P1.3 * DB6 - P1.4 * DB7 - P1.5 I didn't use R/W, probably I should connect it to the GND, but maybe I should try to read the busy state instead of using delay functions it would be more robust. BTW. I didn't know that TP1 and TP3 can be used to get 5v from the USB, useful for 3.3v logic, 5v BL LCD lcd_4bit.zip larsie 1 Quote Link to post Share on other sites
MarkoeZ 68 Posted February 5, 2012 Share Posted February 5, 2012 Hi,I bought a 16x2 LCD from ebay and wanted to use it in 4 bit mode, with no shift register (I'm waiting for them to come). Maybe it will be useful to someone. The LCD is LMB162ABC-1 which uses ST7066U but it should work on HD44780 drivers. There is a bug in ST7066U documentation regarding 4 bit operation that was very annoying (looked for it about 2 hours). When initializing the 4 bit mode, in documentation it says that DB7/6/5/4 should be set to 0011, but actually DB4 should be set to 0, so nibble should be 0010. The interface is quite simple, just three public functions demonstrated in main.c: lcd_init(); lcd_goto(0,4); lcd_show("Hello"); lcd_goto(1,9); lcd_show("world"); The connections to the uC: * RS - P1.0 * R/W - P2.0 * E - P1.1 * DB4 - P1.2 * DB5 - P1.3 * DB6 - P1.4 * DB7 - P1.5 I didn't use R/W, probably I should connect it to the GND, but maybe I should try to read the busy state instead of using delay functions it would be more robust. BTW. I didn't know that TP1 and TP3 can be used to get 5v from the USB, useful for 3.3v logic, 5v BL LCD Ooooh need to try this!! Did not know there was an error in the documentation. Been trying to get my display working in 4 bit mode for almost a full day, without success. Eventually got too frustrated and put it in a drawer for a next session another day. So first thing tomorrow im gonna test this and report back. With a big thanks if it works ofcourse Cheers! MarkoeZ Quote Link to post Share on other sites
Alan 11 Posted February 6, 2012 Share Posted February 6, 2012 Did not know there was an error in the documentation. Been trying to get my display working in 4 bit mode for almost a full day, without success. If you're still struggling checking out this page, It helped me out. http://joshuagalloway.com/lcd.html Quote Link to post Share on other sites
timotet 44 Posted February 6, 2012 Share Posted February 6, 2012 this page http://www.geocities.com/dinceraydin/lcd/index.html Has a ton of info on the HD4478 lcd driver IC. He even has a LCD simulator. hope this helps Quote Link to post Share on other sites
nuetron 64 Posted February 6, 2012 Share Posted February 6, 2012 This is how I do it: void initLCD(void){ for(char t=2; t; t--){ wrLCD(0x28,0); wrLCD(0x0E,0); wrLCD(0x01,0); wrLCD(0x06,0); } } void wrLCD(char data, bool rs){ P1DIR |= 0x0F; P2OUT &= ~RW; (bools & rs) ? (P1OUT |= RS) : (P1OUT &= ~RS); for(char two=2; two; two--){ P1OUT &= ~0x0F; // First clear the bits P1OUT |= ((data>>4) & 0x0F); // then set the ones needed P1OUT |= EN; if(!(bools & rs)) __delay_cycles(2000); P1OUT &= ~EN; data <<=4; } } void rdLCD(char* data, bool rs){ *data = 0; P1DIR &= ~0x0F; P2OUT |= RW; (bools & rs) ? (P1OUT |= RS) : (P1OUT &= ~RS); for(char two=2; two; two--){ P1OUT |= EN; *data |= (P1IN & 0x0F); P1OUT &= ~EN; *data <<=4; } } void sendStr(char* string) { while(*string){ // keep going until all chars are sent for(char str = 0; (str<32) && *string; str++){ switch(str & 0x1F){ case 0x00: wrLCD(0x80, 0); break; // first line case 0x10: wrLCD(0xC0, 0); break; // second line } wrLCD(*string, 1); string++; } __delay_cycles(2000000); // delay between screens } } And this is how these are used: initLCD(); // initialization wrLCD('G',1); // write one char char temp=0; // create temp rdLCD(&temp,1); // read the LCD, store the value in temp sendStr("Hello 43oh!"); // write a string of chars Edit: found a better and faster way of setting the nibble to output data. Edit2: found a typo... Quote Link to post Share on other sites
mochouinard 6 Posted February 8, 2012 Share Posted February 8, 2012 Did not know there was an error in the documentation. Been trying to get my display working in 4 bit mode for almost a full day, without success. If you're still struggling checking out this page, It helped me out. http://joshuagalloway.com/lcd.html Warning, there is error in that link you provided. I said so in my header of my HD44780 lib The datasheet from sparkfun seem to be more accurate, but it did help me a little bit... Just don't fully trust it. Quote Link to post Share on other sites
Alan 11 Posted February 18, 2012 Share Posted February 18, 2012 There is a bug in ST7066U documentation regarding 4 bit operation that was very annoying (looked for it about 2 hours). When initializing the 4 bit mode, in documentation it says that DB7/6/5/4 should be set to 0011, but actually DB4 should be set to 0, so nibble should be 0010. Could you give me the whereabouts of said bug? I have a feeling this is not a mistake. If you are referring to the 4 bit initialisation routine of the lcd you are supposed to send upper nibble 0x30 three times (i.e. 8 bit mode) for reasons I am not 100% sure of ( I assume it helps to bring the module up.) You are then expected to clock upper nibble 0x20 which will be treated as 8 bit command 0x20 which will then put the lcd into 4 bit mode and you can continue from there Here is a fragment of my lcd lib - I followed the datasheet and referenced http://joshuagalloway.com/lcd.html to get this working and didn't pick up on any mistakes in either. void lcdInit(void) { /* Setup LCD pins as output - leave other pins as input */ LCD_SET_PINS_OUTPUT(); LCD_SET_PINS_LOW(); LCD_STARTUP_WAIT(); /*Set startup sequence to ensure correct initalisation of lcd*/ /*First*/ lcdSetUpperNibble(ST7066_START_UP_COMMAND); clock(); TIME430_DELAY_MS(5UL); /*Second*/ lcdSetUpperNibble(ST7066_START_UP_COMMAND); clock(); TIME430_DELAY_US(200UL); /*Third*/ lcdSetUpperNibble(ST7066_START_UP_COMMAND); clock(); TIME430_DELAY_US(200UL); /*Set display to 4 bit mode*/ LCD_SET_PINS_INSTRUCTION_WRITE(); lcdSetUpperNibble(ST7066_FUNCTION_SET_BITS | ST7066_BIT_MODE_4); clock(); LCD_COMMAND_WAIT(); /*Set up LCD now that it is in 4 bit mode*/ LCD_FUNCTION_SET(ST7066_BIT_MODE_4 | ST7066_LINE_MODE_2); LCD_CLEAR_DISPLAY(); LCD_RETURN_HOME(); LCD_ENTRY_MODE_SET(ST7066_MOVE_CURSOR_RIGHT); LCD_DISPLAY_ON_OFF(ST7066_DISPLAY_ON); } Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.