zkt_PiratesDen
New Member
This follows the idea, if not the letter, that Nigel presents his tutorial. Three 8 bit bytes are send on the i2c bus to a slave ; address, subadress, and data. The slave (should) responds with an acknowledgement by pulling the sda line low during the 9th scl (clock) bit ot each byte. It doesnt happen. Iv`e checked the code more than once and it looks good to me. There may not be an error at all. The slave is so28 package and only the power, i2c bus and analog input selector and its output are connected. When I asked the manufacturer if these test conditions were sufficient, they said they would look into it- about a week ago. If anyone familiar with this stuff would look the code over and maybe see a blatant error, sure would appreciate it. ( I`m pretty much talking to Nigel- after all you wrote the code that this is based on). If this fails I can either rewrite it in asm and post on the Microchip forum and/or connect the rest on the pins, all 20 of em, and test it again. The debuger and scope verify that the code follows the correct steps and is sending pulses, but the slsve doesn`t send an ack. The tining looks right too. Gotta be something stupid
Code:
program I2C
' pic 16F87
'SENDS START CONDITION,3 BYTES, THEN STOP CONDITION ON I2C BUS TO SLAVE.
' PORTB.0 IS SCL LINE. PORTA.7 IS SDA LINE. DELAYS ARE FOR BTTER SCOPE DISPLAY.
dim tmp, bit,bite as byte
const tda_adr as byte=$88
const sub_adr as byte[9]=($00,$01,$02,$02,$02,$02,$02,$02,$02)
const data as byte[9]=($00,$00,$01,$03,$05,$07,$09,$0b,$0D)
main:
osccon=%01100010 'cpu clock(Fosc)=4 Mhz
while iofs=1
wend
cmcon=7
portb.0=0 ' portb.0 scl
porta.7=0 ' porta.7 sda
I2C_Start:
trisb=0
trisa=128
delay_us(100)
trisb=1
delay_us(100)
trisa=0
delay_us(100)
trisb=0
delay_us(100)
for bite=1 to 3
for bit=0 to 7
if bite=1 then tmp=$88 'tda address
end if
if bite=2 then tmp=$00 'tda sub_adr=#00000000=in select
end if
if bite=3 then tmp=$00 ' tda_data=#00000000=in4
end if
tmp=tmp<<n ' shift current tda_data bit to MSB of tmp
if tmp and 128=128 then
trisa=128 'set tda high if current tda_data bit is high
else trisa=0 ' else set tda low
end if
trisb=1 ' send scl pulse
delay_us(100)
trisb=0
delay_us(100)
next bit
next bite
gosub ack
i2c_stop:
trisb=0
delay_us(100)
trisa=0
delay_us(100)
trisb=1
delay_us(100)
trisa=128
delay_us(100)
trisb=0
delay_ms(10)
ack:
trisb=1
trisa=128
while porta and 128=1
wend
trisb=0
delay_us(100)
return
end.