<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://www.marcelpost.com/wiki/index.php?action=history&amp;feed=atom&amp;title=I2C</id>
	<title>I2C - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://www.marcelpost.com/wiki/index.php?action=history&amp;feed=atom&amp;title=I2C"/>
	<link rel="alternate" type="text/html" href="https://www.marcelpost.com/wiki/index.php?title=I2C&amp;action=history"/>
	<updated>2026-06-30T12:35:06Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.39.17</generator>
	<entry>
		<id>https://www.marcelpost.com/wiki/index.php?title=I2C&amp;diff=1373&amp;oldid=prev</id>
		<title>Admin at 11:01, 16 March 2014</title>
		<link rel="alternate" type="text/html" href="https://www.marcelpost.com/wiki/index.php?title=I2C&amp;diff=1373&amp;oldid=prev"/>
		<updated>2014-03-16T11:01:33Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
various:&lt;br /&gt;
&lt;br /&gt;
[[i2c-master]]&lt;br /&gt;
&lt;br /&gt;
[[i2c-slave]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I&amp;#039;m currently working on coding a reliable I2C library that can act as a master, slave or both.&lt;br /&gt;
&lt;br /&gt;
The current library is not a stand-alone file, but needs to be included in the code. Below is the latest (not fully operational) i2cmaster.h, use at own risk.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// --- I2C Functions ---&lt;br /&gt;
// --- I2C Functions ---&lt;br /&gt;
// --- I2C Functions ---&lt;br /&gt;
&lt;br /&gt;
void i2cpin(int line, int state)&lt;br /&gt;
{&lt;br /&gt;
  // set the I2C SDA or SCL PIN&lt;br /&gt;
  // works on the PORTB registers&lt;br /&gt;
  &lt;br /&gt;
  if (state == 0)&lt;br /&gt;
  {&lt;br /&gt;
    // set the pin low&lt;br /&gt;
&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; line);     // set line to output&lt;br /&gt;
    PORTB &amp;amp;= ~(1 &amp;lt;&amp;lt; line);   // set it to zero&lt;br /&gt;
&lt;br /&gt;
  } else {&lt;br /&gt;
&lt;br /&gt;
    // set the pin high (let external pull-up resistor bring it high)&lt;br /&gt;
&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; line);  // set line to input&lt;br /&gt;
   &lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  //_delay_ms(500);   // use this as a debug tool&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_delay()&lt;br /&gt;
{&lt;br /&gt;
  // default delay in between I2C commands&lt;br /&gt;
  _delay_ms(10);   // seems to hover around 2-3ms&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_tx(char d)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // SDA is LOW, SCL is HIGH (inherited from i2c-start command)&lt;br /&gt;
&lt;br /&gt;
  // bring clock low to start data transfer&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SCL,LOW);&lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
  &lt;br /&gt;
  char x;&lt;br /&gt;
  //static int b;&lt;br /&gt;
  for(x=8; x; x--) &lt;br /&gt;
  { &lt;br /&gt;
    if(d&amp;amp;0x80) &lt;br /&gt;
    {&lt;br /&gt;
      i2cpin(SDA,HIGH);  &lt;br /&gt;
    } else {&lt;br /&gt;
      i2cpin(SDA,LOW);  &lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    i2cpin(SCL,HIGH);                  // strobe clock&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // allow for I2C clock stretching (SCL can be held low by slave)&lt;br /&gt;
    // see I2C_STRETCH_TIMEOUT_MS&lt;br /&gt;
&lt;br /&gt;
    int stretch_counter;&lt;br /&gt;
    &lt;br /&gt;
    for (stretch_counter=0; stretch_counter &amp;lt; I2C_STRETCH_TIMEOUT_MS; stretch_counter++)&lt;br /&gt;
    {&lt;br /&gt;
      // allow for some cycles for SCL to go high  &lt;br /&gt;
&lt;br /&gt;
      if (bit_is_clear(PINB,SCL))&lt;br /&gt;
      {&lt;br /&gt;
        // SCL is held low by slave&lt;br /&gt;
        // we&amp;#039;ll just wait a little &lt;br /&gt;
&lt;br /&gt;
        _delay_ms(1);&lt;br /&gt;
&lt;br /&gt;
      } else {&lt;br /&gt;
&lt;br /&gt;
        // SCL has risen, ready to move on&lt;br /&gt;
        stretch_counter = I2C_STRETCH_TIMEOUT_MS;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //_delay_us(1);                      // 1-3 us  &lt;br /&gt;
    i2cpin(SCL,LOW);&lt;br /&gt;
&lt;br /&gt;
    d &amp;lt;&amp;lt;= 1;                 // shift byte&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,HIGH);         // first bring SDA into listening mode&lt;br /&gt;
&lt;br /&gt;
  //_delay_ms(1);             // delay no longer needed, this used to be 1.6ms&lt;br /&gt;
  //_delay_us(600);&lt;br /&gt;
&lt;br /&gt;
  // read acknowledge bit if any&lt;br /&gt;
&lt;br /&gt;
  // an addressed i2c slave will have already set SDA low&lt;br /&gt;
  _delay_us(5);             // give the bus some time to possibly bring the pin high&lt;br /&gt;
  i2cpin(SCL,HIGH);         // start the clock pulse&lt;br /&gt;
&lt;br /&gt;
  _delay_us(5);             // this should be 10us or so&lt;br /&gt;
&lt;br /&gt;
  if (bit_is_set(PINB,SDA))&lt;br /&gt;
  {&lt;br /&gt;
    got_ack=0;&lt;br /&gt;
  } else {&lt;br /&gt;
    got_ack=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,LOW);         // we now bring SDA low &lt;br /&gt;
  _delay_us(10);          // give the bus some time?    ----- may go &lt;br /&gt;
&lt;br /&gt;
  i2cpin(SCL,LOW);          // end the clock pulse&lt;br /&gt;
&lt;br /&gt;
  // slave detects SCL is low and will release SDA &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  _delay_ms(3);    // this should be 10us or so&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // return b;&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_start(char i2c_id)&lt;br /&gt;
{&lt;br /&gt;
  // SDA goes from high to low while SCL is high&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,HIGH); &lt;br /&gt;
  _delay_us(10);    // give bus some time to bring SDA high&lt;br /&gt;
  i2cpin(SCL,HIGH);&lt;br /&gt;
&lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,LOW);&lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // send the I2C Device ID&lt;br /&gt;
&lt;br /&gt;
  // send as Write (last bit is 0)&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  i2c_tx(i2c_id&amp;lt;&amp;lt;1);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_stop()&lt;br /&gt;
{&lt;br /&gt;
  // SDA goes from low to high while SCL is high&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,LOW);&lt;br /&gt;
  _delay_us(20);    // give bus some time to bring SDA high&lt;br /&gt;
  i2cpin(SCL,LOW); &lt;br /&gt;
&lt;br /&gt;
  _delay_ms(6);&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SCL,HIGH);&lt;br /&gt;
  _delay_ms(6);&lt;br /&gt;
&lt;br /&gt;
  i2cpin(SDA,HIGH);&lt;br /&gt;
  _delay_ms(4);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_text(char *StrData)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  int p = 0;&lt;br /&gt;
  int q = strlen(StrData);&lt;br /&gt;
  int temp = 0;&lt;br /&gt;
&lt;br /&gt;
  for (p = 0; p &amp;lt; q; p++)&lt;br /&gt;
  {&lt;br /&gt;
    temp = StrData[p];&lt;br /&gt;
    i2c_tx(temp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_number(int number)&lt;br /&gt;
{&lt;br /&gt;
  int digits;&lt;br /&gt;
&lt;br /&gt;
  if (number == 0)&lt;br /&gt;
  {&lt;br /&gt;
    digits = 0;&lt;br /&gt;
    int array[0];&lt;br /&gt;
    array[0]=0;&lt;br /&gt;
    i2c_tx(array[0]+48);&lt;br /&gt;
&lt;br /&gt;
  } else {&lt;br /&gt;
&lt;br /&gt;
    // determine the number of digits&lt;br /&gt;
    digits = (int) (log(number)/log(10))+1;&lt;br /&gt;
&lt;br /&gt;
    // split up the number&amp;#039;s digits into an array&lt;br /&gt;
    int i = digits -1;&lt;br /&gt;
    int array[digits];&lt;br /&gt;
    while (number &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
      array[i--] = number % 10;&lt;br /&gt;
      number /= 10;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // send array over i2c&lt;br /&gt;
    for (i =0; i &amp;lt;= digits-1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      i2c_tx(array[i]+48);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_hex(uint8_t x)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // sends one byte in hex (without 0x prefix) to the lcd&lt;br /&gt;
&lt;br /&gt;
  char nibble;&lt;br /&gt;
&lt;br /&gt;
  /* extract high nibble */&lt;br /&gt;
  nibble = x &amp;amp; 0xf0;        // (resets lower nibble to all zero&amp;#039;s)&lt;br /&gt;
  nibble = x &amp;gt;&amp;gt; 4;          // (moves high nibble to lower nibble)&lt;br /&gt;
&lt;br /&gt;
  // output the high nibble&lt;br /&gt;
  if(nibble &amp;lt; 10)&lt;br /&gt;
  {&lt;br /&gt;
    i2c_tx(48 + nibble);&lt;br /&gt;
  } else {&lt;br /&gt;
    i2c_tx(65 + nibble - 10);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /* do the same on the low nibble */&lt;br /&gt;
  nibble = x &amp;amp; 0x0f;&lt;br /&gt;
&lt;br /&gt;
  if(nibble &amp;lt; 10)&lt;br /&gt;
  {&lt;br /&gt;
    i2c_tx(48 + nibble);&lt;br /&gt;
  } else {&lt;br /&gt;
    i2c_tx(65 + nibble - 10);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
usage:&lt;br /&gt;
&lt;br /&gt;
in main()&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    // -- set up lines for I2C --&lt;br /&gt;
    pinMode(SDA,INPUT);&lt;br /&gt;
    pinMode(SCL,INPUT);&lt;br /&gt;
    PORTB = 0;    // disable internal pullup resistors&lt;br /&gt;
    PORTB &amp;amp;= ~(1 &amp;lt;&amp;lt; SDA);  // set SDA LOW (makes line output)&lt;br /&gt;
    PORTB &amp;amp;= ~(1 &amp;lt;&amp;lt; SCL);  // set SCL LOW (makes line output)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    i2c_start(LCD_I2C_DEVICE_ID);&lt;br /&gt;
    i2c_tx(12); //clear screen&lt;br /&gt;
    i2c_tx(&amp;#039; &amp;#039;);&lt;br /&gt;
    i2c_lcd_number(voltage_int); // measured voltage, whole numbers &lt;br /&gt;
    i2c_tx(&amp;#039;.&amp;#039;);&lt;br /&gt;
    i2c_lcd_number(voltage_dec1); // decimal 1&lt;br /&gt;
    i2c_lcd_number(voltage_dec2); // decimal 2&lt;br /&gt;
    i2c_tx(&amp;#039;V&amp;#039;);&lt;br /&gt;
    i2c_tx(&amp;#039; &amp;#039;);&lt;br /&gt;
    i2c_tx(&amp;#039; &amp;#039;);&lt;br /&gt;
    i2c_lcd_number(run_counter);   &lt;br /&gt;
    i2c_stop();   &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
&lt;br /&gt;
  i2cmaster.h&lt;br /&gt;
&lt;br /&gt;
  defines functions for bit-banging the I2C protocol on generic I/O pins&lt;br /&gt;
&lt;br /&gt;
  Author: M. Post&lt;br /&gt;
  Last modified: 28 January 2012&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  Add the following to your main.c in order to make use of this header file:&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
  #define HIGH      1&lt;br /&gt;
  #define LOW       0&lt;br /&gt;
  #define INPUT     1&lt;br /&gt;
  #define OUTPUT    0&lt;br /&gt;
&lt;br /&gt;
  // I2C pin definitions&lt;br /&gt;
  #define SCL  PB0    // Define Clock pin  &lt;br /&gt;
  #define SDA  PB1    // Define Data pin  &lt;br /&gt;
  int got_ack;&lt;br /&gt;
  int LCD_I2C_DEVICE_ID=58;&lt;br /&gt;
  int I2C_STRETCH_TIMEOUT_MS=100;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;other includes&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  #include &amp;quot;i2cmaster.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;defines, rest of code, etc..&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setPin(int line, int state)&lt;br /&gt;
{&lt;br /&gt;
  // set the I2C SDA or SCL PIN&lt;br /&gt;
&lt;br /&gt;
  if (state == LOW)&lt;br /&gt;
  {&lt;br /&gt;
    // set the pin low&lt;br /&gt;
&lt;br /&gt;
    DDRB |= (1 &amp;lt;&amp;lt; line);     // set line to output&lt;br /&gt;
    PORTB &amp;amp;= ~(1 &amp;lt;&amp;lt; line);   // set it to zero&lt;br /&gt;
&lt;br /&gt;
  } else {&lt;br /&gt;
&lt;br /&gt;
    // set the pin high (let external pull-up resistor bring it high)&lt;br /&gt;
&lt;br /&gt;
    DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; line);  // set line to input&lt;br /&gt;
   &lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_delay()&lt;br /&gt;
{&lt;br /&gt;
  // default delay in between I2C commands&lt;br /&gt;
  _delay_ms(10);   // seems to hover around 2-3ms&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_tx(char d)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  int stretch_counter;&lt;br /&gt;
  char x;&lt;br /&gt;
&lt;br /&gt;
  // SDA is LOW, SCL is HIGH (inherited from i2c-start command)&lt;br /&gt;
&lt;br /&gt;
  // bring clock low to start data transfer&lt;br /&gt;
&lt;br /&gt;
  setPin(SCL,LOW);&lt;br /&gt;
  &lt;br /&gt;
  for(x=8; x; x--) &lt;br /&gt;
  { &lt;br /&gt;
    //_delay_us(10); // (additional time inbetween scl pulses)&lt;br /&gt;
&lt;br /&gt;
    // if statement:  if (d &amp;amp; 0x80) &lt;br /&gt;
    // 0x80 = 128d = 10000 0000b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    if(d&amp;amp;0x80) &lt;br /&gt;
    {&lt;br /&gt;
      _delay_us(15);&lt;br /&gt;
      setPin(SDA,HIGH);  &lt;br /&gt;
    } else {&lt;br /&gt;
      setPin(SDA,LOW);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    _delay_us(30); // (additional time before scl pulse)&lt;br /&gt;
    setPin(SCL,HIGH);                  // strobe clock&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // allow for I2C clock stretching (SCL can be held low by slave)&lt;br /&gt;
    // see I2C_STRETCH_TIMEOUT_MS&lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
    for (stretch_counter=0; stretch_counter &amp;lt; I2C_STRETCH_TIMEOUT_MS; stretch_counter++)&lt;br /&gt;
    {&lt;br /&gt;
      // allow for some cycles for SCL to go high  &lt;br /&gt;
&lt;br /&gt;
      if (bit_is_clear(PINB,SCL))&lt;br /&gt;
      {&lt;br /&gt;
        // SCL is held low by slave&lt;br /&gt;
        // we&amp;#039;ll just wait a little &lt;br /&gt;
&lt;br /&gt;
        _delay_ms(1);&lt;br /&gt;
&lt;br /&gt;
      } else {&lt;br /&gt;
&lt;br /&gt;
        // SCL has risen, ready to move on&lt;br /&gt;
        stretch_counter = I2C_STRETCH_TIMEOUT_MS;&lt;br /&gt;
      }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    //_delay_us(10);         // additional SCL-high time&lt;br /&gt;
    setPin(SCL,LOW);&lt;br /&gt;
&lt;br /&gt;
    d &amp;lt;&amp;lt;= 1;                 // shift byte&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  // byte is now sent&lt;br /&gt;
  // next is to read a possible ack from the slave device&lt;br /&gt;
  // scl is already set low by the master&lt;br /&gt;
&lt;br /&gt;
  setPin(SDA,HIGH);         // first bring SDA into listening mode&lt;br /&gt;
  &lt;br /&gt;
  // read i2c slave acknowledge bit if any&lt;br /&gt;
&lt;br /&gt;
  // an addressed i2c slave will set SDA low very quickly&lt;br /&gt;
&lt;br /&gt;
  _delay_us(40);           // space between the previous SCL pulse&lt;br /&gt;
  setPin(SCL,HIGH);        // start the clock pulse&lt;br /&gt;
&lt;br /&gt;
  //_delay_us(5);          // this should be 5us or so&lt;br /&gt;
&lt;br /&gt;
  if (bit_is_set(PINB,SDA))&lt;br /&gt;
  {&lt;br /&gt;
    got_ack=0;&lt;br /&gt;
  } else {&lt;br /&gt;
    got_ack=1;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  setPin(SDA,LOW);         // we now bring SDA low (so we don&amp;#039;t see a spike on SDA&lt;br /&gt;
                           // when the master brings SCL low again&lt;br /&gt;
 &lt;br /&gt;
  _delay_us(25);           // show a nice long SCL high pulse for easier debugging&lt;br /&gt;
&lt;br /&gt;
  setPin(SCL,LOW);         // end the clock pulse&lt;br /&gt;
                           // this is also a signal for the i2c slave to release SDA &lt;br /&gt;
&lt;br /&gt;
  _delay_us(10);           // give the bus some time   &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_start()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // SDA goes LOW while SCL is HIGH&lt;br /&gt;
&lt;br /&gt;
  // TODO: check the state of the lines first (they should both be HIGH)&lt;br /&gt;
&lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
  setPin(SDA,LOW);  // start condition&lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_repeatedstart()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // SDA goes LOW while SCL is HIGH&lt;br /&gt;
&lt;br /&gt;
  // first bring SCL and SDA LOW  (SCL and SDA should already be low)&lt;br /&gt;
&lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
  setPin(SCL,LOW); &lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
  setPin(SDA,LOW); &lt;br /&gt;
&lt;br /&gt;
   // then we bring them both HIGH&lt;br /&gt;
 &lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
  setPin(SDA,HIGH); &lt;br /&gt;
  _delay_us(10);    &lt;br /&gt;
  setPin(SCL,HIGH); &lt;br /&gt;
  _delay_us(100);    &lt;br /&gt;
&lt;br /&gt;
  // then we generate the repeated start condition&lt;br /&gt;
&lt;br /&gt;
  setPin(SDA,LOW); &lt;br /&gt;
  _delay_us(100);&lt;br /&gt;
  setPin(SCL,LOW); &lt;br /&gt;
  _delay_us(100);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_startRead(char i2c_id)&lt;br /&gt;
{&lt;br /&gt;
  // SDA goes from high to low while SCL is high&lt;br /&gt;
 &lt;br /&gt;
  i2c_start();&lt;br /&gt;
&lt;br /&gt;
  // send the I2C Device ID&lt;br /&gt;
&lt;br /&gt;
  // send as Read (last bit is 1)&lt;br /&gt;
  &lt;br /&gt;
  i2c_id = i2c_id &amp;lt;&amp;lt; 1; // shift all bits one position to the left&lt;br /&gt;
  i2c_id |= 1 &amp;lt;&amp;lt; 0;     // then set bit 0 to 1&lt;br /&gt;
  i2c_tx(i2c_id); &lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_startWrite(char i2c_id)&lt;br /&gt;
{&lt;br /&gt;
  // SDA goes from high to low while SCL is high&lt;br /&gt;
&lt;br /&gt;
  i2c_start();&lt;br /&gt;
&lt;br /&gt;
  // send the I2C Device ID&lt;br /&gt;
&lt;br /&gt;
  // send as Write (last bit is 0)&lt;br /&gt;
&lt;br /&gt;
  i2c_id = i2c_id &amp;lt;&amp;lt; 1; // shift all bits one position to the left&lt;br /&gt;
  i2c_id |= 0 &amp;lt;&amp;lt; 0;     // then set bit 0 to 0&lt;br /&gt;
  i2c_tx(i2c_id);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_stop()&lt;br /&gt;
{&lt;br /&gt;
  // SDA goes HIGH while SCL is HIGH&lt;br /&gt;
&lt;br /&gt;
  // TODO: check if both lines are low&lt;br /&gt;
&lt;br /&gt;
  _delay_us(10);&lt;br /&gt;
  setPin(SCL,LOW); &lt;br /&gt;
  _delay_us(10);&lt;br /&gt;
  setPin(SDA,LOW);&lt;br /&gt;
  _delay_us(10); &lt;br /&gt;
&lt;br /&gt;
  setPin(SCL,HIGH); &lt;br /&gt;
  _delay_us(100);    // at least 100 us for I2C_LCD module  :-/&lt;br /&gt;
  setPin(SDA,HIGH);  // stop condition&lt;br /&gt;
  _delay_us(10);&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_text(char *StrData)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  int p = 0;&lt;br /&gt;
  int q = strlen(StrData);&lt;br /&gt;
  int temp = 0;&lt;br /&gt;
&lt;br /&gt;
  for (p = 0; p &amp;lt; q; p++)&lt;br /&gt;
  {&lt;br /&gt;
    temp = StrData[p];&lt;br /&gt;
    i2c_tx(temp);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_number(int number)&lt;br /&gt;
{&lt;br /&gt;
  int digits;&lt;br /&gt;
&lt;br /&gt;
  if (number == 0)&lt;br /&gt;
  {&lt;br /&gt;
    digits = 0;&lt;br /&gt;
    int array[0];&lt;br /&gt;
    array[0]=0;&lt;br /&gt;
    i2c_tx(array[0]+48);&lt;br /&gt;
&lt;br /&gt;
  } else {&lt;br /&gt;
&lt;br /&gt;
    // determine the number of digits&lt;br /&gt;
    digits = (int) (log(number)/log(10))+1;&lt;br /&gt;
&lt;br /&gt;
    // split up the number&amp;#039;s digits into an array&lt;br /&gt;
    int i = digits -1;&lt;br /&gt;
    int array[digits];&lt;br /&gt;
    while (number &amp;gt; 0)&lt;br /&gt;
    {&lt;br /&gt;
      array[i--] = number % 10;&lt;br /&gt;
      number /= 10;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // send array over i2c&lt;br /&gt;
    for (i =0; i &amp;lt;= digits-1; i++)&lt;br /&gt;
    {&lt;br /&gt;
      i2c_tx(array[i]+48);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void i2c_lcd_hex(uint8_t x)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // sends one byte in hex (without 0x prefix) to the lcd&lt;br /&gt;
&lt;br /&gt;
  char nibble;&lt;br /&gt;
&lt;br /&gt;
  /* extract high nibble */&lt;br /&gt;
  nibble = x &amp;amp; 0xf0;        // (resets lower nibble to all zero&amp;#039;s)&lt;br /&gt;
  nibble = x &amp;gt;&amp;gt; 4;          // (moves high nibble to lower nibble)&lt;br /&gt;
&lt;br /&gt;
  // output the high nibble&lt;br /&gt;
  if(nibble &amp;lt; 10)&lt;br /&gt;
  {&lt;br /&gt;
    i2c_tx(48 + nibble);&lt;br /&gt;
  } else {&lt;br /&gt;
    i2c_tx(65 + nibble - 10);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  /* do the same on the low nibble */&lt;br /&gt;
  nibble = x &amp;amp; 0x0f;&lt;br /&gt;
&lt;br /&gt;
  if(nibble &amp;lt; 10)&lt;br /&gt;
  {&lt;br /&gt;
    i2c_tx(48 + nibble);&lt;br /&gt;
  } else {&lt;br /&gt;
    i2c_tx(65 + nibble - 10);&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
unsigned char i2c_rxbyte()&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  unsigned char rxbyte=0;&lt;br /&gt;
  int bitcount=8;&lt;br /&gt;
&lt;br /&gt;
  setPin(SDA,HIGH);  // release SDA so we can listen what the slave has to say&lt;br /&gt;
 &lt;br /&gt;
   // the ic2_tx command lastly sent the ack pulse and now has SDA and SCL set to LOW&lt;br /&gt;
   // we now control the read from the i2c slave device by pulsing SCL and reading SDA &lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
  while (bitcount &amp;gt; 0)&lt;br /&gt;
  { &lt;br /&gt;
  &lt;br /&gt;
    rxbyte = rxbyte &amp;lt;&amp;lt; 1; // shift all bits in rxbyte one position to the left&lt;br /&gt;
    &lt;br /&gt;
        setPin(SCL,HIGH);         // start the clock pulse&lt;br /&gt;
    _delay_us(I2C_SCL_T_HIGH_US);           // give the bus some time to possibly bring the pin high&lt;br /&gt;
&lt;br /&gt;
        if (bit_is_set(PINB,SDA))&lt;br /&gt;
    {&lt;br /&gt;
      // -- detected bit &amp;#039;1&amp;#039; --&lt;br /&gt;
         &lt;br /&gt;
      rxbyte |= 1 &amp;lt;&amp;lt; 0 ; // sets bit 0 of rxbyte to 1&lt;br /&gt;
&lt;br /&gt;
    } else {&lt;br /&gt;
&lt;br /&gt;
      // -- detected bit &amp;#039;0&amp;#039; --&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    setPin(SCL,LOW);         // stop the clock pulse&lt;br /&gt;
    _delay_us(I2C_SCL_T_LOW_US);           // give the bus some time to possibly bring the pin high&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
    bitcount--;  // decrement bitcounter&lt;br /&gt;
        &lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
  setPin(SCL,HIGH); &lt;br /&gt;
        &lt;br /&gt;
  return rxbyte;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
unsigned char i2c_read(uint8_t i2c_id, uint16_t DEV_REG)&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  // reading the memory address contents from an I2C Slave Device&lt;br /&gt;
  &lt;br /&gt;
  unsigned char read_result=0;&lt;br /&gt;
  &lt;br /&gt;
  // send start sequence as write (so we can specify which address we want to read)&lt;br /&gt;
  i2c_startWrite(i2c_id);  // sends i2c start condition + i2c address+0(w)&lt;br /&gt;
&lt;br /&gt;
  // send the address word we want to query on the device&lt;br /&gt;
  &lt;br /&gt;
  // for the 24LC256 we need to do this in two goes. First the MSB then the LSB&lt;br /&gt;
 &lt;br /&gt;
  i2c_tx(DEV_REG&amp;gt;&amp;gt;8);        // shift 8 bits to the right to get the high byte &lt;br /&gt;
  i2c_tx(DEV_REG &amp;amp; 0xff);    // mask out the lower 8 bits to get the low byte&lt;br /&gt;
&lt;br /&gt;
  // -- send repeated start --&lt;br /&gt;
&lt;br /&gt;
  i2c_repeatedstart();&lt;br /&gt;
&lt;br /&gt;
  // send the I2C Device ID as Read (last bit is 1)&lt;br /&gt;
  &lt;br /&gt;
  i2c_id = i2c_id &amp;lt;&amp;lt; 1; // shift all bits one position to the left&lt;br /&gt;
  i2c_id |= 1 &amp;lt;&amp;lt; 0;     // then set bit 0 to 1&lt;br /&gt;
  i2c_tx(i2c_id); &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  // the slave will acknowledge and then transmit the 8-bit data word&lt;br /&gt;
&lt;br /&gt;
  // read data from device, one byte long&lt;br /&gt;
  read_result=i2c_rxbyte();&lt;br /&gt;
  &lt;br /&gt;
  i2c_stop();  &lt;br /&gt;
&lt;br /&gt;
  return read_result;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>