' ========================================================================= ' ' File...... SRF08_Demo.BS2 ' Purpose... Daventech SRF08 Ultrasonic Range Finder Demonstration ' Author.... Jon Williams ' E-mail.... jwilliams@parallax.com ' Started... ' Updated... 20 MAY 2003 ' ' {$STAMP BS2} ' {$PBASIC 2.5} ' ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' -----[ Revision History ]------------------------------------------------ ' -----[ I/O Definitions ]------------------------------------------------- SDA PIN 8 ' I2C serial data line SCL PIN 9 ' I2C serial clock line ' -----[ Constants ]------------------------------------------------------- SRF08 CON $E2 ' address of SRF08 RegCmd CON 0 ' command register RegLight CON 1 ' light value RegRange CON 2 ' ranger reading RngIn CON $50 ' range in inches RngCm CON $51 ' range in centimeters RngUs CON $52 ' range in microseconds Ack CON 0 ' acknowledge bit Nak CON 1 ' no ack bit ' -----[ Variables ]------------------------------------------------------- i2cSlave VAR Byte ' I2C device address i2cReg VAR Byte ' register address i2cData VAR Word ' data to/from device i2cWork VAR Byte ' work byte for I2C io i2cAck VAR Bit ' Ack bit from device ' -----[ EEPROM Data ]----------------------------------------------------- ' -----[ Initialization ]-------------------------------------------------- Setup: DEBUG CLS DEBUG CRSRXY, 0, 0, "Devantech SRF08 Range Finder Demo" DEBUG CRSRXY, 0, 1, "---------------------------------" i2cSlave = SRF08 ' set device ID i2cReg = RegCmd ' rev number in cmd reg GOSUB Read_Byte DEBUG CRSRXY, 0, 3, "Rev Num... " DEBUG DEC i2cData, CLREOL DEBUG CRSRXY, 0, 5, "Light..... " DEBUG CRSRXY, 0, 6, "Range..... " ' -----[ Program Code ]---------------------------------------------------- Main: i2cSlave = SRF08 i2cReg = RegCmd i2cData = RngIn ' get range in inches GOSUB Write_Byte PAUSE 65 ' allow measurement i2cReg = RegLight GOSUB Read_Byte DEBUG CRSRXY, 11, 5, DEC i2cData, CLREOL i2cReg = RegRange GOSUB Read_Word DEBUG CRSRXY, 11, 6, DEC i2cData, " in.", CLREOL GOTO Main END ' -----[ Subroutines ]----------------------------------------------------- ' -------------------------- ' High Level I2C Subroutines ' -------------------------- ' Writes low byte of i2cData to i2cReg Write_Byte: GOSUB I2C_Start i2cWork = i2cSlave GOSUB I2C_TX_Byte ' send device address i2cWork = i2cReg GOSUB I2C_TX_Byte ' send register number i2cWork = i2cData.LOWBYTE GOSUB I2C_TX_Byte ' send the data GOSUB I2C_Stop RETURN ' Writes i2cData to i2cReg Write_Word: GOSUB I2C_Start i2cWork = i2cSlave GOSUB I2C_TX_Byte ' send device address i2cWork = i2cReg GOSUB I2C_TX_Byte ' send register number i2cWork = i2cData.HIGHBYTE GOSUB I2C_TX_Byte ' send the data - high byte i2cWork = i2cData.LOWBYTE GOSUB I2C_TX_Byte ' send the data - low byte GOSUB I2C_Stop RETURN ' Read i2cData (8 bits) from i2cReg Read_Byte: GOSUB I2C_Start i2cWork = i2cSlave GOSUB I2C_TX_Byte ' send device address i2cWork = i2cReg GOSUB I2C_TX_Byte ' send register number GOSUB I2C_Start ' start (sets register) i2cWork = (i2cSlave | 1) GOSUB I2C_TX_Byte ' send read command GOSUB I2C_RX_Byte_Nak GOSUB I2C_Stop i2cData = i2cWork ' return the data RETURN ' Read i2cData (16 bits) from i2cReg Read_Word: GOSUB I2C_Start i2cWork = i2cSlave GOSUB I2C_TX_Byte ' send device address i2cWork = i2cReg GOSUB I2C_TX_Byte ' send register number GOSUB I2C_Start ' start (sets register) i2cWork = (i2cSlave | 1) GOSUB I2C_TX_Byte ' send read command GOSUB I2C_RX_Byte i2cData.HIGHBYTE = i2cWork ' read high byte of data GOSUB I2C_RX_Byte_Nak GOSUB I2C_Stop i2cData.LOWBYTE = i2cWork ' read low byte of data RETURN ' ------------------------- ' Low Level I2C Subroutines ' ------------------------- ' --- Start --- I2C_Start: ' I2C start bit sequence INPUT SDA INPUT SCL LOW SDA ' SDA --> low while SCL high Clock_Hold: DO : LOOP WHILE (SCL = 0) ' wait for device ready RETURN ' --- Transmit --- I2C_TX_Byte: SHIFTOUT SDA, SCL, MSBFIRST, [i2cWork\8] ' send byte to device SHIFTIN SDA, SCL, MSBPRE, [i2cAck\1] ' get acknowledge bit RETURN ' --- Receive --- I2C_RX_Byte_Nak: i2cAck = Nak ' no Ack = high GOTO I2C_RX I2C_RX_Byte: i2cAck = Ack ' Ack = low I2C_RX: SHIFTIN SDA, SCL, MSBPRE, [i2cWork\8] ' get byte from device SHIFTOUT SDA, SCL, LSBFIRST, [i2cAck\1] ' send ack or nak RETURN ' --- Stop --- I2C_Stop: ' I2C stop bit sequence LOW SDA INPUT SCL INPUT SDA ' SDA --> high while SCL high RETURN