Hi Guys,
After a few days of trying, I got this code to work. One 16F88 as master, and two 16F767 as slaves, just to test that the address is working fine. I only test to send one byte. I will have to test to read one, but wanted to share the code anyway:
Code:
'--- MASTER BEGINS ----------------------------------------------------------------------------
@ device pic16f88, intrc_osc_noclkout ; system clock options
@ device pic16f88, wdt_on ; watchdog timer
@ device pic16f88, pwrt_on ; power-on timer
@ device pic16f88, mclr_off ; master clear options (internal)
@ device pic16f88, protect_off ; code protect off
'---
DEFINE OSC 8
DEFINE I2C_HOLD 1
DEFINE I2C_SLOW 1
osccon = %01111000 '8mhz
'---
cmcon = 7
ansel = 0
'---
scl VAR PORTB.4 ' i2c clock input
sda VAR PORTB.1 ' i2c data input
'---
main:
High PORTA.6
Pause 500
Low PORTA.6
Pause 500
' First 16f767 - address 6
I2CWrite sda, scl, $06, [15], bogus
Pause 100
I2CWrite sda, scl, $06, [30], bogus
Pause 100
' Second 16f767 - address 8
I2CWrite sda, scl, $08, [45], bogus
Pause 100
I2CWrite sda, scl, $08, [60], bogus
Pause 100
GoTo main
'---
bogus:
GoTo main
'---
End
'--- MASTER ENDS ----------------------------------------------------------------------------
Code:
'--- FIRST SLAVE STARTS ----------------------------------------------------------------------------
@ DEVICE PIC16F767, INTRC_OSC_NOCLKOUT ; System Clock Options
@ DEVICE PIC16F767, WDT_ON ; Watchdog Timer
@ DEVICE PIC16F767, PWRT_ON ; Power-On Timer
@ DEVICE PIC16F767, MCLR_OFF ; Master Clear Options (Internal)
@ DEVICE PIC16F767, PROTECT_OFF ; Code Protect Off
'---
DEFINE OSC 8
OSCCON = %01110000
'---
CMCON = 7 ' Comparators Off
ADCON0 = 0 ' A/D Modules Off
ADCON1 = %11111111 ' All Digital Pins
TRISA = %00000000
'---
DEFINE I2C_HOLD 1
DEFINE I2C_SLOW 1
'---
' Alias pins
scl VAR PORTC.3 ' I2C clock input
sda VAR PORTC.4 ' I2C data input
'---
' Define used register flags
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
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
'---
' Define constants
I2Caddress CON 6 ' Make our address 6
'---
LEDA VAR PORTB.2
LEDB VAR PORTB.6
LEDC VAR PORTB.7
'---
' Allocate RAM
datain VAR BYTE ' Data in
readcnt VAR BYTE
dataout VAR BYTE[8]
'---
' Initialize I2C slave mode
SSPADD = I2Caddress ' Set our address
SSPCON2 = 0 ' General call address disabled
SSPCON = $36 ' Set to I2C slave with 7-bit address
'---
' POST
Low leda
Pause 100
High leda
Pause 100
Low leda
Pause 100
High leda
Pause 100
GoTo main
'---
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 data into array
GoTo i2cexit
'---
i2crd: ' I2C read data from us
IF D_A = 0 Then
readcnt = 0 ' Mark as first read
EndIF
SSPBUF = dataout[readcnt] ' Get data from array
CKP = 1 ' Release SCL line
readcnt = readcnt + 1 ' Move along read count
GoTo i2cexit ' That's it
'---
i2cexit:
Return
'---
main:
IF SSPIF = 1 Then
GoSub i2cslave
Low leda
Pause 10
High leda
Pause 10
IF datain = 15 Then
Low ledb
Pause 10
High ledb
Pause 10
EndIF
IF datain = 30 Then
Low ledc
Pause 10
High ledc
Pause 10
EndIF
EndIF
SSPOV = 0
WCOL = 0
GoTo main
'---
End
'--- FIRST SLAVE ENDS ----------------------------------------------------------------------------
Code:
'--- SECOND SLAVE STARTS ----------------------------------------------------------------------------
@ DEVICE PIC16F767, INTRC_OSC_NOCLKOUT ; System Clock Options
@ DEVICE PIC16F767, WDT_ON ; Watchdog Timer
@ DEVICE PIC16F767, PWRT_ON ; Power-On Timer
@ DEVICE PIC16F767, MCLR_OFF ; Master Clear Options (Internal)
@ DEVICE PIC16F767, PROTECT_OFF ; Code Protect Off
'---
DEFINE OSC 8
OSCCON = %01110000
'---
CMCON = 7 ' Comparators Off
ADCON0 = 0 ' A/D Modules Off
ADCON1 = %11111111 ' All Digital Pins
TRISA = %00000000
'---
DEFINE I2C_HOLD 1
DEFINE I2C_SLOW 1
'---
' Alias pins
scl VAR PORTC.3 ' I2C clock input
sda VAR PORTC.4 ' I2C data input
'---
' Define used register flags
SSPIF VAR PIR1.3 ' SSP (I2C) interrupt flag
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
'---
' Define constants
I2Caddress CON 8 ' Make our address 8
'---
LEDA VAR PORTB.2
LEDB VAR PORTB.6
LEDC VAR PORTB.7
'---
' Allocate RAM
datain VAR BYTE ' Data in
readcnt VAR BYTE
dataout VAR BYTE[8]
'---
' Initialize I2C slave mode
SSPADD = I2Caddress ' Set our address
SSPCON2 = 0 ' General call address disabled
SSPCON = $36 ' Set to I2C slave with 7-bit address
'---
' POST
Low leda
Pause 100
High leda
Pause 100
Low leda
Pause 100
High leda
Pause 100
GoTo main
'---
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 data into array
GoTo i2cexit
'---
i2crd: ' I2C read data from us
IF D_A = 0 Then
readcnt = 0 ' Mark as first read
EndIF
SSPBUF = dataout[readcnt] ' Get data from array
CKP = 1 ' Release SCL line
readcnt = readcnt + 1 ' Move along read count
GoTo i2cexit ' That's it
'---
i2cexit:
Return
'---
main:
IF SSPIF = 1 Then
GoSub i2cslave
Low leda
Pause 10
High leda
Pause 10
IF datain = 45 Then
Low ledb
Pause 10
High ledb
Pause 10
EndIF
IF datain = 60 Then
Low ledc
Pause 10
High ledc
Pause 10
EndIF
EndIF
SSPOV = 0
WCOL = 0
GoTo main
'---
End
'--- SECOND SLAVE ENDS ----------------------------------------------------------------------------
Hope it helps.
Regards,
Daniel.
Bookmarks