'*********************************************************** '** ** '** I2C Routines for the BX-24 ** '** to demonstrate the use of Compass module ** '** ** '** Copyright 2002 - Devantech Ltd ** '** Commercial use of this software is prohibited ** '** Private and educational use only is permitted ** '** ** '** Written by Gerald Coe - February 2002 ** '** ** '*********************************************************** Const SCL As Byte = 14 ' I2C clock - choose any pins you wish for SCL and SDA Const SDA As Byte = 13 ' I2C data Const Calibrate As Byte = 15 ' Calibrate push button Const CmdReg As Byte = 0 ' SRF08 command register Const Compass As Byte = &Hc0 ' Compass module is at address 0Xc0 Const BearingReg As Byte = 2 ' Bearing is in registers 2 & 3 (High:Low) Const CalReg As Byte = 15 ' Calibration Register Const CalCmd As Byte = 255 ' Calibration Command Dim I2cAck As Boolean ' Acknowledge flag Sub Main() Dim Bearing As New UnsignedInteger ' Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputHigh) Call PutPin(Calibrate, bxInputPullup) Do Bearing = I2cWordRead(Compass, BearingReg)\10 ' Read Bearing and convert to 0-359 degrees debug.Print "Bearing = "; CStr(Bearing) ' The following four lines of code are all you need if you wish to calibrate the compass ' You can delete them if not required If GetPin(Calibrate)=0 Then ' If Push Button pressed Call I2cByteWrite(Compass, CalReg, CalCmd ) ' then send calibration command debug.Print "Calibrating.. . ."; End If Loop End Sub '-------------------------------------------------------------------------------------------- ' I2C subroutines follow '-------------------------------------------------------------------------------------------- ' writes I2cData to I2cReg at I2cAddr Sub I2cByteWrite(ByVal I2cAddr As Byte, ByVal I2cReg As Byte, ByVal I2cData As Byte) Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cOutByte(I2cData) ' send the data Call I2cStop() End Sub Function I2CByteRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As Byte Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cStart() ' repeated start I2cAddr = I2cAddr+1 Call I2cOutByte(I2cAddr) ' send device address with read set I2cAck = False ' setup to send Nak I2cByteRead = I2cInByte() ' get data byte with Nak Call I2cStop() End Function Function I2CWordRead(ByVal I2cAddr As Byte, ByVal I2cReg As Byte) As UnsignedInteger Set I2CWordRead = New UnsignedInteger Call I2cStart() Call I2cOutByte(I2cAddr) ' send device address Call I2cOutByte(I2cReg) ' send register address Call I2cStart() ' repeated start I2cAddr = I2cAddr+1 Call I2cOutByte(I2cAddr) ' send device address with read set I2cAck = True ' setup to send Ack I2cWordRead = CuInt(I2cInByte()*256) I2cAck = False ' setup to send Nak I2cWordRead = I2cWordRead + CuInt(I2cInByte()) Call I2cStop() End Function Sub I2cOutByte(I2cData As Byte) Call ShiftOut(SDA, SCL, 8, I2cData) ' shift data out Call PutPin(SDA, bxInputTristate) ' turn SDA around Call PutPin(SCL, bxOutputHigh) ' and clock in the ack' bit Call PutPin(SCL, bxOutputLow) End Sub Function I2cInByte() As Byte I2cInByte = ShiftIn(SDA, SCL, 8) If I2cAck=True Then Call PutPin(SDA, bxOutputLow) Else Call PutPin(SDA, bxOutputHigh) End If Call PutPin(SCL, bxOutputHigh) ' clock out the ack' bit Call PutPin(SCL, bxOutputLow) End Function Sub I2cStart() ' I2C start bit sequence Call PutPin(SDA, bxOutputHigh) Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputLow) Call PutPin(SCL, bxOutputLow) End Sub Sub I2cStop() ' I2C stop bit sequence Call PutPin(SDA, bxOutputLow) Call PutPin(SCL, bxOutputHigh) Call PutPin(SDA, bxOutputHigh) End Sub