Having designed a few hundred PIC circuits at work I thought perhaps I could contribute some of my more useful designs.

This is an LCD interface that allows a serial communications connection either via RS232 COM port or connected to another PIC. It uses a standard parallel LCD module connected to it (4-bit mode). It also has an interface for analog or digital addons. Example a LM35 or similar 5V solid state temperature sensor (10mV/Degree) can be added. In this case a 1.024V reference is available to make conversion easy with a resolution of 1 bit = .1 degree. Or put a pot on and use voltage ref = VCC for the ADC configuration.

A digital temperature sensor can also be added. The code here is only for the serial-parallel control and any additional addon code is up to the user. I refer to it as Universal as it can use a power supply from +5V to 24V and a jumper to select serial inverted or non-inverted logic. Prevents having to reprogram it depending on interface used.

Communication protocol is straight forward. "S" for start followed by line number (1-4) then string data terminated with EOL (10). Baud rate default is 9600 8,n,1

Schematic
Name:  SERIAL LCD SCHEMATIC.jpg
Views: 1718
Size:  94.0 KB

PCB
Name:  SERIAL LCD PCB.jpg
Views: 1362
Size:  153.0 KB

Code
Code:
'Serial LCD program  for PCB SERLCD4B.PCB - SERLCD4B.SCH
'Version 3.0  GOOD
'December 2003 original design
'Sept 25 Increased buffer to 40 and initialize it everytime in the main loop
'
'Sept 6, 2007 modified to support 4 line displays
'Buffer count increased to 40 for 4x20 character displays
'
'Sept 24, 2011 modified for new board & 16F819. Includes jumper to select
'Between TTL or RS232 modes.
'
'May 3, 2012 - support for LM35 or Serial Temp/Hum digital sensor
'
'*******************************************************************
@  __CONFIG  _INTRC_IO & _WDT_OFF & _PWRTE_ON & _LVP_OFF & _CP_OFF & _MCLR_OFF   'FOR 819
'
TRISA = %11111100    
TRISB = %00001111    ' 1=INPUT 0=OUTPUT  
ADCON0 = 0           ' ADC OFF
ADCON1 = 7           ' ALL DIGITAL
DEFINE OSC  8        ' PIC16F819
OSCCON = %01110010   ' 8 MHz
CCP1CON = 0          ' DISABLE COMPARATORS
'
'Port Definitions 
'PORTA.0 ANALOG INPUT (LM35) OR TH CLOCK
'PORTA.1 TH DATA (HUMIDITY/TEMPERATURE SENSOR)
'PORTA.2 CHIP ENABLE
'PORTA.3 ADC VREF 1.024V
'PORTA.4 RS (REGISTER SELECT)
'
'PORTB.1 - SERIAL RX DATA
'PORTB.4 - PORTB.7  LCD DATA (4-BIT)
'PORTB.5 - MCLR - RESET
'
'LCD Control Registers
DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 2
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2
DEFINE LCD_COMMANDUS 2000
DEFINE LCD_DATAUS 50
'
EOL           con 10         'End of line character (Line Feed)
START       con "S"        'Serial Wait character
LINENUM    var byte       'Which line data is arriving 1=line 1 2=line2
'EG. "S1" = Read line 1 "S2" = Read line 2
LINEDATA    var byte(40)   '"S3" = Clear Display  "S4" = Change serial mode
charcount    var byte
testchar      var byte       'Look for nulls in array
COMM         VAR PORTB.0    '1=TTL(INVERTED) 0=RS232(NONINV) JUMPER IN FOR RS232
SERIAL       VAR PORTB.1    'SERIAL input
MODE         VAR BIT        'FLAG TO DETERMINE COMMUNICATION MODE, SEE COMM ABOVE
TTL            CON 1
RS232        CON 0
'
IF COMM = 1 THEN
  MODE = TTL
ELSE
  MODE = RS232
ENDIF
'
pause 500 'Let LCD initialize
lcdout $FE, 1,   "  SYSTEM READY  " 'Clear Display and display message
' $FE=COMMAND $C0 = line2  $94 = line3   $D4 = line 4   1 = CLEAR DISPLAY 2=BEGINNING OF LINE 1

Main:
'wait for start then load array
  FOR charcount = 0 to 39     'Initialize array
    linedata(charcount) = " "
  next 
  IF MODE = TTL THEN 
    SERIN2 SERIAL, 16468 , [WAIT (start), linenum, str linedata\40\eol]      '9600
  ELSE   'NONINV RS232
    SERIN2 SERIAL, 94 , [WAIT (start), linenum, str linedata\40\eol]         '9600
  ENDIF  
  for charcount = 0 to 19
    testchar = linedata(charcount)
    if testchar = 0 then   'if null then make it a space character
      linedata(charcount) = " "
    endif  
  next  
  if LINENUM = "1" then
    lcdout $FE,2,"                    "   'fill with spaces rather then reset display
    lcdout $FE, 2, STR LINEDATA\20        'faster this way
  endif
  if LINENUM = "2" then
    lcdout $FE,$C0,"                    " 'fill with spaces rather then reset display
    LCDOUT $FE, $C0, STR LINEDATA\20
  endif
  if LINENUM = "3" then 
    lcdout $FE,$94,"                    " 'fill with spaces rather then reset display
    LCDOUT $FE, $94, STR LINEDATA\20
  endif
  if LINENUM = "4" then 
    lcdout $FE,$D4,"                    " 'fill with spaces rather then reset display
    LCDOUT $FE, $D4, STR LINEDATA\20
  endif
  if LINENUM = "R" then 'RESET
    lcdout $FE, 1,  "  SYSTEM READY  " 'Clear Display and display message
  endif
GoTo main