IIC简介
IIC(Inter-Integrated Circuit)是一个多主从的串行总线,又叫I2C,是由飞利浦公司发明的通讯总线,属于半双工同步传输类型总线。IIC总线是非常常见的数据总线,仅仅使用两条线就能完成多机通讯,一条SCL时钟线,另外一条双向数据线SDA。
(随便百度了一下,相关介绍资料较多,就不赘述了。)
推荐看这一篇 “ IIC通信协议”-- 白码王子小张
通信过程中的几种状态
-
开始 IIC_Start()
从协议的角度来说,当时钟信号(SCK)处于高电平时,数据线(SDA)产生下降沿,表示开始通信。
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-1.png)
如上图所示,在时钟线处于高电平时,数据线下降沿代表开始信号。
结合C语言代码
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-2.png)
在开始通信前,先将时钟线、数据线所对应的IO口,配置成输出模式。
设置时钟线和数据线为高电平,延时4微妙后,拉低数据线,产生下降沿,表示通信开始。
在产生开始信号后,延时4微妙,拉低时钟线,准备发送或接受和数据。
-
发送 IIC_Write_Byte()
传输数据时,每一位数据都有一个时钟脉冲相对应,即在SCL串行时钟的配合下,在SDA上逐位地传送每一位数据。进行数据传输时,在SCL的高电平期间SDA上的电平必须保持稳定,只有在SCL为低电平期间,才允许SDA上的电平改变状态。即数据在SCL的上升沿到来之前就必须准备好,并在下降沿到来之前保持稳定。
(详情请阅读这篇文章 -->)
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-3.png)
结合实际电平信号图可以看到,数据线的电平变换在时钟线的低电平期间,而在时钟线的高电平期间都处于稳定状态。正好印证了上面有关传输数据时的协议规定。
结合C语言代码
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-4.png)
结合IIC_Start()函数,在发送第一个数据前,SCL已经处于低电平状态,此状态可以变换数据线的数据(高低电平)。
-
在发送数据之前,要保证时钟线处于低电平,数据线 IO 处于输出状态
-
将 1 字节的数据,具体化为八个时钟周期内连续的高低电平。
落实到具体的代码逻辑就是 (&)按位与 和(<<)左移。
比如,要发送的数据为 0xA0 ,转换成二进制 即 1010 0000 b
而发送都是从高位先开始发送,即发送顺序为1、0、1、0、0、0、0、0。
结合实际代码 0xA0 先左移 0 位 然后 和 0x80进行 按位与 操作
(1010 0000) & (1000 0000) = 1 & 1 = 1
如果 左移 后的 按位与 操作的结果为 1 就将 SDA置为 高电平 否则 SDA拉低。
3.数据发送完成后将 时钟线拉低
-
等待回复IIC_Wait_Ack()
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-5.png)
结合代码来说
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-6.png)
首先,开始读取前,将数据线 IO 设置成输入模式,准备读取从机的回复信号。
用while()一直等待,当收到从机低电平信号时,表示从机应答成功,否则继续等待。
等待超过205次后,返回应答超时停止等待,发送停止信号,结束通信。
-
接收IIC_Read_Byte()
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-7.png)
从实际电平信号图看,发送数据和接收数据的逻辑是完全一样的。
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-8.png)
从代码来说,也没啥特别需要注意的,就是在读取之前将数据线IO设置为输入。
就是为了使波形更加标准,对延时的数值进行了微调,使实际的时钟波形都在8us左右。
-
停止IIC_Stop()
在SCL保持高电平期间,SDA被释放,由低电平转变为高电平,产生上升沿,称为I2C总线的停止信号,标志着一次数据传输的终止。
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-9.png)
结合代码
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-10.png)
发送结束信号前,先将数据线和时钟线拉低。
先拉高时钟线,延时4us后,拉高数据线,产生上升沿,发送结束信号。
发送结束信号后将数据线和时钟线都设为输入模式。
-
发送回复IIC_Send_Ack()
发送回复是在主机接受完一帧(字节)数据后,回应从机,表示这一帧(字节)数据接收完毕,继续发送下一帧(字节)数据。
实际波形如下图
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-11.png)
结合代码和图片来说
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-12.png)
-
发送不回复IIC_NoAck()
发送不回复是在主机接完最后一帧(字节)数据后,回应从机,表示这一帧(字节)数据接收完毕,停止数据接收。IIC_NoAck() 后面紧跟的是 IIC_Stop()信号。
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-13.png)
代码和波形图基本和 IIC_ACK() 是一致的,只是数据线一直处于高电平没有拉低。
![iic 波形,单片机,嵌入式硬件,开源协议,51单片机,stm32,Powered by 金山文档](https://imgs.yssmx.com/Uploads/2023/09/704159-14.png)
C语言代码分享
示例工程还未整理,后面准备出一个STM32F103 和 屏幕通讯的示例工程。文章来源:https://www.toymoban.com/news/detail-704159.html
阿里网盘: 阿里云盘分享文章来源地址https://www.toymoban.com/news/detail-704159.html
到了这里,关于IIC代码波形对照详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!