Hi again,
Here is the code I'm using..
Master pic using Pic16F877A
Code:
'-------------------------------------------------------------------------------
' Master
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
DEFINE OSC 4
'OPTION_REG.7 = 0
ADCON1 = 7
'------------------------------------------------------------------------------
DEFINE I2C_SLOW 1
TRISB.5 = 1
TRISB.7 = 1
'------------------------------------------------------------------------------
scl VAR PORTB.5 ' i2c clock input
sda VAR PORTB.7 ' i2c data input
'------------------------------------------------------------------------------
I2Caddress VAR BYTE
valor VAR BYTE
'------------------------------------------------------------------------------
' Set LCD Data port
DEFINE LCD_DREG PORTD
' Set starting Data BIT (0 OR 4) IF 4-BIT bus
DEFINE LCD_DBIT 4
' Set LCD Register Select port
DEFINE LCD_RSREG PORTC
' Set LCD Register Select BIT
DEFINE LCD_RSBIT 6
' Set LCD Enable port
DEFINE LCD_EREG PORTC
' Set LCD Enable BIT
DEFINE LCD_EBIT 7
' Set LCD bus size (4 OR 8 bits)
DEFINE LCD_BITS 4
' Set number of lines ON LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 2000
' Set Data delay time in us
DEFINE LCD_DATAUS 50
'------------------------------------------------------------------------------
Pause 500 ' Wait for LCD to startup
LCDOut $fe, 1
LCDOut $fe, "Daniel"
Pause 500 ' Wait for LCD to startup
valor = 0
'------------------------------------------------------------------------------
main:
I2Caddress = $3
LCDOut $fe, 1
LCDOut "Write 1 - LED ON"
Pause 500
I2CWrite SDA, SCL, I2Caddress, [6], bogus ' Write offset to slave
Pause 500
LCDOut $fe, 1
LCDOut "Write 1 - LED OFF"
Pause 500
I2CWrite SDA, SCL, I2Caddress, [8], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Reading 1..."
Pause 500
I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave
LCDOut $fe, 1
LCDOut "Value1: ", DEC valor
Pause 500
'--------
I2Caddress = $5
LCDOut $fe, 1
LCDOut "Write 2 - LED ON"
Pause 500
I2CWrite SDA, SCL, I2Caddress, [4], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Write 2 - LED OFF"
Pause 500
I2CWrite SDA, SCL, I2Caddress, [10], bogus ' Write to slave
Pause 500
LCDOut $fe, 1
LCDOut "Reading 2..."
Pause 500
I2CRead SDA, SCL, I2Caddress, [valor], bogus ' Read from slave
LCDOut $fe, 1
LCDOut "Value2: ", DEC valor
Pause 500
'--------
GoTo main ' Do it forever
'-------------------------------------------------------------------------------
bogus:
LCDOut $fe,1, "Time out" ' I2C command timed out
Pause 500
GoTo main
'-------------------------------------------------------------------------------
End
Here is the code for the Slave Pic16F88
Code:
DEFINE OSC 8
OSCCON = 110001 '8mhz
'------------------------------------------------------------------------------
CMCON = 7
ADCON1 = 0 ' Disable A/D converter
ADCON0 = 0
ANSEL = 0 ' all analog pins to digital
'--- tris port config here (don't use SCL & SDA pins other than I2C) ----------
DEFINE I2C_HOLD 1
TRISB.1 = 1
TRISB.4 = 1
'--- Alias pins ---------------------------------------------------------------
SDADIR VAR TRISB.1
SCLDIR VAR TRISB.4
'--- Define here your variables and alias -------------------------------------
LEDT VAR PORTA.2
LEDL VAR PORTB.7
LEDM VAR PORTB.6
LEDR VAR PORTB.5
readcnt VAR BYTE
datain VAR BYTE
WrData VAR BYTE
'--- 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 1
RxBuffer VAR BYTE[Rxbufferlen]
RxBufferIndex VAR BYTE
'--- Tx Buffer defintion ------------------------------------------------------
TxBufferLEN CON 1
TxBuffer VAR BYTE[txbufferlen]
TxBufferIndex VAR BYTE
'--- Define constants ---------------------------------------------------------
I2Caddress CON $3 ' Make address = 3
'--- Initialize I2C slave mode ------------------------------------------------
SCLDIR = 1 ' SCL must be an input before enabling interrupts
SDADIR = 1
SSPADD = I2Caddress ' Set our address
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:
pause 100
txbuffer = 12
IF SSPIF = 1 Then
GoSub i2cslave
EndIF
SSPOV = 0
WCOL = 0
Select Case RxBuffer[0]
Case 6
High LEDT
Case 8
Low LEDT
End Select
WrData=0
GoTo Main
'------------------------------------------------------------------------------
End
The codes I'm using is from Daniel(copy and paste).
BTW I'm using a simulator...
regards,
tacbanon
Bookmarks