/* Delay routtines */ #define FOSC 16000000UL // Using Internal Clock of 16 MHz #define delay_us(x) { unsigned char _dcnt; \ _dcnt = (x)/(24000000UL/FOSC)|1; \ while(--_dcnt != 0) continue; \ }void delay_ms(unsigned int cnt) { unsigned char i; do { i = 5; do { delay_us(164); } while(--i); } while(--cnt); } 4 bit code for a pic 18f lcd interface /* ** LCD Routine ** LCD Data RB7,RB6,RB5,RB4 ** LCD Control: RC7 -> E-Enable, RC6 -> RS-Register Select, R/W-Always 0 */ void LCD_putcmd(unsigned char data,unsigned char cmdtype) { // Put the Upper 4 bits data PORTB = data & 0xF0; RC6=0; // RS = 0 RC7=1; // E = 1 // E=0; write data RC7=0; delay_us(1); // Delay 1us for 16 MHz Internal Clock // cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes if (cmdtype) { // Put the Lower 4 bits data PORTB = (data & 0x0F) << 4; RC6=0; // RS = 0 RC7=1; // E = 1 // E=0; write data RC7=0; delay_us(1); // Delay 1us for 16 MHz Internal Clock } delay_ms(5); // Wait for busy flag (BF) } void LCD_putch(unsigned char data) { // Put the Upper 4 bits data PORTB = data & 0xF0; RC6=1; // RS = 1 RC7=1; // E = 1 // E=0; write data RC7=0; delay_us(1); // Delay 1us for 16 MHz Internal Clock // Put the Lower 4 bits data PORTB = (data & 0x0F) << 4; RC6=1; // RS = 1 RC7=1; // E = 1 // E=0; write data RC7=0; delay_ms(5); // Wait for busy flag (BF) } void LCD_init(void) { // Wait for more than 15 ms after VCC rises to 4.5 V delay_ms(30); // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Wait for more than 4.1 ms delay_ms(8); // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Wait for more than 100 us delay_us(200); // Delay 250us for 16 MHz Internal Clock ; // Send Command 0x30 LCD_putcmd(0x30,LCD_1CYCLE); // Function set: Set interface to be 4 bits long (only 1 cycle write). LCD_putcmd(0x20,LCD_1CYCLE); // Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font) LCD_putcmd(0x28,LCD_2CYCLE); // Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off LCD_putcmd(0x08,LCD_2CYCLE); // Display Clear LCD_putcmd(0x01,LCD_2CYCLE); // Entry Mode Set: I/D=1; Increament, S=0; No shift LCD_putcmd(0x06,LCD_2CYCLE); // Display On, Cursor Off LCD_putcmd(0x0C,LCD_2CYCLE); } void LCD_puts(const char *s) { while(*s != 0) { // While not Null if (*s == '\n') LCD_putcmd(LCD_NEXT_LINE,LCD_2CYCLE); // Goto Second Line else LCD_putch(*s); s++; } }