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 <pic.h>

    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: