首先,就是讲一下I2C的由来(以下内容copy自百度百科)
2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。
上面这段话概括一下就是,I2C两根线(数据线,和信号线),就能完成通讯。
削微拟人化一下,I2C通讯的过程有点像老师上课喊人。简单来说,咱不是每个人都有一个编号嘛,比如我学号就是14,上着课开着小差,突然老师:“十四号!起来回答问题”,然后我站起来:“到!老师”,老师就问了:“这道题怎么这么写。”然后我对答如流(大概率是不可能的)。反正只要老师布村心针对你,你就能坐下。
换到I2C协议里面(这里只考虑主机向从机发消息):
1,老师喊我学号,叫我答题,在I2C通讯里面,这就叫寻址。
2,我站起来,回应老师的点名,叫做从机的应答。
3,老师看到我人在,就开始提问(或者干其他的事情),这一过程就是主机向从机读或者写数据的操作
4,当然,老师提问也是有条件的,他总得上课时候提问我才会理的吧。上下课可以理解为I2C通讯开始和停止的标志。
大致上,就这几个步骤;
接下来咱们就着重看一下I2C时序图(我知道这玩意很劝退,但还是希望大伙听一下QAQ)

I2C通讯主要是靠两根线,一根时钟线(SCL),一根数据线(SDA),主要的几个环节就是:I2C通讯开始,I2C通讯结束,I2C应答信号,I2C的读和写操作。I2C通讯最大的一条禁忌就是:“千万千万千万不要在时钟线高电平的时候,数据线电平跳变”(因这是独属于I2C开始和I2C停止的权力)。
根据时序图,咱们文字描述一下一次I2C通讯的完整流程
1第一步:主机吧SCL和SDA都拉高,然后,在SCL 还是高电平的时候,突然就把SDA拉低,此时挂在I2C总线上的所有从机一激灵:“老子のmaster要点人了”。
2第二步:主机发送从机地址(8位的数据,最后一位是读写位,相当于通过I2C总线@全体,xxx号从机在吗?我要给你写点东西or你抓紧点儿的把数据给我)。然后主机释放I2C总线的控制权(其实就是拉高SDA和SCL,如果遥远的I2C那一头的从机接到命令了,他就会把SDA线拉低,这时候主机就会了然:“对上暗号了”)。
3第三步就是8位数据的读和写了,这一步看第二步,第二步是读操作,那这一步就是读8位数据,否则就是写8位数据。
4第四步就好说了,无论是读还是写,每一次8位数据传送完,接收数据那一方必须给发数据的一方发一个应答信号(应答信号参考第二步的应答过程)。
5第五步,就是如果有数据就重复 发(收)数据->应答-> 发(收)数据->应答……这个过程,没话可说就I2C_stop,下次通讯再见(拜拜了您嘞~)。
虽然我不太清楚我这样讲有没有讲清楚,但是我觉得自己描述的应该大概也许还比较到位吧(心虚……)
下面就是我
自己参考一些个大佬写的基于stm32HAL库的模拟I2C通讯的程序
请各位看官笑纳~
链接:https://pan.baidu.com/s/1sWv7AJ4cOUTse7j4E490zw?pwd=8888
提取码:8888