Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Using a PIC's digital I/O with an i2C communication bus

Status
Not open for further replies.

Steve311

Member
Hi All, I'm using a PIC16F684 as a master and a digital output accelerometer as the slave. I'm using a one of the digital I/Os as the data line. The data line will be pulled high and low from both the master and the slave, as well as start/stop bits, addressing and data bytes.

Will I need to set that specific digital I/O pin to an input when recieving data and set it as an output when sending data? Or will the uC realize that the line has been pulled low or high when I test the corresponding PORT register bit?

The accelerometer I'm using is a Kionix KXTF9.

Thanks in advance!
 
I the PIC16F684 has no hardware I2C so you will have to do all the I2C in software.
The data line will have to be changed from in to out and back.
You will have to clock the clk pin every edge.
 
Thank you., What do you mean by clock the clk pin every edge? If I send out a 1MHz clock from the PIC to the accelerometer continuously, then I thought each bit should be sent and received at a rate of 1uS?
 
From by memory:

SDA=1, CLK=1 idle condition
SDA=0, CLK=1 start
SDA=0, CLK=0 start
SDA= MSB of
CLK=1,
CLK=0,
SDA= data7
CLK=1,
CLK=0,
SDA= data6
CLK=1,
CLK=0,
SDA= data5
CLK=1,
CLK=0,
SDA= data4
CLK=1,
CLK=0,
SDA= data3
CLK=1,
CLK=0,
SDA= data2
CLK=1,
CLK=0,
SDA= data1
CLK=1,
CLK=0,
SDA= data 0 (lsb)
make SDA input
CLK=1,
read in data (acknowledge from slave)
CLK=0,
make SDA input or output depending on I or O
then do this again for data

a stop is
CLK=1
SDA=1
 
Thank you., What do you mean by clock the clk pin every edge? If I send out a 1MHz clock from the PIC to the accelerometer continuously, then I thought each bit should be sent and received at a rate of 1uS?
Where do you get the idea that I2C will run at 1mhz? OK new parts but the old parts will not.
The clock doe not run continuously but clocks 9 times / byte then stops.
 
I see, so the clock pin can just be triggered from high to low as a digital pulse for every edge. The clock will always be high when a start or stop command is sent. Data bits are sent with the clock low.

I don't fully understand why the Clock must go high to low inbetween each data bit. I thought the acknowledge comes after each byte of data is sent?
 
clock & data:
When clock is low data can change. When clock is high data is input. (level not edge)
clock=0, now change data, clock=1, now read data (slave and/or master), clock=0, change data

Start:
falling edge of data when clock is high
remember data should never change when clock is high (start or stop only)

Stop:
rising edge of data when clock is high
remember data should never change when clock is high (start or stop only)

Acknowledge: The bus may have a mixture of fast and slow devices. Every 9th bit is acknowledge. You should wait until the slave says "I have the data". data=0
 
The two bus wires should be open collector. (resistor pulls up, silicon pulls down) It will work with a drive high/drive low. (well most of the time)
 
If you are using straight assembler, you may want to look at a higher-level compiler (just to make your life easier). Oshonsoft Basic and **broken link removed** offer free (full featured) version you could try. They both have software I2C routines which make your life easier.
 
Below is an example program (untested) to poll the KXTF9
Code:
'* PIC16F684 * Kinox KXTF9 Example *'
'Title: Kinox KXTF9 Example
'Description: This program uses PIC16F684 to communicate with the Kinox KXTF9.
'from AN-023: Getting Started with the KXTF9
'Author: languer (2012)


'General Configuration
Define CONF_WORD = 0x33c4
Define CLOCK_FREQUENCY = 8
'Define SIMULATION_WAITMS_VALUE = 1
OSCCON = 0x71  'set for internal 8MHZ oscillator


'Variable Declarations
Symbol io_sda = RA0  'I2C SDA
Symbol io_scl = RA1  'I2C SCL
Symbol io_rs232 = RA2  'rs232 debug output

Const kxtf9_address = 0x0f
Const ctrl_reg1 = 0x1b
Const tilt_timer = 0x28
Const wuf_timer = 0x29
Const b2s_timer = 0x2a
Const xout_h = 0x07
Const yout_h = 0x09
Const zout_h = 0x0b

Dim _true As Bit
Dim _false As Bit

_true = True
_false = False


'Main Program
main:
Dim data_x As Byte
Dim data_y As Byte
Dim data_z As Byte
AllDigital
TRISA = %11111111
TRISC = %11111111

'power-up delay (110ms minimum)
WaitMs 200

Serout io_rs232, 9600, "Example to poll KXTF9", CrLf

'set accelerometer to read back acceleration data
I2CWrite io_sda, io_scl, kxtf9_address, ctrl_reg1, 0x98

While _true
	WaitMs 1000
	I2CRead io_sda, io_scl, kxtf9_address, xout_h, data_x
	I2CRead io_sda, io_scl, kxtf9_address, yout_h, data_y
	I2CRead io_sda, io_scl, kxtf9_address, zout_h, data_z
	Serout io_rs232, 9600, "X, Y, Z = ", #data_x, ", ", #data_y, ", ", #data_z, CrLf
Wend
End
 
Last edited:
Or you could just use the code on Nigel's site... He has an I2C software implementation for the pic16f628 (virtually the same chip )

The link is in my signature....
Or the direct link
 
Last edited:
The two bus wires should be open collector. (resistor pulls up, silicon pulls down) It will work with a drive high/drive low. (well most of the time)

For a single master system there's no 'need' for the clock line to be open collector, as only that single master ever controls it. However, it's normally done that way.
 
Thank you very much for your input Languer and Ronsimpson....I have definately made great progress with your posts. I feel I'm close..

So when I trigger the clock line before I send or recieve data bits.... Does the clock have to see a rising/falling edge? Or just a level....I'm a little unclear on if I need to pulse high or low during the clock pulse (or just have the data line in a low or high state during the trigger).

Also, about how long do I have to keep the clock on for to ensure I send/recieve data? I would assume there should be some delay to ensure both the KXTF9 and PIC read the data properly (but not for too long of course)...

Thanks Again in Advance!
 
Do not think edge. Think level.
When clock is low the data bus is not read by any device.
When clock is low master or slave can change the data.
When clock is high, the data must not change.
When clock is high, any device can and will read the data at any time.
 
The Kionix KXTF9 appears to be fast. 400khz clock rate.
I did not find timing for the part. All it said is 400khz. Using 1500 ohm pull up resistors.

I think you can find a I2C memory IC or some other part that also is 400khz and look at its timing.
 
...
So when I trigger the clock line before I send or recieve data bits.... Does the clock have to see a rising/falling edge? Or just a level...
...
Also, about how long do I have to keep the clock on for to ensure I send/recieve data? I would assume there should be some delay...
...

These things are specific to the I2C system and/or specific to the actual I2C device you are using. the datasheet for the device should have many timing diagrams and clearly written explanations of it's particular I2C implementation. :)
 
Here is a good data sheet for a SRAM I2C. This data sheet has timing diagrams. I know it is a different part but they both have "400khz bus" speed.
 
Status
Not open for further replies.

Latest threads

Back
Top