[嵌入式]I2C协议指东
最近闲来无聊,入了一块MPU6050,手头本来就有一块原子的STM32 MINI开发板,凑活着学习了一下IIC,特此总结。
IIC,是集成电路总线【Inter-Intergrated Circuit】的缩写,属于飞利浦公司的原创。
主要用两根线:数据线SDA和时钟线SCL。
关于时序方面本文就不截图了,网上一大堆。
下面就具体说IIC的传输过程中,比较重要的几个方法,下文的代码均是在STM32中实现,是一种模拟IIC。
SCL为输出模式的PC(12),SDA则根据情况切换输入和输出模式,为PC(11)。
1、开始信号
开始信号定义为:SCL高电平时,SDA的下降沿。
//开始信号 void IIC_Start(void) {SDA_OUT(); //SDA输出模式IIC_SDA=1;IIC_SCL=1;delay_us(IIC_DELAY);IIC_SDA=0;//SCL高电平时SDA的下降沿 delay_us(IIC_DELAY); }
2、结束信号
结束信号定义为:SCL高电平时,SDA的上升沿。
//结束信号 void IIC_Stop(void) {SDA_OUT();IIC_SDA=0; IIC_SCL=1;delay_us(IIC_DELAY);IIC_SDA=1;//SCL高电平时SDA的上升沿 delay_us(IIC_DELAY); }
其中的SDA_OUT()是STM32的IO口模式设置,其他MCU可忽略或更改。IIC_DELAY是定义的宏,可以控制延迟时间从而控制IIC速率。
3、IIC写一个字节
这里的写一个字节是说,控制了IIC总线的主机往总线上写数据。
void IIC_Send_Byte(u8 data) {u8 i;SDA_OUT();//输出模式 for(i=0;i<8;i++){IIC_SCL=0;//拉低时钟 占据总线 delay_us(IIC_DELAY);IIC_SDA=(data&0x80)>>7;//每次1位,先高位data<<=1;delay_us(IIC_DELAY);IIC_SCL=1;delay_us(IIC_DELAY); }IIC_SCL=0; }
这里默认是先MSB后LSB,IIC_SDA根据数据位依次置1或0,传输数据时,SCL必须拉低,以此告诉其他器件“传输进行中”,在传输结束后,还需要再次拉高SCL总线。在送完一个字节后,拉低SCL,等待应答。
4、IIC读一个字节
//IIC读一个BYTE u8 IIC_Read_Byte(void) {u8 i,receive=0;SDA_IN();//输入模式READ_SDA=1;for(i=0;i<8;i++){receive<<=1;//先接收的是高位IIC_SCL=0;delay_us(IIC_DELAY);IIC_SCL=1;delay_us(IIC_DELAY);receive|=READ_SDA; }IIC_SCL=0;return receive; }
这里同样的默认是先高位后低位,使用receive|=READ_SDA;来组成数据,接收数据位时,需要先拉低SCL再拉高SCL,然后再读取SDA的数据。这里的READ_SDA和IIC_SDA都是PC(11),只不过是不同的模式。
5、应答
在IIC中,应答不是必须的,所以对于应答的检测其实也不是必须的。
下面是应答和不应答的代码。
//产生ACK应答 void IIC_Ack(void) {SDA_OUT();IIC_SCL=0;delay_us(IIC_DELAY);IIC_SDA=0;delay_us(IIC_DELAY);IIC_SCL=1;delay_us(IIC_DELAY);IIC_SCL=0;//SDA为低时 拉低时钟线 delay_us(IIC_DELAY); } //不产生ACK应答 void IIC_NAck(void) {IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(IIC_DELAY);IIC_SCL=1;delay_us(IIC_DELAY);IIC_SCL=0;// SDA为高时 SCL的脉冲 delay_us(IIC_DELAY); }
6、应答检测
经过我的检验,当STM32写MPU6050时,是不需要进行应答检测的;但是当STM32读MPU6050时,如果不进行应答检测,就会出现数据出错/检测不到MPU6050等奇怪的错误,所以在应用IIC总线协议时,一律增加应答检测是比较好的一种规范做法。
应答检测返回一个值,但是大多数情况中不需要用到这个返回值。
//应答信号确认 //1有ACK //0无ACK u8 IIC_Wait_Ack(void) {u8 ucErrTime=0;SDA_IN();// SDA输入模式IIC_SCL=0;delay_us(IIC_DELAY);IIC_SDA=1;delay_us(IIC_DELAY);IIC_SCL=1;delay_us(IIC_DELAY);while(READ_SDA){ucErrTime++;if(ucErrTime>250){IIC_Stop();return 0;}}IIC_SCL=0;//关闭时钟return 1; }
如果SDA一直是高电平没有被从设备【此处为MPU6050】拉低,则说明MPU没有应答,此时停止传输,并返回0.
如果接收到应答了,则把时钟线拉低,等待下一次开始信号。
7、MPU6050相关。
关于IIC的所有函数已经讲完了,下面贴一下MPU6050相关的操作。
//写MPU60X0 u8 IIC_Write_One_Byte(u8 regaddr, u8 data) {IIC_Start(); //起始信号IIC_Send_Byte(SlaveAddress); //发送设备地址+写信号if(IIC_Wait_Ack()==0) {IIC_Stop();return 0;}IIC_Send_Byte(regaddr); //内部寄存器地址//IIC_Wait_Ack();IIC_Send_Byte(data); //内部寄存器数据//IIC_Wait_Ack();IIC_Stop(); //发送停止信号return 1; } //读MPU60X0 u8 IIC_Read_One_Byte(u8 regaddr) {u8 REG_data=0;IIC_Start(); //起始信号IIC_Send_Byte(SlaveAddress); //发送设备地址+写信号if(IIC_Wait_Ack()==0) {IIC_Stop();return 0;}IIC_Send_Byte(regaddr); //发送存储单元地址,从0开始 IIC_Wait_Ack();IIC_Start(); //起始信号 IIC_Send_Byte(SlaveAddress+1); //发送设备地址+读信号 IIC_Wait_Ack();REG_data=IIC_Read_Byte(); //读出寄存器数据,并且不应答IIC_NAck(); //不回应IIC_Stop(); //停止信号return REG_data; }
可以看到写一个字节的应答检测被我注释掉了,实验证明依旧可以正确写入MPU。
以上就是IIC的所有内容。
总结:IIC主要使用SDA,SCL两条线进行传输,其中SCL是独立的,SDA是接入总线的。当SCL为高时,说明有“事件”:比如开始信号、终止信号或者传输过程;当SCL为低时,说明总线闲,只要某一个设备拉高总线,并使得SDA总线产生一个下降沿,则主设备就可以得知是哪个设备的请求。这种通过独立SCL电平+SDA跳变的组合信号进行多设备整合的总线方案简单、有效,容错高,软件上易于实现,硬件上则更加方便。
转载于:https://www.cnblogs.com/lancelod/p/3849375.html
[嵌入式]I2C协议指东相关推荐
- 阿里巴巴指东打西,PC之后卖盒饭?
这两天,看到了数篇关于阿里巴巴的报道,核心内容都是阿里巴巴联手英特尔,发起主题为"助力中国"的电子商务推动计划,并将推出面向中小企业电子商务专用电脑的消息.从报道看,阿里巴巴将同英 ...
- 【数字IC】深入浅出理解I2C协议
深入浅出理解I2C协议 一.什么是I2C协议 二.I2C,SPI,UART协议的区别 三.I2C的信号线 四.I2C的连接方式 4.1 单主设备,单从设备 4.2 单主设备,多从设备 4.3 多主设备 ...
- I2C协议——物理层和协议层
I2C协议简介 I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART.CAN等通讯协议的外部收发设 ...
- 基于I2C协议的EEPROM驱动控制(笔记整理)
一.目标 要求:设计一个使用I2C通讯协议的EEPROM读写控制器.使用写按键向EEPROM中写入1~10共10字节数据:使用读按键读出之前写入的数据并显示在数码管上. 分析:①首先按键控制读写操作按 ...
- 《STM32从零开始学习历程》——I2C协议层
<STM32从零开始学习历程>@EnzoReventon I2C理论部分--协议层 相关资料: I2C物理层介绍 I2C固件库介绍 STM32的I2C特性及架构介绍 参考资料: [野火Em ...
- 基于I2C协议利用STM32进行温湿度传感器的数据采集
目录 一.I2C总线通信协议的介绍 1.I2C简介 2.I2C总线时序图 3.五种速率 4.四种信号 5.I2C的优缺点 6.软件IIC和硬件IIC 二.创建工程 1.实验目的 2.工具的选择 3.相 ...
- STM32F103基于I2C协议的AHT20温湿度传感器的数据采集
目录 一.I2C 1.I2C 协议简介 2.I2C 物理层 3.协议层 通讯的起始和停止信号 数据有效性 响应 4. 软件I2C"和"硬件I2C 二.实现AHT20采集程序 1.A ...
- STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集
文章目录 一.I2C总线通讯协议 1.I2C总线简介 2.I2C 协议的物理层和协议层 2.1物理层 2.2协议层 3.I2C的两种方式--硬件I2C和软件I2C 3.1硬件I2C 3.2软件I2C ...
- 用STM32F103达成基于I2C协议的AHT20温湿度传感器和OLED屏显示汉字
目录 一 I2C协议简介 硬件I2C与软件I2C 二 代码和ATH20芯片实现温湿度的串口显示 三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度 1 先用文字字模生成器 ...
- I2C协议靠这16张图彻底搞懂(超详细)
文章目录 背景 硬件层 数据传输协议 实际上如何工作? 单个主设备连接多个从机 多个主设备连接多个从机 如何编程? 总结 背景 I²C(Inter-Integrated Circuit),中文应该叫集 ...
最新文章
- IOS开发中发送Email的两种方法
- javaScript中常见的几种报错类型
- 关于数据仓库 — 总体工具介绍
- JAVA List集合转Page(分页对象)
- vb.net提取html网址,如何提取网页代码中指定内容
- 基于Matlab的跨孔电磁波\跨孔雷达的胖射线追踪(一)
- 华为机试HJ64:MP3光标位置
- 关于Clipboard剪切板获取值为NULL问题解决方法
- c#读取ini配置文件、将配置数据保存至ini文件
- Snell Advanced Media选择金雅拓保护其知识产权
- 谷歌首页被别的网站篡改
- i3wm 获取window class
- 怎么打开linux的超级终端,电脑超级终端在哪里|电脑打开超级终端的方法
- allure用例定制参数及报告效果展示
- A - ConneR and the A.R.C. Markland-N
- 最最最最能测出你数通hcia基础扎不扎实的实验!速速行动!
- 2022-2028年中国塑封机行业市场需求分析及投资前景展望报告
- SpringBoot整合邮件发送
- 平行四边形符号怎么打?
- 强推面试前必刷:Alibaba 内部 Java 高级架构师
热门文章
- 摆脱IDE进行时. . .
- mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
- 14、OpenCV Python 直线检测
- 1.3 - 字典练习题
- spring4.x的一些新特性
- AtCoder Regular Contest 061 DSnuke's Coloring
- 怎样把win7系统下的屏幕设置成护眼的非常柔和的豆沙绿色?
- 第一回合:.net与 C#基本概念
- WCF消息传输的几个基本概念(知识点整理)
- ActiveMQ笔记(二)