Here a working snipet for I2C slave communication.
I2C write command will be received into variable array RxBuffer and RxBuffer[0] is used for the case select routine.
I2C read command will return content of variable array TxBuffer. So before reading you have to update the array in someways. The easy way is to write a command that will update the array TxBuffer with the values you need than you read them.
Array lenght can be changed, changing the constants "RxBufferLEN" & "TxBufferLEN"
Slave address can be changed changing the constant "I2Caddress".
A 20 MHz quartz is recommended.
Add your code in the correct place and you should not have problem.
Code:
'****************************************************************
'* Name : I2C_Slave *
'* Author : *
'* Notice : *
'* : All Rights Reserved *
'* Date : 03/01/2008 *
'* Version : 1.0 *
'* Notes : I2C Slave with Pic16F876 *
'* : *
'****************************************************************
'-- set device & tris port config here (don't use SCL & SDA pins other than I2C) ----
DEFINE I2C_HOLD 1
'---------------- Alias pins -----------------------------------
SCLDIR var TRISC.3
SDADIR var TRISC.4
'--------------- Define used register flags -------------------
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
SSPIE VAR PIE1.3
BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
R_W VAR SSPSTAT.2 ' SSP (I2C) Read/Write
D_A VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKP VAR SSPCON.4 ' SSP (I2C) SCK Release Control
SSPEN VAR SSPCON.5 ' SSP (I2C) Enable
SSPOV VAR SSPCON.6 ' SSP (I2C) Receive Overflow Indicator
WCOL VAR SSPCON.7 ' SSP (I2C) Write Collision Detect
STAT_BF VAR SSPSTAT.0 ' SSP (I2C) Buffer Full
STAT_RW VAR SSPSTAT.2 ' SSP (I2C) Read/Write
STAT_DA VAR SSPSTAT.5 ' SSP (I2C) Data/Address
CKE VAR SSPSTAT.6 ' SSP (I2C) Data/Address
'------------------- Rx Buffer defintion --------------------
RxBufferLEN con 3
RxBuffer var byte[Rxbufferlen]
RxBufferIndex var byte
'------------------ Tx Buffer defintion ----------------------
TxBufferLEN con 3
TxBuffer var byte[txbufferlen]
TxBufferIndex var byte
'------------------ Define constants ------------------------
I2Caddress CON $2 ' Make address = 2
' --------- Define here your variables and alias ------------------
' -------------- Initialize I2C slave mode ------------------------
SCLDIR = 1 ' SCL must be an input before enabling interrupts
SDADIR = 1
SSPADD = I2Caddress ' Set our address
SSPCON2.7 = 0 ' General call address disabled
SSPCON = $36 ' Set to I2C slave with 7-bit address
SSPSTAT = 0
SSPIE = 1
SSPIF = 0
RxBufferIndex = 0
TxBufferIndex = 0
'----------------- Initialization Done! -----------------------------
GoTo main
'------------------------- I2C subroutine --------------------------------
i2cslave: ' I2C slave subroutine
SSPIF = 0 ' Clear interrupt flag
IF R_W = 1 Then i2crd ' Read data from us
IF BF = 0 Then i2cexit ' Nothing in buffer so exit
IF D_A = 1 Then i2cwr ' Data for us (not address)
IF SSPBUF != I2Caddress Then i2cexit ' Clear the address from the buffer
readcnt = 0 ' Mark as first read
GoTo i2cexit
i2cwr: ' I2C write data to us
datain = SSPBUF ' Put buffer data into array
Rxbuffer[Rxbufferindex]=datain
rxbufferindex =rxbufferindex+1
if rxbufferindex=RxBufferLEN then ' end of buffer transfer
WrData=1
rxbufferindex=0
endif
GoTo i2cexit
i2crd: ' I2C read data from us
IF D_A = 0 Then
TxBufferIndex = 0
EndIF
while STAT_BF : wend ' loop while buffer is full
wcol = 0 ' clear collision flag
SSPBUF = TxBuffer[TxBufferIndex]
while wcol
wcol = 0
SSPBUF = TxBuffer[TxBufferIndex]
wend
CKP = 1 ' release clock, allowing read by master
TxBufferIndex = TxBufferIndex + 1 ' increment index
if TxBufferIndex = TxBufferlen then ' all bytes have been tx
TxBufferIndex = 0 ' reset index
endif
i2cexit:
Return
' -------------------------end I2C subroutine --------------------------------
Main:
IF SSPIF = 1 Then
GoSub i2cslave
EndIF
SSPOV = 0
WCOL = 0
Select case RBuffer[0]
'--------------------- Place here your case select code
end select
WrData=0
GoTo Main
' ----------------- This space for your program code
End
Enjoy
Al.
All progress began with an idea
Bookmarks