'{$STAMP BS2} '*********************************************************** '** ** '** I2C Routines for the Basic Stamp ** '** Controlling Two SRF08 Ultrasonic Rangers ** '** ** '** Copyright 2002 - Devantech Ltd ** '** Commercial use of this software is prohibited ** '** Private and educational use only is permitted ** '** ** '** Written by Gerald Coe - January 2002 ** '** ** '** This Code has been Tested on BS2 and BS2p ** '** It should work equally well on the BS2e and BS2sx ** '** ** '*********************************************************** SCL con 9 ' I2C clock SDA con 8 ' I2C data SDAin var in8 SDAout var out8 ' To change the pins used, alter these 5 lines SDAdir var dir8 ' The 4 SDA numbers must be the same, of course loop var byte ' just a looping counter I2cBuf var byte ' I2c read/write buffer I2cAddr var byte ' Address of I2C device I2cReg var byte ' Register number within I2C device I2cData var word ' Data to read/write I2cAck var bit ' Acknowledge bit Main: ' 1st SRF08 Ranger I2cAddr = $e0 I2cReg = 0 I2cData = 81 ' Rangeing command - 80 for inches, 81 for cm, 82 for uS gosub I2cByteWrite pause 70 ' wait for ranging to complete I2cReg = 1 ' address of light sensor register gosub I2cByteRead debug 2,0,0, "Light Sensor1 ", dec3 I2cData I2cReg = 2 ' address of first ranging result gosub I2cWordRead debug 2,0,1, "Range1 ", dec4 I2cData ' 2nd SRF08 Ranger I2cAddr = $e2 I2cReg = 0 I2cData = 81 ' Rangeing command - 80 for inches, 81 for cm, 82 for uS gosub I2cByteWrite pause 70 ' wait for ranging to complete I2cReg = 1 ' address of light sensor register gosub I2cByteRead debug 2,0,3, "Light Sensor2 ", dec3 I2cData I2cReg = 2 ' address of first ranging result gosub I2cWordRead debug 2,0,4, "Range2 ", dec4 I2cData goto main '-------------------------------------------------------------------------------------------- ' I2C subroutines follow '-------------------------------------------------------------------------------------------- I2cByteWrite: ' writes I2cData.lowbyte to I2cReg at I2cAddr gosub I2cStart I2cBuf = I2cAddr gosub I2cOutByte ' send device address I2cBuf = I2cReg gosub I2cOutByte ' send register number I2cBuf = I2cData.lowbyte gosub I2cOutByte ' send the data gosub I2cStop return I2cWordWrite: ' writes I2cData to I2cReg at I2cAddr gosub I2cStart I2cBuf = I2cAddr gosub I2cOutByte ' send device address I2cBuf = I2cReg gosub I2cOutByte ' send register number I2cBuf = I2cData.highbyte gosub I2cOutByte ' send the data - high byte I2cBuf = I2cData.lowbyte gosub I2cOutByte ' send the data - low byte gosub I2cStop return I2CByteRead: gosub I2cStart I2cBuf = I2cAddr gosub I2cOutByte ' send device address I2cBuf = I2cReg gosub I2cOutByte ' send register number gosub I2cStart ' repeated start I2cBuf = I2cAddr | 1 gosub I2cOutByte ' send device address (with read set) I2cAck = 0 ' send Nak gosub I2cInByte I2cData.lowbyte = I2cBuf ' read the data I2cData.highbyte = 0 gosub I2cStop return I2CWordRead: gosub I2cStart I2cBuf = I2cAddr gosub I2cOutByte ' send device address I2cBuf = I2cReg gosub I2cOutByte ' send register number gosub I2cStart ' repeated start I2cBuf = I2cAddr | 1 I2cAck = 1 ' send Ack gosub I2cOutByte ' send device address (with read set) gosub I2cInByte I2cData.highbyte = I2cBuf ' read the data I2cAck = 0 ' send Nak gosub I2cInByte I2cData.lowbyte = I2cBuf gosub I2cStop return I2cOutByte: shiftout SDA, SCL, MSBFIRST, [I2cBuf] input SDA high SCL ' clock in the ack' bit low SCL return I2cInByte: shiftin SDA, SCL, MSBPRE, [I2cBuf] SDAout = 0 SDAdir = I2cAck high SCL ' clock out the ack' bit low SCL input SDA return I2cStart ' I2C start bit sequence high SDA high SCL low SDA low SCL return I2cStop: ' I2C stop bit sequence low SDA high SCL high SDA return