/****************************************/ /* */ /* C driver for sdcc compiler. */ /* 40*4 lcd display */ /* */ /****************************************/ // line 1 0x00 - 0x27 controller 1 // line 2 0x40 - 0x67 controller 1 // line 3 0x00 - 0x27 controller 2 // line 4 0x40 - 0x67 controller 2 #define DB7 PORTCbits.RC7 #define DB6 PORTCbits.RC6 #define DB5 PORTCbits.RC5 #define DB4 PORTCbits.RC4 #define TB7 TRISCbits.TRISC7 #define TB6 TRISCbits.TRISC6 #define TB5 TRISCbits.TRISC5 #define TB4 TRISCbits.TRISC4 #define E1 PORTCbits.RC2 #define E2 PORTCbits.RC3 #define RW PORTCbits.RC1 #define RS PORTCbits.RC0 #define TE1 TRISCbits.TRISC2 #define TE2 TRISCbits.TRISC3 #define TRW TRISCbits.TRISC1 #define TRS TRISCbits.TRISC0 /******************* MACRO's *******************/ #define setE E1 = 1; /* if (activeDisplay == 1) E1 = 1; else E2 = 1; */ #define clearE E1 = 0; /* if (activeDisplay == 1) E1 = 0; else E2 = 0; */ #define setWrite \ if (modeRW == 1) { \ TB7 = 0; \ TB6 = 0; \ TB5 = 0; \ TB4 = 0; \ RW = 0; \ modeRW = 0;} #define setRead \ if (modeRW == 0) { \ TB7 = 1; \ TB6 = 1; \ TB5 = 1; \ TB4 = 1; \ RW = 1; \ modeRW = 1;} /*********************** Globals ************************/ unsigned char activeDisplay; unsigned char modeRW; // 0 = write, 1 = read /************************* Functions ***********************/ void delay_us(unsigned int delay) { unsigned int x; delay = delay / 8; for( x = 0; x < delay; x++ ) { //; Core runs at 48Mhz/12 equals 250ns per cycle _asm nop nop nop nop nop nop nop nop _endasm; } } void delay_ms(unsigned int delay) { int idx; for(idx = 0; idx < delay; idx++ ) delay_us(1000); } void putByte(char byte) // be sure to set the registers for writing { setWrite setE DB7 = (byte >> 7) & 1; DB6 = (byte >> 6) & 1; DB5 = (byte >> 5) & 1; DB4 = (byte >> 4) & 1; delay_us(1000); clearE // En nu low nibble setE DB7 = (byte >> 3) & 1; DB6 = (byte >> 2) & 1; DB5 = (byte >> 1) & 1; DB4 = byte & 1; delay_us(1000); clearE } void nibble() { setE delay_us(1000); clearE } void busyTest(void) { char bit = 0; RS = 0; led_pin = 0; setRead delay_us(500); while (bit != 0) { setE delay_us(200); bit = DB7; clearE delay_us(200); } led_pin = 1; } void LCDClr() { RS = 0; putByte(0x1); busyTest(); } void LCDHome() { RS = 0; putByte(0x2); busyTest(); } void LCDPutChar(char character) { RS = 1; putByte(character); busyTest(); } void WriteLCD( unsigned char* message ) { unsigned char i; for( i=0; i<40; i++ ) { if( !message[i] ) break; LCDPutChar(message[i]); } } void LCD_init() // make sure that the display is configured accordingly { TE1 = 0; TE2 = 0; TRW = 0; TRS = 0; RS = 0; modeRW = 0; activeDisplay = 1; delay_ms(20); putByte(0x03); delay_ms(10); putByte(0x03); delay_us(100); putByte(0x03); delay_us(100); putByte(0x02); delay_us(100); putByte(0x02); delay_ms(10); putByte(0x2C); // write the data interface length, 4-bit, 2 lines, character font: 0b001DNF**, 0x2C busyTest(); putByte(0x08); // turn off the display busyTest(); putByte(0x01); // clear the display busyTest(); putByte(0x10); // cursor move direction: right, no display increment. 0 0 0 1 SC RL * * (00010000) busyTest(); putByte(0x0F); // display on, cursor on, blink on. 0x00001DCB busyTest(); LCDClr(); }