1: //LCD Display Module Interfacing Example in Hi-Tech PICCLITE C 2: //Number of PIC pins used: 6 (RB5 - RB0) 3: //This example works for any LCD Module made by Optrex, Hitachi, etc. 4: //Two 4-bit nybbles are sent one after the other from the PIC16F877 to the LCD interface, 5: //as explained in Microchip Application Note AN587 (DS00587B - page 3-205) 6: //Chip Type: PIC16F877 7: //Clock Frequency: 13.5 MHz 8: //Written by KEH on 11/01/2003 9: //LCD Display Type: 20 char X 2 line 10: //*********************************************************************** 11: //LCD Display Module connections to the PIC 12: // LCD Pin LCD Pin # PIC Sig PIC Pin # 13: // 1 GND --- --- 14: // 2 Vcc --- --- 15: // 3 Vee (Gnded for full contrast) 16: // 4 RS RB5 P38 17: // 5 R/W* (Gnded, since we will only write to LCD module) 18: // 6 E RB4 P37 19: // 7-10 DB0-DB3 (Not used) --- 20: // 11 DB4 RB0 P33 21: // 12 DB5 RB1 P34 22: // 13 DB6 RB2 P35 23: // 14 DB7 RB3 P36 24: //*********************************************************************** 25: #include 26: #define RS RB5 27: #define RSCMD 0 28: #define RSDTA 1 29: #define E RB4 30: 31: void initialize_lcd(void); 32: void delayms(unsigned char); 33: void sendnyb(unsigned char); 34: void sendbyte(unsigned char); 35: 36: void main(void) 37: { 38: unsigned char j; 39: PORTB = 0; 40: TRISB = 0xC0; // Make RB5-0 all outputs 41: initialize_lcd(); 42: RS=RSDTA; 43: for(j=0;j<20;j++) 44: sendbyte(j+0x41); 45: RS=RSCMD; 46: sendbyte(0b10101000); //Set DDRAM address command 47: //Format (1 a a a a a a a ) 48: //Set DDRAM address to 0x28 = 40 49: //This is the starting address 50: //of the 2nd row. 51: RS=RSDTA; 52: for(j=0;j<20;j++) 53: sendbyte(j+0x61); 54: for(;;) 55: continue; 56: } 57: 58: 59: void initialize_lcd(void) 60: { 61: //initializes LCD Display 62: delayms(20); 63: RS=RSCMD; 64: E=0; 65: sendnyb(0x3); // Function Set Command, Gen'l format: 0 0 1 DL N F * * 66: delayms(0x5); // Note that DL = 1 => 8-bit interface mode (Display must be started in 8-bit mode) 67: // Note that the N F * * (low order 4 bits) are not connected, and may be any value. 68: sendnyb(0x3); // Repeat a second time. 69: delayms(0x1); 70: sendnyb(0x3); // Repeat a 3rd time 71: sendnyb(0x2); // Function Set Command - Now we can set interface to 4-bit (nybble) mode 72: 73: // Now that we are in nybble mode, we can send all 8 bits of each command via 74: // two back-to-back calls to sendnyb( ). 75: sendbyte(0x28); // Function Set Command Format: 0 0 1 DL N F * * 76: // We just sent: 0 0 1 0 1 0 0 0 77: // DL=0 => 4-bit mode, 78: // N=1 => 1/8 duty cycle 79: // F=0 => 5 X 7 dot font 80: sendbyte(0x08); // Display OFF command 81: sendbyte(0x01); // Clear Display command 82: sendbyte(0x06); // Entry mode set command format: 0 0 0 0 0 1 I/D S 83: // I/D = 1 => Increment display addr ptr. 84: // S = 0 => Do not shift (scroll) display 85: sendbyte(0x0C); // Display ON command 86: } 87: 88: 89: void delayms(unsigned char nrms) 90: { 91: // Uses Timer #2 to delay the nr of ms specified assuming clock freq = 13.5 MHz 92: unsigned char i; 93: T2CON=0b0000111; //Timer 2 tick time = (4/13.5 Mhz)*16 = 210.93 94: for (i = 0; i < nrms; i++) 95: { 96: TMR2=256-211; //Schedule TMR2IF flag to be set in 1 ms 97: TMR2IF = 0; //Clear TMR2IF timeout flag 98: while(TMR2IF == 0) 99: continue; //Wait here for 1 ms, until TMR2IF flag is set 100: } 101: } 102: 103: void sendnyb(unsigned char sendval) 104: { 105: unsigned char portbval; 106: portbval = PORTB; 107: PORTB = (portbval & 0xF0) + (sendval & 0x0F); 108: //Send out most sig 4 bits of sendval on RB3:0 109: delayms(1); 110: E=1; 111: delayms(1); 112: E=0; 113: delayms(1); 114: } 115: 116: void sendbyte(unsigned char sendval) 117: { 118: sendnyb(sendval >> 4); 119: sendnyb(sendval & 0x0f); 120: } 121: 122: