Hi. I have been struggling getting an I2C master slave routine going between two different PICs. I can write from the master with no issues, but when ever I try to read it resets the master and it keeps resetting as soon as it hits an I2C cmd. It seems to go through once, but then starts to reset and never goes through the routine again as if something is not being released or the like from the slave... I have attached the master and slave code below. Any help would be greatly appreciated. Thanks, Charlie
' PicBasic Pro Master PIC18F2220 to read and write to I2C slave
@ __CONFIG _CONFIG1H, _INTIO2_OSC_1H
@ __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _LVP_OFF_4L
OSCCON = $70
DEFINE OSC 8
DEFINE I2C_HOLD 1
SCL VAR PORTC.3 ' Clock pin
SDA VAR PORTC.4 ' Data pin
' Alias pins (0=Output, 1=Input)
L1 VAR LATB.7 :TRISB.7 = 0
L2 VAR LATB.6 :TRISB.6 = 0
L3 VAR LATB.5 :TRISB.5 = 0
L4 VAR LATB.4 :TRISB.4 = 0
'Define RAM
i var byte
a VAR BYTE[8] ' Holds 8 characters read from slave
j var byte
'blink L1-L4 to signal its alive or has been reset
for i = 1 to 12
high L1: pause 25: low L1
high L2: Pause 25: Low l2
high l3: pause 25: low l3
high l4: pause 25: low l4
next i
j= 125
loop:
toggle L1
j= j+1
I2CWrite SDA,SCL,$02,[j], bogus ' Write value to slave
if j>130 then j=125
Pause 250
'I2CRead SDA,SCL,$02,[STR a\8], bogus ' Read string from slave
GoTo loop ' Do it forever
bogus:
high l2: Pause 1000: low l2
GoTo loop
' PicBasic Pro I2C slave program - PIC16F819
@ device INTRC_OSC_NOCLKOUT
'@ DEVICE XT_OSC ' System Clock Options
@ DEVICE WDT_ON ' Watchdog Timer
@ DEVICE PWRT_ON ' Power-On Timer
@ DEVICE BOD_ON ' Brown-Out Detect
@ DEVICE MCLR_OFF ' Master Clear Options
@ DEVICE LVP_OFF ' Low-Voltage Programming
@ DEVICE CPD_OFF ' Data Memory Code Protect
@ DEVICE PROTECT_OFF ' Program Code Protection
OSCCON = $70 'sets the oscillator speed
DEFINE OSC 8 'Oscillator speed in MHz: 3(3.58) 4 8 10 12 16 20 24 25 32 33 40
' Alias pins (0=Output, 1=Input)
scl VAR PORTB.3: TRISB.3 = 1 ' I2C clock input
sda VAR PORTB.4: TRISB.4 = 1 ' I2C data input
L1 var PORTA.2 :TRISA.2 = 0
L2 VAR PORTA.4 :TRISA.4 = 0
L3 VAR PORTB.0 :TRISB.0 = 0
L4 VAR PORTB.3 :TRISB.3 = 0 ' Green LED
L5 VAR PORTB.6 :TRISB.6 = 0 ' Red LED
' 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 2 ' Make our address 2
' Allocate RAM
result VAR BYTE ' ADC result
datain VAR BYTE ' Data in
dataout VAR BYTE[8] ' Data out array
readcnt VAR BYTE ' I2C read count
' 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
readcnt = 0 ' Zero counter
high L1: high L2: high L3: high L4 : High L5
pause 200
low L1: low L2: low L3: low L4 : Low L5
dataout[0] = 0
dataout[1] = 1
dataout[2] = 2
dataout[3] = 3
dataout[4] = 4
dataout[5] = 5
dataout[6] = 6
dataout[7] = 7
dataout[8] = 8
mainloop: ' Main program loop
toggle l1
IF SSPIF Then ' Check for I2C interrupt flag
GoSub i2cslave
EndIF
GoTo mainloop ' Do it all forever
i2cslave: ' I2C slave subroutine
SSPIF = 0 ' Clear interrupt flag
IF R_W = 1 Then i2crd ' Read data
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
toggle l2
if datain = 127 then
high l5
else
low l5
endif
GoTo i2cexit
i2crd: ' I2C read data from us
toggle l3
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
Bookmarks