Recently, I did a real time clock using an i2c RTC device, (DS1337). I got to thinking that if I had an LCD display that was i2c I could not only reduce the number of I/O pins needed, but also move to a more 'modular' approach in my projects. The modular approach would also provide me with 'ready made' chunks that I could just hang on the i2c buss as needed. For instance a data logger could now have RTC info for the logging output with the addition of an i2c RTC. I could expand the memory available for data or event capture. You get the idea. Assemble the building blocks and use them as needed, where needed.

I happen to have an unused two line LCD display based on the industry standard Hitachi 44780 controller. Proton makes using an LCD a snap The same for using i2c devices. Now how to combine them?

I started by building an LCD/PICŪ module using a 16F819. The 16F819 has a Synchronous Serial Port, (SSP) with onboard i2c support and 2kb of program memory. I first built the PICŪ on a PICŪ proto board I had on hand. I wired the LCD to it and tested printing to the LCD with a 'Hello World' type program. I used the connection information found in the Proton manual pages for the "Print" command. Once the LCD was known to be working, the next task was to get the PICŪ to receive i2c data and print it to the LCD. I found the "i2c_Slave.bas" program supplied by Crownhill in the samples folder of Proton Development Suite. The i2c_Slave program is a basic skeleton framework for sending and receiving data over the i2c buss.
By adding the appropriate declares for LCD and i2c operation and inserting a small print routine I was in business.
If buff != 0 Then ;Print byte to LCD Print buff buff = 0 ;Clear Buff EndIf

The i2c LCD display works well, however, I did find that after some control commands, ($FE,1 etc), a small (5ms) delay was needed before I sent the next byte to the display. Currently I add this delay in the program that uses the display. I will probably move this to the i2cLCD program in a future version.
This is not intended to be a comprehensive 'how-to', but I hope I have provided enough information for you to be well on your way.
;File Name: i2cLCD101.bas
;Version: 1.0.1
;ProtonPlus DS: v3.1.5
;
;Discription
;Program to read data and format command and print to LCD
;via i2c buss. This program is derived from i2c_Slave.bas
;supplied by Crownhill with Proton Development Suite.
;
;Release History
;v001 Initial prerelease - Tests LCD printing from PICŪ board
;v002 First attempt LCD i2c slave operation
;v003 Basic functions working OK. Unit receives a byte from
; the i2c bus and prints it to the LCD
;v004 Added device address to banner
;v100 First 'working' release
;v101 Removed un-needed SSPCON2
; Revised comments regarding TX & RX
;
; Port A MAP
; Bit Pin Function
; A.0 17 (out) LCD DB4
; A.1 18 (out) LCD DB5
; A.2 01 (out) LCD DB6
; A.3 02 (out) LCD DB7
; A.4 03 (N/A) Not used
;
; Port B MAP
; Bit Pin Function
; B.0 06 (out) LCD EN
; B.1 07 (i2c) SDA
; B.2 08 (out) LCD RS
; B.3 09 (N/A) Not used
; B.4 10 (i2c) SCL
; B.5 11 (N/A) Not used
; B.6 12 (N/A) Not used
; B.7 13 (N/A) Not used
;
Device = 16F819 ;set device hardware type
XTAL = 4 ;Clock freq and type
ALL_DIGITAL true ;All Port A pins digital
Declare OPTIMISER_LEVEL = 0 ;Set optimizer level, 0=none
Declare LCD_TYPE = 0 ;LCD is Alpha
Declare LCD_DTPIN = PORTA.0 ;LCD data line starting port.pin
Declare LCD_ENPIN = PORTB.0 ;LCD EN line
Declare LCD_RSPIN = PORTB.2 ;LCD RS line
Declare LCD_INTERFACE = 4 ;LCD 4 line interface
Declare LCD_LINES = 2 ;LCD number of display lines
Declare SDA_PIN PORTB.1 ;i2c buss SDA
Declare SCL_PIN PORTB.4 ;i2c buss SCL
Declare SLOW_BUS On ;12c bus 100Khz
Symbol null = 0
Symbol LCDdelay = 5 ;LCD control settle delay
Symbol SSPIF PIR1.3 ;SSP (I2C) interrupt flag
Symbol BF SSPSTAT.0 ;SSP (I2C) Buffer Full
Symbol R_W SSPSTAT.2 ;SSP (I2C) Read/Write
Symbol D_A SSPSTAT.5 ;SSP (I2C) Data/Address
Symbol CKP SSPCON.4 ;SSP (I2C) SCK Release Control
Symbol SSPEN SSPCON.5 ;SSP (I2C) Enable
Symbol SSPOV SSPCON.6 ;SSP (I2C) Receive Overflow Indicator
Symbol WCOL SSPCON.7 ;SSP (I2C) Write Collision Detect
Dim buff As Byte ;Data buffer
Init: ;* * * Init routines * * *
SSPADD = 8 ;Make our address 8
SSPCON = $36 ;Set to I2C slave with 7-bit address
GoSub Banner
buff = null ;Clear arrry and buffer
Begin: ;* * * Mainline BEGIN * * *
Loop:
If SSPIF = 1 Then ;Check for I2C interrupt
GoSub i2cSlave
EndIf
SSPOV = 0 ;Clear collisions & error flags
WCOL = 0
If buff != 0 Then ;Print byte to LCD
Print buff
buff = 0 ;Clear Buff
EndIf
GoTo Loop ;Do it all forever
Stop ;* * * Mainline END * * *
i2cSlave: ;I2C slave subroutine
SSPIF = 0 ;Clear interrupt flag
If R_W = 1 Then i2cTX ;Write data TO bus
If BF = 0 Then Return ;Nothing in buffer so exit
If D_A = 1 Then i2cRX ;Data FROM bus (not address)
If SSPBUF != 2 Then Return ;Clear the address from the buffer
Return
i2cRX: ;I2C Read Data From bus
buff = SSPBUF ;Put data into SSPBUF from buff
Return
i2cTX: ;I2C Write Data To bus
SSPBUF = buff ;Put data into buff
CKP = 1 ;Release SCL line
Return
Banner:
Print $fe,1
DelayMS LCDdelay
Print " * i2cLCD101 *"
Print $fe,$c0
Print "LCD Addr:",@SSPADD
DelayMS 5000
Print $fe,1
DelayMS LCDdelay
Return
End
;Version: 1.0.1
;ProtonPlus DS: v3.1.5
;
;Discription
;Program to read data and format command and print to LCD
;via i2c buss. This program is derived from i2c_Slave.bas
;supplied by Crownhill with Proton Development Suite.
;
;Release History
;v001 Initial prerelease - Tests LCD printing from PICŪ board
;v002 First attempt LCD i2c slave operation
;v003 Basic functions working OK. Unit receives a byte from
; the i2c bus and prints it to the LCD
;v004 Added device address to banner
;v100 First 'working' release
;v101 Removed un-needed SSPCON2
; Revised comments regarding TX & RX
;
; Port A MAP
; Bit Pin Function
; A.0 17 (out) LCD DB4
; A.1 18 (out) LCD DB5
; A.2 01 (out) LCD DB6
; A.3 02 (out) LCD DB7
; A.4 03 (N/A) Not used
;
; Port B MAP
; Bit Pin Function
; B.0 06 (out) LCD EN
; B.1 07 (i2c) SDA
; B.2 08 (out) LCD RS
; B.3 09 (N/A) Not used
; B.4 10 (i2c) SCL
; B.5 11 (N/A) Not used
; B.6 12 (N/A) Not used
; B.7 13 (N/A) Not used
;
Device = 16F819 ;set device hardware type
XTAL = 4 ;Clock freq and type
ALL_DIGITAL true ;All Port A pins digital
Declare OPTIMISER_LEVEL = 0 ;Set optimizer level, 0=none
Declare LCD_TYPE = 0 ;LCD is Alpha
Declare LCD_DTPIN = PORTA.0 ;LCD data line starting port.pin
Declare LCD_ENPIN = PORTB.0 ;LCD EN line
Declare LCD_RSPIN = PORTB.2 ;LCD RS line
Declare LCD_INTERFACE = 4 ;LCD 4 line interface
Declare LCD_LINES = 2 ;LCD number of display lines
Declare SDA_PIN PORTB.1 ;i2c buss SDA
Declare SCL_PIN PORTB.4 ;i2c buss SCL
Declare SLOW_BUS On ;12c bus 100Khz
Symbol null = 0
Symbol LCDdelay = 5 ;LCD control settle delay
Symbol SSPIF PIR1.3 ;SSP (I2C) interrupt flag
Symbol BF SSPSTAT.0 ;SSP (I2C) Buffer Full
Symbol R_W SSPSTAT.2 ;SSP (I2C) Read/Write
Symbol D_A SSPSTAT.5 ;SSP (I2C) Data/Address
Symbol CKP SSPCON.4 ;SSP (I2C) SCK Release Control
Symbol SSPEN SSPCON.5 ;SSP (I2C) Enable
Symbol SSPOV SSPCON.6 ;SSP (I2C) Receive Overflow Indicator
Symbol WCOL SSPCON.7 ;SSP (I2C) Write Collision Detect
Dim buff As Byte ;Data buffer
Init: ;* * * Init routines * * *
SSPADD = 8 ;Make our address 8
SSPCON = $36 ;Set to I2C slave with 7-bit address
GoSub Banner
buff = null ;Clear arrry and buffer
Begin: ;* * * Mainline BEGIN * * *
Loop:
If SSPIF = 1 Then ;Check for I2C interrupt
GoSub i2cSlave
EndIf
SSPOV = 0 ;Clear collisions & error flags
WCOL = 0
If buff != 0 Then ;Print byte to LCD
Print buff
buff = 0 ;Clear Buff
EndIf
GoTo Loop ;Do it all forever
Stop ;* * * Mainline END * * *
i2cSlave: ;I2C slave subroutine
SSPIF = 0 ;Clear interrupt flag
If R_W = 1 Then i2cTX ;Write data TO bus
If BF = 0 Then Return ;Nothing in buffer so exit
If D_A = 1 Then i2cRX ;Data FROM bus (not address)
If SSPBUF != 2 Then Return ;Clear the address from the buffer
Return
i2cRX: ;I2C Read Data From bus
buff = SSPBUF ;Put data into SSPBUF from buff
Return
i2cTX: ;I2C Write Data To bus
SSPBUF = buff ;Put data into buff
CKP = 1 ;Release SCL line
Return
Banner:
Print $fe,1
DelayMS LCDdelay
Print " * i2cLCD101 *"
Print $fe,$c0
Print "LCD Addr:",@SSPADD
DelayMS 5000
Print $fe,1
DelayMS LCDdelay
Return
End
<sigridco> <AT> <neo.> <rr.> <com>
Sorry for the 'assemble it yourself' address but I'm trying to cut down on the spam.
contributed by Eric J Marang.


Menu
Recent Articles


Using PDS with SPI GLCD based on ST7565R Controller
Graphic LCDs based on the ST7565 are cheaper then GLCDs with other controllers. SPI requires only four pins. If the circuit