A while back I was trying to help someone with a 24FC1025 and I was having problems with PBP I2C so I decided to work with the part the "old fashioned" way using SHIFTIN and SHIFTOUT. Turns out my problem was using an analog pin on the PIC without setting it to digital. Yes, a typical mistake, not always made by newbies.
Many devices are interfaced via I2C, they can also be interfaced via SHIFTIN/SHIFTOUT. Either way an understanding of the part is needed. That is where the data sheet comes in.
First, compare the two figures below. The fisrt one is from the PBP manual showing a time line of the SHIFT sequence. The second is from the EEPROM data sheet showing the data transfer sequence. Similar ???
From the data sheet look at figure 6.1. This shows the sequence of events to write a BYTE of data to the EEPROM.
The first thing we do is put the EEPROM in a START condition. This is done by holding the EEPROM clock pin HIGH and toggleing the data pin High to LOW. The I2C command does this for us.
Code:
HIGH CPIN:HIGH DPIN:LOW DPIN
Bits 7-4 are the control code for this EEPROM. "1010"
Bit 3 is is for selecting the memory block, this EEPROM is divided into to parts. This example is using the lower half. "0"
Bits 2-1 are for addressing. Up to four EEPROM can be used on the same bus. In this example both pins A1 and A2 are pulled LOW. "00"
Bit 0 selects Read or Write mode. "0" for Write, "1" for Read. PBP's I2C command will set this bit for us, leave as "0"
When the EEPROM receives the control byte it will then send an ACKnowledge bit to the MCU. Then the High byte of the EEPROM address can be sent, this will be followed by another ACK from the EEPROM. The LOW byte of the address is sent next, with the EEPROM sending an ACK again.
In the below code the above is all in the "INT_ROM:" routine. PBP I2C will take care of the ACKs.
Now a BYTE of data can be sent to the EEPROM, when the data is received by the EEPROM it will send an ACK to the MCU. The MCU will then send a STOP condition to the EEPROM letting it know to start writing the data. Again, the I2C command does this for us.
Code:
HIGH CPIN:LOW DPIN:HIGH DPIN
Part #2 will talk about WORD and page writes to the EEPROM.
Code:
' 18F6680 24FC1025
'912 BYTES
DEFINE OSC 20
@ __CONFIG _CONFIG1H, _OSC_HS_1H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L
DEFINE LCD_DREG PORTG
define LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
DEFINE LCD_COMMANDUS 3000
DEFINE LCD_DATAUS 150
DPIN VAR PORTB.2 'I2C DATA PIN
CPIN VAR PORTB.1 'I2C CLOCK PIN
ADDR VAR WORD
DATI VAR BYTE
DATO VAR BYTE
START2: ADDR = 0 : DATO = 0
For ADDR = 0 To 15
DATO = DATO + 2
I2CWRITE DPIN,CPIN,$A0,ADDR,[DATO]
Pause 10
Next ADDR
Pause 100
ADDR = 0
For ADDR = 0 To 15
I2CREAD DPIN,CPIN,$A0,ADDR,[DATI]
lcdout $FE,1,"DATI ",DEC DATI
lcdout $FE,$C0,"ADDR ",DEC ADDR
PAUSE 250
Next ADDR
GOTO START2
Code:
' 18F6680 24FC1025
'1216 BYTES
DEFINE OSC 20
@ __CONFIG _CONFIG1H, _OSC_HS_1H
@ __CONFIG _CONFIG2H, _WDT_OFF_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L
DEFINE LCD_DREG PORTG
define LCD_DBIT 0
DEFINE LCD_RSREG PORTE
DEFINE LCD_RSBIT 0
DEFINE LCD_EREG PORTE
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 4
DEFINE LCD_COMMANDUS 3000
DEFINE LCD_DATAUS 150
DPIN VAR PORTB.2 'I2C DATA PIN
CPIN VAR PORTB.1 'I2C CLOCK PIN
ADDR_HB VAR BYTE
ADDR_LB VAR BYTE
ADDR_HB = 0
ADDR_LB = 0
CONT1 CON %10100001 'READ CONTROL
CONT0 CON %10100000 'WRITE CONTROL
ACK VAR BIT
DATI VAR BYTE
DATO VAR BYTE
START: DATO = 0
WRITE_DATA:
For ADDR_LB = 1 To 15
DATO = DATO + 2
GOSUB INT_ROM
SHIFTOUT DPIN,CPIN,1,[DATO\8,%1\1]
GOSUB STOP_ROM
PAUSE 10
NEXT ADDR_LB
READ_DATA:
For ADDR_LB = 0 To 15
GOSUB INT_ROM
GOSUB START_ROM
SHIFTOUT DPIN,CPIN,1,[CONT1]
SHIFTIN DPIN,CPIN,0,[ACK\1,DATI\8]
SHIFTOUT DPIN,CPIN,1,[%1\1]
GOSUB STOP_ROM
lcdout $FE,1,"DATI ",DEC DATI
lcdout $FE,$C0,"ADDR ",DEC ADDR_LB
PAUSE 250
NEXT ADDR_LB
GOTO START
INT_ROM:
GOSUB START_ROM
SHIFTOUT DPIN,CPIN,1,[CONT0]
SHIFTIN DPIN,CPIN,0,[ACK\1]
SHIFTOUT DPIN,CPIN,1,[ADDR_HB]
SHIFTIN DPIN,CPIN,0,[ACK\1]
SHIFTOUT DPIN,CPIN,1,[ADDR_LB]
SHIFTIN DPIN,CPIN,0,[ACK\1]
RETURN
START_ROM:
HIGH CPIN:HIGH DPIN:LOW DPIN:RETURN
STOP_ROM:
HIGH CPIN:LOW DPIN:HIGH DPIN:RETURN


Menu


Re: serial LCD 1602 Backpack using PIC16F690 for Hitach HD44780
one last update:
jackberg1 - 1st November 2025, 17:11added an PGM Sw on RA3
to edit the baud rate:
turn off the LCD display, press & hold the PGM sw, turn on the LCD
line 1 will show "Press to Select" , line 2 : "Baud Rate:"...