RS232 LCD Display Driver

PIC16F628 based LCD display driver controllable via serial data input and with a 4 button command interface.

Picture of the finished display

This is a serial data LCD display driver I developed to be used in conjunction with Jeff Keyser’s Wifi router webradio project. In order to get this display driver working together with the router, see the interface related shell scripts for the wifi webradio here.

The driver is laid out to hook up with a 2×40 LCD display but could easily be adapted to suit other displays by adding a scrolling functionality. Right now I did not add this feature due to the lack of such a display for testing.

The main features of this driver are:

  • Works with common HD44780 based LCD displays.
  • Serial Input, only 4 wires needed (Rx, Tx, Vcc, GND).
  • User selectable baud rate (9600 or 19200).
  • 4 Button – Interface with user definable message output and counter value output.
  • User-programmable splashscreen message.
  • User-programmable start message to avoid display from showing boot-time messages.
  • All user definable parameters are programmable via serial port commands, no pic programmer required.
  • User definable parameters stored in EEprom.


The schematic is quite unspectacular, a Pic16F628 at 20Mhz connected to the LCD display over 4 data lines and 3 control lines.

If the driver is to be used on a standard RS232 port of a computer, a line driver/receiver like the MAX232 has to be added to adjust the signal levels. Here in my case, as I connect to the serial port on my router, the line driver/receiver is not required as the voltage level of the routers serial port is already 3.3V.

The buttons are connected to their individual input ports with a pulldown resistor of 10K. Debouncing of the switches is performed in the software on the PIC, so no worry here.

For the LCD contrast adjustment, a simple potentiometer between Vcc and GND has been used. The brightness was ok for me, therefore I did not add any adjustment possibilities there.

As I draw the power from the router’s power supply, which is slightly above 5.1V, I decided to add a voltage regulation in form of a Z-diode of 4.7V and a serial resistor of 3.3R, just to lower the voltage level and the power consumption a little bit.

RS232 LCD Driver Schematic


At power on, the driver cycles the LCD through it’s required initialization sequence. Once the display is initialized, the preprogrammed splashscreen is shown for 1 sec and then the user programmed splash for 2 sec’s.

Then the controller initialize the serial port baud rate and shows the selected baud rate on the screen.

If no value has been configured for the baud rate, default will be 19200 Baud.

Next, the driver will wait for the OP_Start message to appear on the serial port (from host). This feature has been implemented to avoid the display from displaying all kind of strange messages until the OP_start message has been received. This is very useful if you have for example a router’s serial port wired to the driver, which typically broadcasts a lot of boot sequence messages over that port.

Again, if no value has been preset for the OP_start message, the driver will skip this part and go straight to the display routine.

Alternatively, if the OP_message has been set, a push of 2 buttons at the same time will put the driver into display mode.

For display testing and programming I can recommend the Br@y++ Terminal:

This tool makes it very easy to send hex characters necessary for configuration by simply putting $ in front of the hex number.

Example: $07 <=> 0x07

Once the driver has booted up and is in display mode, a button press will make the driver send out the button assigned message over the USART, this at the same baud rate as the specified input baud rate. Appended to the end of the button message is a decimal number counting up or down from 0 to 99  followed by a CR. A button pair will always make one counter count up/down, ie. Button 1/2 and Button 3/4 are always linked to one variable.

This way it is either possible to on the host side to differentiate from 4 different buttons or have 2 button combinations with a value parameter for inc/dec operations.

Display behaviour:

The driver will wrap at the end of the line (after 40 chars) to the 2nd line, once that one is full, it will clear the screen an start from top left.

The driver also recognizes Carriage Return (CR) and Backspace Characters which helps if being used in a real-time display, for example when displaying what you just type.

The HOME_CSR message will clear the screen and home the cursor.

Character Hex Values:

Backspace: 0x08    ; Receipt of this character causes the display to move the cursor one position to the left.

Carriage return: 0x0D  ; Line Feed, Receipt of this character causes the display to move the cursor down to the next line in the same column. The display will scroll up if the cursor was on the last line.

HOME_CSR :      equ 0x02        ; Clear display, home cursor

Special Function messages:

As stated before, the messages sent out at button press as well as splashscreen and op_message are programmable by serial command. The maximum length of each programmable message is fixed in firmware, on trespassing length limit the display will show “MSG OVR” and only store the maximum allowed characters.

Program message command: 0x07 (hex)

Parameter identifiers:

Button 1 message preset: 0x03 (max. length: 10 Chars)

Button 2 message preset: 0x04 (max. length: 10 Chars)

Button 3 message preset: 0x05 (max. length: 10 Chars)

Button 4 message preset: 0x06 (max. length: 10 Chars)

Baudrate preset: 0x01 (max. length: 1 Char)

Splashscreen preset: 0x08 (max. length: 80 Chars)

OP_message preset: 0x09 (max. length: 10 Chars)

In order to initiate programming command mode, a message sequence must be sent to the driver: First, the programming command character (0x07)  followed by the parameter identifier, then the message to be programmed and it is  finished off by repeating the parameter identifier again.

For example, a button 1 message programming sequence would look like this:

0x07 0x03 MESSAGE 0x03

In Br@y terminal you would type:


When setting the baudrate you type $07$01$21$01 for 9600 baud and $07$01$22$01 for 19200. I choose deliberately not to give the possibility to type in the SPBRG value directly since this could create a mess in the setup.

Code details:

I won’t go into details at this point since the code is rather long but it’s pretty well documented in the .asm file, in case somebody is interested in the functionality of a display driver.

A lot of interesting functions like EEprom load/save, lookup table handling as well as ring buffer functionality for the USART input buffer can be found in the code.

Download Code here


This code is presented here for information and NON-commercial applications only.

I cannot be held responsible for any harm or damage you do to yourself your equipment or others.


%d bloggers like this: