Interfacing LCD (16 X 2) with Parallel Port

                                                                     By : Sujit K. Nayak



      This a project to interface the Parallel Port to a LCD Module (16Character x 2 Line). These LCD Modules are quite simple to work with, as all the logic required to run them is on board.

       

    Circuit Diagram :

      Parallel Port to 16 Character x 2 Line LCD Schematic

    Circuit Description :

       The LCD panel's Enable and Register Select is connected to the Control Port. The Control Port is an open collector / open drain output. While most Parallel Ports have internal pull-up resistors. Therefore by incorporating the two 10K external pull up resistors, the circuit is more portable for a wider range of computers, some of which may have no internal pull up resistors.

      There no effort to place the Data bus into reverse direction. Therefore I hard wire the R/W line of the LCD panel, into write mode to avoid bus conflicts on the data lines. Due it's unidirectional property, it cannot read back the LCD's internal Busy Flag which tells that, the LCD has accepted and finished processing the last instruction. This problem is overcome by inserting known delays into the program.

      The 10k Potentiometer controls the contrast of the LCD panel. The LCD can be drive by a 5V regulated power supply . 

       

     Source Code :
      /*    LCD Interfacing Softwares			*/                      
      /*  Email   - sanuzr@yahoo.com                                   */
      /*                                                                    */
      /*  Register Select must be connected to Select Printer (PIN 17)      */
      /*  Enable must be connected to Strobe (PIN1)                         */
      /*  DATA 0:7 Connected to DATA 0:7                                    */
      
      #include <dos.h>
      #include <string.h>
      
      #define PORTADDRESS 0x378  /* Port Address*/
      
      #define DATA PORTADDRESS+0
      #define STATUS PORTADDRESS+1
      #define CONTROL PORTADDRESS+2
      
      void main(void)
      {
       char string[] = {"Sanu'z World..... "
      		  "Hey ! Congratulation...       "};
       char init[10];
       int count;
       int len;
       init[0] = 0x0F; /* Init Display */
       init[1] = 0x01; /* Clear Display */
       init[2] = 0x38; /* Dual Line / 8 Bits */
      
       outportb(CONTROL, inportb(CONTROL) & 0xDF); /* Reset Control Port - Make sure Forward Direction */
      
       outportb(CONTROL, inportb(CONTROL) | 0x08); /* Set Select Printer (Register Select) */
      
       for (count = 0; count <= 2; count++)
        {
         outportb(DATA, init[count]);
         outportb(CONTROL,inportb(CONTROL) | 0x01); /* Set Strobe (Enable)*/
         delay(20);                                 /* Larger Delay for INIT */
         outportb(CONTROL,inportb(CONTROL) & 0xFE); /* Reset Strobe (Enable)*/
         delay(20);                                 /* Larger Delay for INIT */
        }
      
       outportb(CONTROL, inportb(CONTROL) & 0xF7);  /* Reset Select Printer (Register Select) */
      
       len = strlen(string);
      
       for (count = 0; count < len; count++)
        {
         outportb(DATA, string[count]);
         outportb(CONTROL,inportb(CONTROL) | 0x01); /* Set Strobe */
         delay(2);
         outportb(CONTROL,inportb(CONTROL) & 0xFE); /* Reset Strobe */
         delay(2);
        }
      }
      

       It's been written for Borland C, in a Microsoft compiler,  the outportb() function should be changed to outp() and inportb() to inp().

      The LCD panel requires a few instructions to be sent, in order to turn on the display and initialise it. This is done by the first for loop . These instructions must be sent to the LCD's Instruction Register which is controlled by the Register Select (Pin 4). When pin 4 is low the instruction register is selected, thus when high the data register must be selected. I connect this to the Parallel Port's Select Printer line which happens to be hardware inverted. Therefore if a '1' is write to bit 3 of the Control Register the Select Printer line goes low.

      First the instructions to the LCD module should be send . Therefore the Register Select line must be low. As it is hardware inverted, we will want to set bit 3 of the Control Register to '1'. However we don't want to upset any other bits on the Control Port. This can be achieved by reading the Control Port and OR'ing 0x80 to it. e.g. outportb(CONTROL), inportb(CONTROL) | 0x08); This will only set bit 3.

      After placing a data byte on the data lines, the LCD module must be signal to read the data. This is done using the Enable line. Data is clocked into the LCD module on the high to low transition. The Strobe is hardware inverted, thus by setting bit 0 of the Control Register we get a high to low transition on the Strobe line. We then wait for a delay, and return the line to a high state ready for the next byte.

      After we initialize the LCD Module, we want to send text to it. Characters are sent to the LCD's Data Port, thus we want to clear bit 3. Once again we must only change the one bit, thus we use outportb(CONTROL, inportb(CONTROL) & 0xF7);. Then we set up another for loop to read a byte from the string and send it to the LCD panel. This is repeated for the length of the string.

      The delays should be suitable for most machines. If the LCD panel is not initializing properly, you can try increasing the delays. Likewise if the panel is skipping characters, e.g. Hy ,Cnr. On the other hand, If the LCD module is repeating characters e.g. SSSaaannnuuu... then you may have a faulting Enable connection. Check your Enable to Strobe connection.






Free Web Hosting