Hi,

I have been struggling for the past few days trying to interface an I2C pressure sensor from SensorTechnics with the PIC16F1827. I successfully bit banged the sensor using a Basic Stamp II a few weeks ago so I know that the sensor is working properly. However, even when I convert the bit banging code to the PIC it still doesn't work, so I know I am doing something simple incorrectly.

I can see clock and data when I connect my oscilloscope to the I/O pins so I know their is activity on the ports, but the result is always filled 0's.

I2C DataSheet for Pressure Sensor

DataSheet for the PIC16F1827 chip
  1. When you use the I2CREAD command does it send a START condition?
  2. Using this syntax
    Code:
    I2CRead sda,scl,$F1,[result1,result2]
    does the I2CREAD command send the device address? and an along with an Ack, Nak after the two bytes?

Do I need to use an I2CWRITE command to write the address to the I2C slave after manually generating a START condition myself?

Code:
DEFINE HSER_RCSTA 90h       ' Define Receive Port
DEFINE HSER_TXSTA 24h       ' Define Transmit Port

DEFINE HSER_BAUD    9600    ' Decalre 9600 Baud Rate for Serial Port
DEFINE OSC 20

scl VAR PORTB.4: TRISB.4 = 1 ' I2C clock input
sda VAR PORTB.1: TRISB.1 = 1 ' I2C data input

LED     VAR     PORTB.0     ' Assign name "LED" to PORTB.0
addr    VAR     Byte        ' I2C Address Variable
result1  VAR     BYTE        ' I2C Result Variable
result2  VAR     BYTE        ' I2C Result Variable
result  VAR WORD

ADDR = %11110001

'Reset Digi Xbee Module
LOW PORTB.3 
HIGH PORTB.3

mainloop:

' *** Flash LED (HeartBeat)

   High LED         ' Turn on LED connected to PORTB.0
   Pause 1000       ' Delay for .5 seconds

' *** Read I2C

   Low LED          ' Turn off LED connected to PORTB.0
   Pause 1000       ' Delay for .5 seconds

   TRISB.1 = 1
   TRISb.4 = 1
   
   HIGH SDA
   HIGH SCL
   
   LOW sda

   I2CRead sda,scl,addr,[result1,result2], i2c_error

   PAUSE 1000      ' Pause 1 Second for Read Operation to complete

   HSEROUT ["Value:", BIN8 result1, BIN8 result2]  ' Output Pressure reading through Serial Port
   
   Goto mainloop   ' Go back to loop and blink LED forever
   
   End

' Trasnmit Error if Reading unable to occur
i2c_error:

   HSEROUT ["Error"]
   
   GOTO mainloop
Here is the bit banging code

Code:
DEFINE HSER_RCSTA 90h       ' Define Receive Port
DEFINE HSER_TXSTA 24h       ' Define Transmit Port
'DEFINE HSER_SPBRG 129
DEFINE OSC 20
DEFINE HSER_BAUD    9600    ' Declare 9600 Baud Rate for Serial Port

'Include Basic Stamp II Command Support
INCLUDE "modedefs.bas"


' ------------------------------------------------------------------------------ '
' I/O Definitions
' ------------------------------------------------------------------------------ '
SDA             VAR PORTB.1                       ' I2C serial data line
SCL             VAR PORTB.4                       ' I2C serial clock line

' ------------------------------------------------------------------------------ '
' Constants
' ------------------------------------------------------------------------------ '
Ack             CON     0               ' acknowledge bit
Nak             CON     1               ' no ack bit

slaveAddress    CON     %11110001       'SensorTechnics Slave Address

' ------------------------------------------------------------------------------ '
' Variables
' ------------------------------------------------------------------------------ '
i2cData         VAR     Word                    ' data to/from device
i2cWork         VAR     Byte                    ' work byte for TX routine
i2cAck          VAR     Bit                     ' Ack bit from device

' ------------------------------------------------------------------------------ '
' Initialization
 '------------------------------------------------------------------------------ '
Init:
  PAUSE 250

  i2cACK = 0
  
 ' Reset XBee
  LOW PORTB.3  
  HIGH PORTB.3

TRISB.1 = 0
TRISB.4 = 0

PAUSE 5000
   
' ------------------------------------------------------------------------------ '
' Program Code
' ------------------------------------------------------------------------------ '


Main:

 
  GOSUB Read_Word

  Hserout ["Current Pressure Reading (16 BITS): " , BIN16 i2cData]

  PAUSE 1000

  GOTO Main

  END



' ------------------------------------------------------------------------------ '
' SensorTechnics Access Subroutines
' ------------------------------------------------------------------------------ '

' Read i2cData (16 bits) from Sensor

Read_Word:
 
  GOSUB I2C_Start                               ' Send START Condition

  i2cWork = slaveAddress                        ' Set Slave Address
  GOSUB I2C_TX_Byte                             ' Send Slave Address

  GOSUB I2C_RX_Byte
  i2cData.HIGHBYTE = i2cWork                    ' Read high byte of data / send ack

  GOSUB I2C_RX_Byte_Nak
  i2cData.LOWBYTE = i2cWork                     ' Read low byte of data /send nack

  GOSUB I2C_Stop                                ' Send STOP Command

  RETURN

' ------------------------------------------------------------------------------ '
' Low Level I2C Subroutines
' ------------------------------------------------------------------------------ '
' --- Start ---
I2C_Start:                                      ' I2C start bit sequence

  TRISB.1 = 1
  TRISB.4 = 1
  
  'HIGH SDA                                     ' Pull SDA High
  'HIGH SCL                                     ' Pull SCL High

  LOW SDA                                      ' SDA -> low while SCL high

Hserout ["Waiting for Clock"]

Clock_Hold:
  IF (PORTB.4 = 0) THEN Clock_Hold      ' device ready?

PAUSE 500

  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:

  i2cWork = %00000000

  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
  
  TRISB.1 = 1
  TRISB.4 = 1
  
  HIGH SCL
  HIGH SDA                                  ' SDA --> high while SCL high
  
  RETURN
Any help would be appreciated, thanks in advance!

Ben