When bitbanging I2C, rather than switching the LOW/HIGH states of the pin, switch between LOW/HiZ by simply altering the DDR/DIR registers.Why is it like this? Why can't we switch LOW/HIGH states of data pin? My controller is communicating with only one slave.

  • 2
    \$\begingroup\$ Have you studied how I2C works? It should be pretty obvious why you can't just drive the lines high or low. \$\endgroup\$
    – Matt Young
    Commented Jun 7, 2015 at 5:32
  • \$\begingroup\$ Actually Iam trying to implement I2C in my controller which doest have I2C hardware driver. I am aware of I2C protocol (start,write, read, stop). According to my understanding, I need to configure 'DDR pins' of GPIO (SCL And SDA) as output, and to set/clear the SCL and SDA i need to change the 'data pins' accordingly. I am very much new to this module. Please guide me if I am wrong. \$\endgroup\$ Commented Jun 7, 2015 at 5:42
  • \$\begingroup\$ What would happen if you were driving high when the peripheral needed to drive low? Review the operation of I2C and you will see how that, and your original question, are solved. \$\endgroup\$ Commented Jun 7, 2015 at 5:57
  • \$\begingroup\$ SDA must be high-Z when high as either the master or slave may need to set it low. If the master is pulling high (not high-Z) and the slave needs to send a zero and pulls down the line, you will end up with the two chips fighting. For SCL, even if you only have one master, a slave may cause the master to pause by pulling the line low (clock streaching). Please read up on I2C: it appears you have a lot to learn. \$\endgroup\$
    – DoxyLover
    Commented Jun 7, 2015 at 5:57
  • \$\begingroup\$ This was already answered in the comment at your earlier question: electronics.stackexchange.com/questions/103440/… \$\endgroup\$ Commented Jun 7, 2015 at 5:59

1 Answer 1


Your code change the DDR/DIR bit of that pin because in I2C you want either an high impedance pin (pin set as input pin -> send a "1") or a super low impedance pin (output pin set to 0 -> send a "0"). By design I2C forbids to pull up the bus directly from the pin as it will cause very BAD things (one device setting an high, another device setting a low and... bang!!! a great short-circuit!). Pull up is done by the external 4.7K pull-ups. Any pin used for I2C should be open-drain.

  • \$\begingroup\$ Thanks... this solves my query.One last question.Lets say, I have initially configured a port(GPIO) pin as input, pin(HighZ), Now I want to write '0' to that port. So changing the pin data to '0'and then changing its DDR port to output is correct or, changing DDR port to output and then writing '0' is correct. I know what I am asking something silly, but I want to improve my basics regarding port configurations. \$\endgroup\$ Commented Jun 7, 2015 at 7:57
  • \$\begingroup\$ you got two registers: DDR and PORT register. When you set the DDR bit to "output" the pin will act depending on the content of the corresponding bit in the PORT register. So yes, you can set the PORT register to zero at init time and leave it as it is and then toggle the DDR bit as you want to be. \$\endgroup\$ Commented Jun 7, 2015 at 8:38

Not the answer you're looking for? Browse other questions tagged or ask your own question.