I want to use a 08M to do some very simple i2C communications. I found the attached code from Hippy which appears to do the job but can't get it to work. I'm trying to use it to read and write the memory on a DS1307 ($08-$37) so the only changes I've made are to set the correct slave address and limit the read/write address range. The DS1307 is mounted on a AXE091. I've proved the chip works fine using hi2c routines from a 28x2 on the same board. SCL is connected to pin 4 and SDA pin 1 as per the symbols in the routine and of course the axe091 has the pullups built in.
The problem is that the I2cStrobeScl routine never returns from the loop in which it waits for SCL to go high.
Any help would be gratefully received (particulalry Hippy!)
Thanks
Peter
The problem is that the I2cStrobeScl routine never returns from the loop in which it waits for SCL to go high.
Any help would be gratefully received (particulalry Hippy!)
Thanks
Peter
Code:
#picaxe 08m
; *****************************************************************************
; * *
; * I2C Master Test Program for the PICAXE-08M MAST08-1.BAS *
; * ^^^ *
; *****************************************************************************
; * *
; * This is an version of MAST18-1.BAS specifically designed to run on *
; * the PICAXE-08M using its bi-directional port abilities. *
; * *
; * The program will write to a series of adderesses and then read the *
; * values back.ad the address back ( the value should be what was sent *
; * *
; * The I2C code has been altered to only send a byte address, and the *
; * device address of the PICAXE-18X I2C Slave is $B0. *
; * *
; *****************************************************************************
; --.---.-- +V
; .|. .|.
; | | | | 2 x 4K7
; PICAXE-08M |_| |_| PICAXE-18X
; I2C MASTER | | I2C SLAVE
; .----------. | | . - - - - -.
; | X1 |-------------^---|-------------: O1 :
; | | | : :
; | X4 |-----------------^-------------: O4 :
; `----------' `- - - - - '
; *****************************************************************************
; * *
; * Define the I2C device being used *
; * *
; *****************************************************************************
Symbol I2C_ADDRESS = %11010000 ; $D0 for DS1307
; *****************************************************************************
; * *
; * Variables *
; * *
; *****************************************************************************
Symbol tstAdr = b0
Symbol tstVal = b1
Symbol i2cAdr = w1 ' b3:b2
Symbol i2cAdrLsb = b2
Symbol i2cAdrMsb = b3
Symbol i2cVal = b4
Symbol i2cDataByte = b5
Symbol i2cAckBit = b6
Symbol i2cBitCount = b7
; *****************************************************************************
; * *
; * Bit-Banged I/O definitions *
; * *
; *****************************************************************************
Symbol SDA = 1
Symbol SCL = 4
Symbol SDA_PIN = pin1
Symbol SCL_PIN = pin4
; *****************************************************************************
; * *
; * Main Program Code *
; * *
; *****************************************************************************
; Initialise the I2C comms
Gosub InitI2cDevice
; Test I2C
Do
For i2cAdr = $08 To $3F
Toggle 0
i2cVal = i2cAdr ^ $80
Gosub WriteI2cData
Pause 1000
Next
For i2cAdr = $08 To $3F
Toggle 0
Gosub ReadI2cData
Pause 1000
Next
Loop
; *****************************************************************************
; * *
; * High-Level I2C Interface Routines *
; * *
; *****************************************************************************
WriteI2cData:
Gosub I2cSendHeader
i2cDataByte = i2cVal
Gosub I2cSendByte
Gosub InitI2cDevice
Pause 20 ; 20mS to allow write
Return
ReadI2cData:
Gosub I2cSendHeader
Gosub I2cStart
i2cDataByte = I2C_ADDRESS | $01
Gosub I2cSendByte
Input SDA ; SDA = 1 / Tri-State SDA
For i2cBitCount = 0 To 7
Gosub I2cStrobeScl
i2cVal= i2cVal * 2 | i2cAckBit
Next
InitI2cDevice:
Low SCL ; SCL = 0
Low SDA ; SDA = 0
Input SCL ; SCL = 1
Input SDA ; SDA = 1
Return
; *****************************************************************************
; * *
; * Low-Level I2C Interface *
; * *
; *****************************************************************************
I2cSendHeader:
Gosub I2cStart
i2cDataByte = I2C_ADDRESS & $FE
Gosub I2cSendByte
i2cDataByte = i2cAdrLsb
I2cSendByte:
For i2cBitCount = 0 TO 7
If i2cDataByte < $80 Then
Low SDA ; SDA = 0
Else
Input SDA ; SDA = 1
End If
Gosub I2cStrobeScl
i2cDataByte = i2cDataByte * 2
Next
Input SDA ; SDA = 1 / Tri-State SDA
Gosub I2cStrobeScl
; --- if i2cAckBit = 1 Then
; --- SerTxd( "ACK FAILED",CR,LF )
; --- end if
Return
I2cStart:
Input SDA ; SDA = 1
Input SCL ; SCL = 1
Low SDA ; SDA = 0
Low SCL ; SCL = 0
Return
I2cStrobeScl:
Input SCL ; SCL = 1
Do
Loop Until SCL_PIN = 1
i2cAckBit = SDA_PIN
Low SCL ; SCL = 0
Return
; *****************************************************************************
; * *
; * End of program *
; * *
; *****************************************************************************