Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio
Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio
Here it is. This is a simple test program for PBP2.5 or lower. Anything you do not understand please ask. The next step is to include the command selection inside the LCD_WRITE subroutine.
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_BuffSize CON 30 'LCD_Buff VAR BYTE[LCD_BuffSize] 'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff 'LCD_BuffLen VAR WORD ; 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_Data = $28 : gosub LCD_Write ; Function Set, 4-bit, 2-line, 5x7 LCD_Data = $0C : gosub LCD_Write ; Display ON LCD_Data = $01 : gosub LCD_Write ; Clear Screen PAUSE 50 LCD_Data = $06 : gosub LCD_Write ; Entry Mode PAUSE 2 ; Let command finish LCD_RS = 1 ;Switch to Data ;Print Static Background to LCD LCD_Data = " " : gosub LCD_Write ;Line 1 LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "S" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "v" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "E" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "l" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$a8 : gosub lcd_write ;Move to start of line 2 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = " " : gosub LCD_Write ;Line 2 LCD_Data = " " : gosub LCD_Write LCD_Data = "D" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "g" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "o" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "L" : gosub LCD_Write LCD_Data = "i" : gosub LCD_Write LCD_Data = "m" : gosub LCD_Write LCD_Data = "i" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "d" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$99 : gosub lcd_write ;Move to line 3 col 6 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = "*" : gosub LCD_Write ;Line 3 LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = "T" : gosub LCD_Write ;Line 4 LCD_Data = "e" : gosub LCD_Write LCD_Data = "s" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "P" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "o" : gosub LCD_Write LCD_Data = "g" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "m" : gosub LCD_Write pause 5000 lcd_rs = 0 ;Command is next lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = " " : gosub LCD_Write ;Clear line 4 and set clock LCD_Data = " " : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write main: ;Count seconds and refresh the clock for hours = 0 to 23 for minutes = 0 to 59 for seconds = 0 to 59 lcd_rs = 0 ;Command is next lcd_data=$DA : gosub lcd_write ;Move to line 4 col 7 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = (hours dig 1)+48 : gosub LCD_Write LCD_Data = (hours dig 0)+48 : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = (minutes dig 1)+48 : gosub LCD_Write LCD_Data = (minutes dig 0)+48 : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = (seconds dig 1)+48 : gosub LCD_Write LCD_Data = (seconds dig 0)+48 : gosub LCD_Write pause 1000 next ;second next ;minute next ;hour goto main LCD_WRITE: 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 return
Steve Earl www.datageo.co.uk
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.
Steve Earl www.datageo.co.uk
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
Steve Earl www.datageo.co.uk
Steve,
I am sorry for the delayed reply : I am not at home on those days.
I had a look to your code : it is a good work and I am waiting to check it soon when the hardware is arrived .
Thanks a lot for the assistance.
I think your work will help a lot of people .
Regards,
Ambrogio
I tried using the on board EEPROM by using DATA and READ.
DATA "This is a string",0
but it stores only alternate characters. I was surprised it worked at all but the alternate characters? There has to be a reason for it to work this way.
Steve Earl www.datageo.co.uk
Bookmarks