;此程序适用于PIC单片机读写I2C接口的EEPROM,如24CXX、24LCXX系列的芯片
;该程序由单片机智能工作室友情提供。
;*****************************************************************
; 读外部EEPROM子程序
;
;*******************Initialization subroutine*********************
; This routine initializes the MSSP module
; for I2C Master mode, with a 100 kHz clock.
;*****************************************************************
Init
bcf status,6 ; Select Bank 01
bsf status,5
movlw b'10011001'
movwf trisc ; Set PORTC
clrf sspstat ; Disable SMBus inputs
bsf sspstat,SMP ; Disable slew rate control
movlw 0x18 ; Load 0x18 into WREG
movwf sspadd ; Setup 100 kHz I2C clock
clrf sspcon2 ; Clear control bits
bcf status,5 ; Select Bank 00
movlw b'00101000'
movwf sspcon ; Enable SSP, select I2C Master mode
bcf pir1,SSPIF ; Clear SSP interrupt flag
bcf pir2,BCLIF ; Clear Bit Collision flag
retlw 0
;*******************Start bit subroutine**************************
; This routine generates a Start condition
; (high-to-low transition of SDA while SCL
; is still high.
;*****************************************************************
BSTART
bcf status,6
bcf status,5 ; Select Bank 00
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5 ; Select Bank 01
bsf sspcon2,SEN ; Generate Start condition
bcf status,5 ; Select Bank 00
bstart_wait
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto bstart_wait ; If not, keep checkin
retlw 0
;*******************Restart bit subroutine**************************
; This routine generates a Repeated Start
; condition (high-to-low transition of SDA
; while SCL is still high.
;*****************************************************************
BRESTART
bcf status,6
bcf status,5 ; Select Bank 00
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5 ; Select Bank 01
bsf sspcon2,RSEN ; Generate Restart condition
bcf status,5 ; Select Bank 00
brestart_wait
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto brestart_wait ; If not, keep checking
retlw 0
;*******************Stop bit subroutine***************************
; This routine generates a Stop condition
; (low-to-high transition of SDA while SCL
; is still high.
;*****************************************************************
BSTOP
bcf status,6
bcf status,5 ; Select Bank 00
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5 ; Select Bank 01
bsf sspcon2,PEN ; Generate Stop condition
bcf status,5 ; Select Bank 00
bstop_wait
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto bstop_wait ; If not, keep checking
retlw 0
;*******************Data transmit subroutine**********************
; This routine transmits the byte of data
; stored in 'datao' to the serial EEPROM
; device. Instructions are also in place
; to check for an ACK bit, if desired.
; Just replace the 'goto' instruction,
; or create an 'ackfailed' label, to provide
; the functionality.
;*****************************************************************
TX
bcf status,6
bcf status,5 ; Select Bank 00
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5
movf data_out,0 ; Copy datao to WREG
bcf status,5
movwf sspbuf ; Write byte out to device
tx_wait
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto tx_wait ; If not, keep checking
; bsf status,5 ; Select Bank 01
; btfsc sspcon2,ACKSTAT ; Check if ACK bit was received
; goto ackfailed ; This executes if no ACK received
retlw 0
;************************ 数据接受子程序 **********************
; MCU处接收状态
; 数据保存在:data_in
;*****************************************************************
RX
bcf status,6
bcf status,5 ; Select Bank 00
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5 ; Select Bank 01
bsf sspcon2,RCEN ; Initiate reception of byte
bcf status,5 ; Select Bank 00
rx_wait
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto rx_wait ; If not, keep checking
movf sspbuf,0 ; Copy byte to WREG
bsf status,5
movwf data_in ; Copy WREG to data_in
bcf status,5
bcf pir1,SSPIF ; Clear SSP interrupt flag
bsf status,5 ; Select Bank 01
bsf sspcon2,ACKEN ; Generate ACK/NO ACK bit
bcf status,5 ; Select Bank 00
rx_wait2
clrwdt
btfss pir1,SSPIF ; Check if operation completed
goto rx_wait2 ; If not, keep checking
retlw 0
;************************写一个字节子程序*************************
; 输入:被写的数据存在eebuff中
; 数据存放的地址在eeaddr_h\eeaddr_l中
; 写芯片控制字保存在control_ee中
;*****************************************************************
ByteWrite
call BSTART ; Generate Start condition
bsf status,5 ; Send control byte
movf control_ee,0 ; Load control byte for write
movwf data_out ; Copy to datao for output
call TX ; Send control byte to device
; Send word address high byte
bsf status,5 ; Select Bank 00
movf eeaddr_h,0 ; Load the msb for word address
movwf data_out ; Copy to datao for output
call TX
; Send word address low byte
bsf status,5 ; Select Bank 00
movf eeaddr_l,0 ; Load the lsb for word address
movwf data_out ; Copy to datao for output
call TX ; Send word address to device
; Send data byte
bsf status,5 ; Select Bank 00
movf eebuff,0 ; Load data byte
movwf data_out ; Copy to datao for output
call TX ; Send data byte to device
call BSTOP ; Generate Stop condition
call Poll ; Poll for write completion
return
;******************* 写一页数据到EEPROM ************************
;
;输入:连续写的字节数保存在count_ee中
; 数据写到EEPROM中的起始地址保存在eeaddr_h\eeaddr_l中
; 被写的数据保存在以wrbuff为首的数据缓冲器中
; 写芯片控制字保存在control_ee中
;*****************************************************************
PageWrite
call BSTART ; Generate start bit
bsf status,5 ; Now we send the control byte