
Originally Posted by
EarlyBird2
Ambrogio,
Any feedback?
If you have no questions then I will post the next improvement which includes the command in the LCD_Write subroutine. I am now looking at using arrays as the next step.
Here it is! including LOOKUP and ARRAYs.
Code:
'****************************************************************
'* Name : I2CLCD.BAS *
'* Author : Steve Earl *
'* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 17/07/2014 *
'* Version : 1.0 *
'* Notes : Serial I2C LCD using PBP 2.5 *
'* : PCF8574T I2C port expander 20x4 LCD *
'****************************************************************
define OSC 40 ' set the correct speed here!!
'DEFINE I2C_SLOW 1
SDA VAR PORTD.2 ; I2C Data pin
SCL VAR PORTD.3 ; I2C Clock Pin
LCD_Addr CON 78 ; PCF8574T address
LCD_Line_1 con $80
LCD_Line_2 con $A8
LCD_Line_3 con $94
LCD_Line_4 con $D4
LCD_BuffSize CON 22
LCD_Buff VAR BYTE[LCD_BuffSize]
'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff
LCD_BuffLen VAR byte ; Length of data in buffer
LCD_Data VAR BYTE ; Data to Send to LCD
LCD_Byte VAR BYTE ; Nibbles to Send
LCD_RS VAR LCD_Byte.0 ; Register Select bit
LCD_RW VAR LCD_Byte.1 ; Read/Write bit
LCD_E VAR LCD_Byte.2 ; Enable bit
LCD_BackLight VAR LCD_Byte.3 ; Backlight 1=ON
LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both
LCD_CommandMode VAR BIT ; Indicates next byte is a command
LCD_Byte2 VAR BYTE ; Same nibble without E bit
LCD_Idx VAR BYTE
seconds var byte
minutes var byte
hours var byte
Init:
;----[Initialize the LCD]-------------------------------------------------------
PAUSE 250 ; LCD Power-on delay
LCD_Backlight = 1 ; Backlight On
LCD_RW = 0 ; Write to LCD
LCD_RS = 0 ; Command Register
LCD_WriteMode = 1 ;-- Low Nibbles only
LCD_Data = 3 ; Software Reset 3 times
gosub LCD_Write : PAUSEUS 6000
gosub LCD_Write : PAUSEUS 1000
gosub LCD_Write : PAUSEUS 1000
LCD_Data = 2 ; Start 4-bit mode
gosub LCD_Write : PAUSEUS 1000
LCD_WriteMode = 3 ;-- Both Nibbles
LCD_buff[0] = $28 ; Function Set, 4-bit, 2-line
LCD_buff[1] = $0C ; Display ON
LCD_buff[2] = $FE
LCD_buff[3] = $06 ; Entry Mode
LCD_buff[4] = $FE
LCD_buff[5] = $01 ; Clear Screen
lcd_bufflen = 6
gosub LCD_Buff_Write
;Print Static Background to LCD
for lcd_idx = 0 to 85
;| | 20 characters
lookup lcd_idx,[" Steve Earl ",_ ;20
$FE,lcd_line_2," Datageo Limited ",_ ;+22 = 42
$FE,lcd_line_3," ********** ",_ ;+22 = 64
$FE,lcd_line_4," 00:00:00 "],lcd_data ;+22 = 86 (0-85)
gosub lcd_write
next
;Set up fixed buffer characters
lcd_bufflen = 10 ;8 characters in clock + $FE + LCD_Line
LCD_buff[0] = $FE ;Command is next
LCD_buff[1] = lcd_line_4 + 6 ;Move to line 4 col 7
LCD_buff[4] = ":" ;Fixed characters
LCD_buff[7] = ":" ; "
main: ;Count seconds and refresh the clock
for hours = 0 to 23
for minutes = 0 to 59
for seconds = 0 to 59
LCD_buff[2] = (hours dig 1)+48
LCD_buff[3] = (hours dig 0)+48
LCD_buff[5] = (minutes dig 1)+48
LCD_buff[6] = (minutes dig 0)+48
LCD_buff[8] = (seconds dig 1)+48
LCD_buff[9]= (seconds dig 0)+48
gosub lcd_buff_write
pause 1000
next ;second
next ;minute
next ;hour
goto main
LCD_WRITE:
if lcd_data = $FE then
lcd_commandMode = 1 ;Next byte Command
lcd_rs = 0 ;Switch to Command Register
else
LCD_E = 1
IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble
LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble
LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0)
LCD_Byte2 = LCD_Byte & $FB
I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2]
ENDIF
if lcd_commandmode then
lcd_commandmode = 0 ;Reset to data
lcd_rs = 1 ;Switch to Data Register
pause 2
endif
endif
return
Lcd_Buff_Write:
for lcd_idx = 0 to lcd_bufflen - 1
lcd_data=lcd_buff[LCD_idx]
gosub LCD_Write
next
return
Bookmarks