最近闲来无聊,入了一块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协议指东相关推荐

  1. 阿里巴巴指东打西,PC之后卖盒饭?

    这两天,看到了数篇关于阿里巴巴的报道,核心内容都是阿里巴巴联手英特尔,发起主题为"助力中国"的电子商务推动计划,并将推出面向中小企业电子商务专用电脑的消息.从报道看,阿里巴巴将同英 ...

  2. 【数字IC】深入浅出理解I2C协议

    深入浅出理解I2C协议 一.什么是I2C协议 二.I2C,SPI,UART协议的区别 三.I2C的信号线 四.I2C的连接方式 4.1 单主设备,单从设备 4.2 单主设备,多从设备 4.3 多主设备 ...

  3. I2C协议——物理层和协议层

    I2C协议简介 I2C 通讯协议(Inter-Integrated Circuit)是由Phiilps公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要USART.CAN等通讯协议的外部收发设 ...

  4. 基于I2C协议的EEPROM驱动控制(笔记整理)

    一.目标 要求:设计一个使用I2C通讯协议的EEPROM读写控制器.使用写按键向EEPROM中写入1~10共10字节数据:使用读按键读出之前写入的数据并显示在数码管上. 分析:①首先按键控制读写操作按 ...

  5. 《STM32从零开始学习历程》——I2C协议层

    <STM32从零开始学习历程>@EnzoReventon I2C理论部分--协议层 相关资料: I2C物理层介绍 I2C固件库介绍 STM32的I2C特性及架构介绍 参考资料: [野火Em ...

  6. 基于I2C协议利用STM32进行温湿度传感器的数据采集

    目录 一.I2C总线通信协议的介绍 1.I2C简介 2.I2C总线时序图 3.五种速率 4.四种信号 5.I2C的优缺点 6.软件IIC和硬件IIC 二.创建工程 1.实验目的 2.工具的选择 3.相 ...

  7. STM32F103基于I2C协议的AHT20温湿度传感器的数据采集

    目录 一.I2C 1.I2C 协议简介 2.I2C 物理层 3.协议层 通讯的起始和停止信号 数据有效性 响应 4. 软件I2C"和"硬件I2C 二.实现AHT20采集程序 1.A ...

  8. STM32F103完成基于I2C协议的AHT20温湿度传感器的数据采集

    文章目录 一.I2C总线通讯协议 1.I2C总线简介 2.I2C 协议的物理层和协议层 2.1物理层 2.2协议层 3.I2C的两种方式--硬件I2C和软件I2C 3.1硬件I2C 3.2软件I2C ...

  9. 用STM32F103达成基于I2C协议的AHT20温湿度传感器和OLED屏显示汉字

    目录 一 I2C协议简介 硬件I2C与软件I2C 二 代码和ATH20芯片实现温湿度的串口显示 三 用stm32f103芯片的SPI和IIC接口接上OLED屏显示中文姓名温湿度 1 先用文字字模生成器 ...

  10. I2C协议靠这16张图彻底搞懂(超详细)

    文章目录 背景 硬件层 数据传输协议 实际上如何工作? 单个主设备连接多个从机 多个主设备连接多个从机 如何编程? 总结 背景 I²C(Inter-Integrated Circuit),中文应该叫集 ...

最新文章

  1. IOS开发中发送Email的两种方法
  2. javaScript中常见的几种报错类型
  3. 关于数据仓库 — 总体工具介绍
  4. JAVA List集合转Page(分页对象)
  5. vb.net提取html网址,如何提取网页代码中指定内容
  6. 基于Matlab的跨孔电磁波\跨孔雷达的胖射线追踪(一)
  7. 华为机试HJ64:MP3光标位置
  8. 关于Clipboard剪切板获取值为NULL问题解决方法
  9. c#读取ini配置文件、将配置数据保存至ini文件
  10. Snell Advanced Media选择金雅拓保护其知识产权
  11. 谷歌首页被别的网站篡改
  12. i3wm 获取window class
  13. 怎么打开linux的超级终端,电脑超级终端在哪里|电脑打开超级终端的方法
  14. allure用例定制参数及报告效果展示
  15. A - ConneR and the A.R.C. Markland-N
  16. 最最最最能测出你数通hcia基础扎不扎实的实验!速速行动!
  17. 2022-2028年中国塑封机行业市场需求分析及投资前景展望报告
  18. SpringBoot整合邮件发送
  19. 平行四边形符号怎么打?
  20. 强推面试前必刷:Alibaba 内部 Java 高级架构师

热门文章

  1. 摆脱IDE进行时. . .
  2. mysql Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
  3. 14、OpenCV Python 直线检测
  4. 1.3 - 字典练习题
  5. spring4.x的一些新特性
  6. AtCoder Regular Contest 061 DSnuke's Coloring
  7. 怎样把win7系统下的屏幕设置成护眼的非常柔和的豆沙绿色?
  8. 第一回合:.net与 C#基本概念
  9. WCF消息传输的几个基本概念(知识点整理)
  10. ActiveMQ笔记(二)