用Arduino中的Wire库网上已经有很多文章了,但是今天我要写的是稍微不一样的内容。
很早以前我就在汇编,用C来写I2C的驱动,但是因为工作性质的原因(我的工作不是这个行业),只是出于业余爱好在断断续续的玩这些东西,最近自己又在折腾Arduino玩ESP32,要驱动一颗I2C接口芯片。
Arduino没有这个芯片的库,所以不得不自己写一个。刚刚开始研究,逐步的记下来,今天是第一篇入门。
关于I2C总线上SDA和SCL的时序问题我不想讲太深入,网上资料能够搜索到很多。
一、I2C读写的大致流程
所以我要说的第一个问题是:读写原理。这个对Wire库的应用来说很重要,我会把I2C的读写原理和Wire的应用结合起来讲,把这个Wire库为什么这样用讲得更明白。
我们知道,I2C只有SDA和SCL线。时钟线上的脉冲始终是由master设备产生的,数据线是master和slave都可以拉高或拉低的。
master想与slave通信,大概流程是:
(1)master发起一个开始信号->
(2)master发送地址码,发送完毕后释放SDA->
(3)所有slave检查地址码,如果是自己的话就拉低SDA进行回应,然后释放掉SDA->
(4)发送方(可以master或者Slave)往SDA写想发送的数据,发送完一个字节8bit后,释放掉SDA,接收方拉低SDA给发送方一个回应ACK;如果发送方没有收到ACK,则表示接收方没有接收成功。
(e)数据传输结束后,master发送一个STOP信号。
以下分两种I2C器件类型,来更深入的讲读写上面的区别。
二、单寄存器简单器件,Addr+data
这是一类最为简单的器件,如I2C接口的IO扩展器件PCF8574。
这种器件内部只有一个寄存器,所以不存在写寄存器地址的问题。master想向它写数据不用先写寄存器地址,而是直接把数据发送给它,总线操作就是直接Addr+da