??? 08/04/04 11:56 Read: times Msg Score: 0 -1 Gimmee Code +1 Good Answer/Helpful |
#75401 - RE: ° LCD (44780) works in only ASM not Responding to: ???'s previous message |
I would suggest translating your asm code to 'C'. Be aware that code like P3_3 =1; translates directly into setb P3.3. You may need to sprinkle a few NOP() s into your code especially if you're using a 6 clock or faster cpu. The lcd controllers are slow devices so you need to pay attention to the setup and hold times especially with the faster cpus.
for example: void write_cmd(char cmd) { P1 = cmd; setb RS NOP(); //setup delay setb E NOP(); NOP(); clrb E } On another note, I normally will stay away from polling the ready bit. Why? The lcd's fail sometimes and that will stop other code from running as you have no timeout on the poll. I normally use a delay routine, so if the lcd fails, the code is not hung up waiting for a dead lcd. Also, I tend to use 4 bit mode and write only (RW tied low) to save port pins. Here's some code I use (note: for a 12clock cpu at 12.58MHz): (Ignore the stuff for printf..) // // port 0 // #define LCD_DEN P0.5 // lcd data enable. active high #define LCD_RS P0.4 // lcd register select. 0 = data, 1 = control #define LCD_PORT P0 #define NOP() _opc(0x00) //define the opcode NOP as a 'c' function #pragma warnings = off static void lput_one_char(char c, void *dummy) { lcd_data_wr(c); } /* Warning on this line OK (unused 'dummy') */ #pragma warnings = default int lcd_printf (const char *format, ...) /* Our main entry */ { va_list ap; int nr_of_chars; va_start (ap, format); /* Variable argument begin */ nr_of_chars = _formatted_write (format, lput_one_char, (void *) 0, ap); va_end (ap); /* Variable argument end */ return (nr_of_chars); /* According to ANSI */ } //---------------------------------------------------------------------------- // // // initialise the lcd display // // //---------------------------------------------------------------------------- void lcd_init(void) { delay_100u(50); LCD_PORT = 0xc0; // delay_1ms(150); delay_100u(25); LCD_PORT = 0xc3; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // delay_1ms(50); delay_100u(50); LCD_PORT = 0xc3; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // delay_1ms(50); delay_100u(50); LCD_PORT = 0xc3; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // delay_1ms(10); delay_100u(25); LCD_PORT = 0xc2; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // delay_1ms(10); delay_100u(25); lcd_comm_wr(0x2c); delay_100u(100); lcd_comm_wr(0x0c); delay_100u(100); lcd_comm_wr(0x06); delay_100u(100); lcd_comm_wr(0x01); // delay_1ms(10); delay_100u(50); } //---------------------------------------------------------------------------- // // Locate the lcd cursor. cursor position (0..31) in pos // //---------------------------------------------------------------------------- void locate_cursor(char pos) { if (pos >= 16) lcd_comm_wr(pos + 0xb0); else lcd_comm_wr(pos + 0x80); } //---------------------------------------------------------------------------- // // // send a command to the lcd display. command in A // Zaps: A,B // //---------------------------------------------------------------------------- void lcd_comm_wr(char cmd) { //char a; LCD_RS = 0; if (cmd & 0x10) P0.0 =1; else P0.0 = 0; if (cmd & 0x20) P0.1 =1; else P0.1 = 0; if (cmd & 0x40) P0.2 =1; else P0.2 = 0; if (cmd & 0x80) P0.3 =1; else P0.3 = 0; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; NOP(); NOP(); if (cmd & 0x01) P0.0 =1; else P0.0 = 0; if (cmd & 0x02) P0.1 =1; else P0.1 = 0; if (cmd & 0x04) P0.2 =1; else P0.2 = 0; if (cmd & 0x08) P0.3 =1; else P0.3 = 0; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // a = 25; // while (a!=0) a--; delay_100u(2); } //****************************************************************************** // // // send data to the lcd display. // // //****************************************************************************** void lcd_data_wr(char cmd) { //char a; LCD_RS = 1; if (cmd & 0x10) P0.0 =1; else P0.0 = 0; if (cmd & 0x20) P0.1 =1; else P0.1 = 0; if (cmd & 0x40) P0.2 =1; else P0.2 = 0; if (cmd & 0x80) P0.3 =1; else P0.3 = 0; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; NOP(); NOP(); if (cmd & 0x01) P0.0 =1; else P0.0 = 0; if (cmd & 0x02) P0.1 =1; else P0.1 = 0; if (cmd & 0x04) P0.2 =1; else P0.2 = 0; if (cmd & 0x08) P0.3 =1; else P0.3 = 0; NOP(); NOP(); LCD_DEN = 1; NOP(); NOP(); LCD_DEN = 0; // a = 25; // while (a!=0) a--; delay_100u(2); } //---------------------------------------------------------------------------- // // // Delay routine. dly has # of 100 microseconds to delay // // //---------------------------------------------------------------------------- void delay_100u(char dly) { char a; while (dly!=0) { // a = 54; a = 10; while (a !=0) a--; dly--; } } |