Beyond Logic

Interfacing Example - Connecting a LCD Module to the RS-232 Port.

    This interfacing example shows how to hook up a 2 line x 16 character LCD display up to your Serial/RS-232 Port so that anything sent via the serial port, will be displayed on the LCD's Screen. It also uses the Request to Send line to demonstrate the use of the RS-232's Handshaking lines.

    So you are probably thinking, wouldn't it be easier to connect the LCD Display to your Parallel Port? After all it would require very few external components as the LCD already accepts data in a parallel fashion!

    However the Parallel Port requires many wires which don't tolerate traveling long distances. Say you wanted to connect a remote display somewhere a reasonable distance from your computer. Using a serial port you only require 3 wires, DTR, TD and GND. Think of how much cheaper the cable will be, and RS-232 withstands greater distances than Parallel Transmission.

    Another Advantage is that many people have spare COM Ports, whereas the Printer is normally connected to the only LPT Port you have. Disadvantages is the cost of the hardware at the end which has to convert the Serial Transmission back into Parallel for the LCD Module.



Circuit Description

While the circuit looks quite complicated, it is really quite simple once you grasp what I.C's do what tasks. If we start with the connection to the RS-232 Port, all the signals pass through the MAX-232, RS-232 Level Converter.This simply converts the RS-232 Voltage levels into 0 to 5 volts for the UART and LCD Module.

The UART (CDP6402R) then has the job to transfer the Serial Data into Parallel Data, which is then available on the Receiver Buffer Register Pins, RBR 8 to 1. When the UART receives a byte, it signals this by asserting the Data Received (DR) line high. This will stay high, until the Data Received line is reset. This is done by making Data Received Reset (nDRR) low, thus the use of the Inverter. The LCD Display also requires a high to low Transition on it's enable pin to accept data.

The UART requires a clock input, 16 times greater than the Baud Rate it uses. This is generated by the 74HC4060, 14 bit binary counter/divider. With a 2.4576 Mhz crystal, the frequency at Q4 (Pin 7) is 153.6 Khz. When divided by 16, it gives us 9600 BPS, thus this is our transmission speed. The other Communications Parameters are set by the CDP6402's Control Register.

The Control Register Consists of Parity Inhibit (PI), Stop Bit Select (SBS), Character Length Select (CLS1 and 2) and Even Parity Enable (EPE). These inputs can be latched using the Control Register Load (CRL) or if you tie this pin high like what we have done here, changes made to these pins will immediately take effect. The Current Configuration is 8N1, i.e. 8 Data Bits, No Parity and 1 Stop Bit.

The 2 Line x 16 Character LCD Modules are available from a wide range of manufacturers and should all be compatible. The one I used to test this circuit was a Powertip PC-1602F and a old Philips LTN211F-10 which was extracted from a Poker Machine! The diagram to the right, shows the Pin Numbers for these devices. When viewed from the front, the left pin is Pin 14 and the Right pin is Pin 1.
Pin Diagram of LCD Module

The LCD Display circuit uses a Handshaking line as well as the Transmit Data line from the Serial Port. This line, the DTR (Data Terminal Ready) is connected to the Register Select of the LCD Display. When this line is low the Instruction Register is selected and when high, the Data Register is Selected. The Instruction Register is used to initialize the display, while the Data Register is where you send you data to be displayed.

The LCD Module has a facility where we can read back it's status. This is not used here thus the LCD's read/write pin in tied low for write operations only. Pin 3 of the LCD (Vo) is used to adjust the Contrast of the Display, thus we have connected a pretty standard 10K potentiometer as a contrast adjustment. As the CDP6402R is a CMOS Device, all unused inputs should be tied to either supply rail. This also applies to other CMOS Devices.

Programming - Source Code

Below you will find some basic source code written in C for use with the above circuit. The program only sends (outputs) data via the RS-232 Port, and doesn't receive any data. The communications format use is 8N1 at 9600 BPS.

    /* Name       : Sample LCD Program for Serial/RS-232 Port  */
    /* Written By : Craig Peacock <> 1997 */
    #include <dos.h>
    #include <stdio.h>
    #include <conio.h>
    #define PORT1 0x3E8  /* Port Address Goes Here */
      /* Defines Serial Ports Base Address */
      /* COM1 0x3F8                        */
      /* COM2 0x2F8			       */
      /* COM3 0x3E8			       */
      /* COM4 0x2E8			       */
    void main(void)
     int c;
     int count;
     char init[] = { 0x0F, 0x01, 0x38 };
                     /* 0x0F - Init Display */
                     /* 0x01 - Clear Display */
                     /* 0x38 - Dual Line / 8 Bits */
     outportb(PORT1 + 1 , 0x0);   /* Turn off interrupts - Port1 */
     outportb(PORT1 + 3 , 0x80);  /* SET DLAB ON */
     outportb(PORT1 + 0 , 0x0C);  /* Set Baud rate - Divisor Latch Low Byte */
    			      /*         0x06 =  19,200 BPS */
    			      /*         0x0C =   9,600 BPS */
    			      /*         0x18 =   4,800 BPS */
    			      /*         0x30 =   2,400 BPS */
     outportb(PORT1 + 1 , 0x00);  /* Set Baud rate - Divisor Latch High Byte */
     outportb(PORT1 + 3 , 0x03);  /* 8 Bits, No Parity, 1 Stop Bit */
     outportb(PORT1 + 2 , 0xC7);  /* FIFO Control Register */
     outportb(PORT1 + 4 , 0x0B);  /* Turn on DTR, RTS, and OUT2 */
     outportb(PORT1 + 4 , (inportb(PORT1 + 4) | 0x01)); /* Register Select (DTR) */
    						    /* 0 = Instruction Register */
     for (count = 0; count < 3; count++)
       outportb(PORT1, init[count]);      /* Send Init Data Bytes */
       delay(20);                         /* Larger Delay for INIT */
     outportb(PORT1 + 4 , (inportb(PORT1 + 4) & 0xFE)); /* Register Select (DTR) */
    						    /* 1 = Data Register */
     printf("\nSample Serial LCD Program. Press ESC to quit \n");
     do {
         if (kbhit()){
    		  c = getch();
    		  outportb(PORT1, c);
        } while (c !=27);

The software is quite similar to that of a Terminal program except that it doesn't receive data. Any data sent, is immediately echoed on the screen and doesn't come from the Serial Port. Therefore this will be no indication that the circuit is working or is connected. The first 7 outport statements initialize the PC's RS-232 using the circuits default communications format.

The Data Terminal Ready signal, like the other handshaking signals is regarded as active high at the Serial Port. Setting Bit 0 of the Modem Control Register (MCR - Base + 4) will force the Data Terminal Ready Line High, i.e. it will place +3 to +25 volts on Pin 4 of the Serial Port. As this is feed into the MAX-232 RS-232 Level Converter, which inverts the signal, we must write a 1 to the MCR Bit 0, in order to select the Instruction Register. This is what is done with the next outport instruction.

The software then sends three Instructions contained within the Init array. These three bytes initialize the display as a dual line LCD, with both the cursor on and blinking. This first byte, 0x0F Initializes the display, the next byte, 0x01 clears the display and the last byte, 0x38 sets up a dual line display accepting 8 bit words. For more information on these instructions consult Peer Ouwehand's How to control HD44780-based Character-LCD

The LCD's Enable must now go high, in order to send data to it. Once this has been achieved, the program then loops waiting for a key to be pressed before it sends it to the RS-232 Port and prints it to the screen. Pressing the ESC key, stops this repetition and exits the program.

Note : The above program doesn't use Interrupts, thus you can disable the IRQ on your serial card. This may come in handy if you have a spare COM Port Card, and don't have any spare IRQ's to assign to it.

Wong Jit Chin has also written a program in Turbo Pascal 7 for controlling the above project. This source code can be downloaded from his site at Even if you are not a Turbo Pascal person, Wong has included an executable of an Extremely User-Friendly version of the above software with WYSIWYG facility. His site is well worth a look.

Applications & Variations to the Circuit.

    Inverting the Data Terminal Ready.

    The above circuit has been kept as simple as possible. This means the Data Terminal Ready is not inverted. As most inverters will come in packages of 6, you will have 5 spare inverters to play with. One option would be to invert the Data Terminal Ready signal, as it comes out of the MAX-232. This will extend the usefulness of the circuit.

    Most terminal programs, such as Telemate and Procomm will set the Data Terminal Ready high upon entering the program. After all the Data Terminal (The Program) is Ready. With the circuit's current configuration, this will cause the Instruction Register to be selected. However if we were to invert the signal, then the LCD's Data Register will be selected.

    Monitoring Modems or Serial Transmission Lines.

    With the Data Register selected, anything you type in the terminal program will be displayed to the LCD's Screen, ideal for debugging Modem Initialization strings. This will of course be only possible if the LCD is first initialized. You could write a quick and simple program to do this and run it before entering your communications program.

    However when monitoring Modem Initialization strings the LCD won't reply back with OK or the numeric response for OK, and thus your program will not find a modem. Another option may be to connect the LCD in-line with your modems cable. This way everything will work just like normal when a modem is connected, but the LCD is monitoring every byte sent.

    Unfortunately, there are always problems to everything you dream up. The LCD modules require a certain amount of time to process the data, before the next byte can be sent. Therefore at higher transmission speeds the LCD will miss bytes, or refuse to run completely. Therefore use a lower Speed.

    Another problem which plagues the 2 Line by 16 Character display, is it advances to the next line after 40 characters have been received, i.e. the display only shows the first 16 characters of a 40 character line. You can shift the display left and right, but in this application it creates a problem. A alternative is to upgrade to a 40 Column Display.

    Remote Keypad/LCD

    The transmitter is left disconnected on the UART, but the Transmitter Register Out (TRO) has been connected to the Serial Port Via the MAX-232. Should you not require the use of the transmitter it will save a few connections. Just remember if you are using a CMOS device, any inputs should be tied to either logic level so that the inputs don't oscillate.

    However should we chose, we can use the transmitter with some other input device such as a keypad or credit card reader to make a remote keypad. The Liquid Crystal Display could give the user some status, while they are swiping their card or pressing keys. Being connected to the serial port, you will only require a minimum of wires which can extend for quite some distance. This being just two advantages of using serial over parallel transmission.

    Should you wish to do this, then a 4 by 4 Matrix Keypad could be connected to a 74C922 16 Key to Binary Encoder. This 16 Key to Binary Encoder provides debouncing of the keys, with a 4 bit binary output according to what key you pressed. A Data Available line on the 74C922 goes high when a key is pressed and low once it has been released.

    The Data Available line can be connected up to the UART's Transmitter Buffer Register Load (nTBRL) via an inverter. When a Key is pressed, data is loaded into the UART's Transmitter Buffer, and when the key is released, it is sent down the serial line.

    Schematic of RS-232 Keypad Interface

    The possibilities of such a circuit is almost endless.

Data Sheets and other Useful Links.

    Manufacturers Data Sheets

    Data Sheets for some of the I.C's used in this example can sought on-line from the Internet. This is a list of where the Author obtained his data sheets from. Some semiconductors may be available from other manufacturers. The URL for the manufacturer's homepage is given. You will need to search for the data sheet using their site's search engine.

    I.C's NamePart NumberLink to Manufacturers Homepage
    CMOS Universal Asynchronous Receiver/Transmitter (UART)CDP6402Harris Semiconductor
    RS-232 Level ConverterMAX232Maxim Integrated Products
    14 Stage Binary Counter74HC4060National Semiconductor

    Links to other information.

    Wong Jit Chin's Home Page Wong Jit Chin has very kindly written some Turbo Pascal Source code for the above project, thus if Pascal is your perferred language, try out this very useful site. He also includes an executable of an Extremely User-Friendly version of the above software with WYSIWYG facility.

    How to control HD44780-based Character-LCD Should you want to know more about the LCD Modules, Peer Ouwehand has done a wonderful job of it or presenting it all. Well worth a look.

    LCD Information and Technical Forum A good webpage which includes information on many different types of LCD's. Also includes a LCD Forum.

Copyright 2002-2010 Craig Peacock - 25th October 2010.