首页 » 通讯 » IIC通信协议搞懂这篇就够了_暗记_旗子

IIC通信协议搞懂这篇就够了_暗记_旗子

乖囧猫 2025-01-11 07:32:39 0

扫一扫用手机浏览

文章目录 [+]

I2C(IIC)属于两线式串行总线,由飞利浦公司开拓用于微掌握器(MCU)和外围设备(从设备)进行通信的一种总线,属于一主多从(一个主设备(Master),多个从设备(Slave))的总线构造,总线上的每个设备都有一个特定的设备地址,以区分同一I2C总线上的其他设备。

物理I2C接口有两根双向线,串行时钟线(SCL)和串行数据线(SDA)组成,可用于发送和吸收数据,但是通信都是由主设备发起,从设备被动相应,实现数据的传输。

IIC通信协议搞懂这篇就够了_暗记_旗子 IIC通信协议搞懂这篇就够了_暗记_旗子 通讯

I2C主设备与从设备的一样平常通信过程

IIC通信协议搞懂这篇就够了_暗记_旗子 IIC通信协议搞懂这篇就够了_暗记_旗子 通讯
(图片来自网络侵删)

一. 主设备给从设备发送/写入数据:

1. 主设备发送起始(START)旗子暗记

2. 主设备发送设备地址到从设备

3. 等待从设备相应(ACK)

4. 主设备发送数据到从设备,一样平常发送的每个字节数据后会随着等待吸收来自从设备的相应(ACK)

5. 数据发送完毕,主设备发送停滞(STOP)旗子暗记终止传输

二. 主设备从从设备吸收/读取数据

1. 设备发送起始(START)旗子暗记

2. 主设备发送设备地址到从设备

3. 等待从设备相应(ACK)

4. 主设备吸收来自从设备的数据,一样平常吸收的每个字节数据后会随着向从设备发送一个相应(ACK)

5. 一样平常吸收到末了一个数据后会发送一个无效相应(NACK),然后主设备发送停滞(STOP)旗子暗记终止传输

注:详细通信过程需视详细时序图而定

I2C通信的实现

一. 利用I2C掌握器实现

便是利用芯片上的I2C外设,也便是硬件I2C,它有相应的I2C驱动电路,有专用的IIC引脚,效率更高,写代码会相对大略,只要调用I2C的掌握函数即可,不须要用代码去掌握SCL、SDA的各种高低电平变革来实现I2C协议,只须要将I2C协议中的可变部分(如:从设备地址、传输数据等等)通过函数传参给掌握器,掌握器自动按照I2C协议实现传输,但是如果涌现问题,就只能通过示波器看波形找问题。

二. 利用GPIO通过软件仿照实现

软件仿照I2C比较主要,由于软件仿照的全体流程比较清晰,哪里出来bug,很快能找到问题,仿照一遍会对I2C通信协议更加熟习。

如果芯片上没有IIC掌握器,或者掌握接口不足用了,通过利用任意IO口去仿照实现IIC通信协议,手动写代码去掌握IO口的电平变革,仿照IIC协议的时序,实现IIC的旗子暗记和数据传输,下面会讲到根据通信协议如何用软件去仿照。

I2C通信协议

IIC总线协议无非便是几样东西:起始旗子暗记、停滞旗子暗记、应答旗子暗记、以及数据有效性。

一. 空闲状态

时钟线(SCL)和数据线(SDA)接上拉电阻,默认高电平,表示总线是空闲状态。

二. 从设备地址

从设备地址用来区分总线上不同的从设备,一样平常发送从设备地址的时候会在最低位加上读/写旗子暗记,比如设备地址为0x50,0表示读,1表示写,则读数据就会发送0x50,写数据就会发送0x51。

三. 起始(START)旗子暗记

I2C通信的起始旗子暗记由主设备发起,SCL保持高电平,SDA由高电平跳变到低电平。

// 起始旗子暗记void IIC_start(void){ // 1.首先把数据线设置为输出模式 // 总线空闲, SCL和SDA输出高 SCL = 1; SDA = 1; delay_us(5); // SDA由高变低 SDA = 0; delay_us(5); // 拉低SCL开始传输数据 SCL = 0;}

四. 停滞(STOP)旗子暗记

I2C通信的停滞旗子暗记由主设备终止,SCL保持高电平,SDA由低电平跳变到高电平。

// 停滞旗子暗记void IIC_stop(void){ // 1.首先把数据线设置为输出模式 // 拉高时钟线 SDA = 0; delay_us(5); SCL = 1; delay_us(5); // SDA由低变高 SDA = 1;}

五. 数据有效性

I2C总线进行数据传送时,在SCL的每个时钟脉冲期间传输一个数据位,时钟旗子暗记SCL为高电日常平凡代,数据线SDA上的数据必须保持稳定,只有在时钟线SCL上的旗子暗记为低电日常平凡代,数据线SDA上的高电平或低电平状态才许可变革,由于当SCL是高电平时,数据线SDA的变革被规定为掌握命令(START或STOP,也便是前面的起始旗子暗记和停滞旗子暗记)。

六. 应答旗子暗记(ACK:有效应答,NACK:无效应答)

吸收端收到有效数据后向对方相应的旗子暗记,发送端每发送一个字节(8位)数据,在第9个时钟周期开释数据线去吸收对方的应答。

当SDA是低电平为有效应答(ACK),表示对方吸收成功;

当SDA是高电平为无效应答(NACK),表示对方没有吸收成功。

发送数据须要等待吸收方的应答:

// 等待ACK 1-无效 0-有效u8 IIC_wait_ack(void){ u8 ack = 0; // 数据线设置为输入 // 拉高时钟线 SCL = 1; delay_us(5); // 获取数据线的电平 if(SDA) { // 无效应答 ack = 1; IIC_stop(); } else { // 有效应答 ack = 0; // 拉低SCL开始传输数据 SCL = 0; delay_us(5); } return ack;}

吸收数据须要向发送方发送应答:

void IIC_ack(u8 ack){ // 数据线设置为输出 SCL = 0; delay_us(5); if(ack) SDA = 1; // 无效应答 else SDA = 0; // 有效应答 delay_us(5); SCL = 1; // 保持数据稳定 delay_us(5); // 拉低SCL开始传输数据 SCL = 0;}

注:公众年夜众号后台发送 “IIC” 即可获取基于STM32上实现软件仿照IIC的完全代码。

原创不易,以为文章不错,收藏的同时,麻烦点个赞~~~~~

关注微信"大众年夜众号『混说Linux』

你也可以连续阅读 点击 以下文章,下面是我推举给大家的几篇文章:

《竟然把通信协议讲的如此普通?》《看完还不会c措辞指针,锤自己》《Linux为什么利用内核模块?》《Linux为什么区分内核空间和用户空间?》
标签:

相关文章