码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • IIC通信


    通信协议简述

    • 三条线:串行数据线(SDA)、串行时钟线(SCL),地线;

           

    • 半双工 一问一答 ,主从模式,多设备模式
    • 总线协议:支持多个设备进行通信(多主多从)

    • 异步模式(串口):通信双方约定好波特率,然后各自按照自己时钟进行通信。

            好处:便捷;

            缺点:双方必须时钟精确,否则对不齐了。

    • 同步通信(IIC):由主机的时钟总线确定通信速率
    • 选择IIC原因:考虑小型传感器没有晶振提供精确的时钟基准

    通信协议过程

    在IIC总线上,每个从机都有其唯一的默认设备地址【这个设备地址由谁规定的呢?】。发送数据时采用广播形式,数据最开始带着从机地址,其他设备会选择性失聪。

    1、通信开始前:

    两总线电平处于拉高状态:

    主机在时钟线上产生恒定的时钟脉冲

    2、主机发起通信:

    在时钟线某个高电平时,数据线下拉;随机主机会在时钟线上产生一个恒定的时钟脉冲信号。

    3、数据发送过程:

    接下来每一个时钟周期内,SDL上发送电平基本小规则:

    主机在低电平时钟时,设置数据;从机在高时钟时,读取数据。

    字节数据发送主要规则:

           每当发送器传输完一个字节(8 bit)的数据之后,发送端会等待一定的时间,等接收方的应答信号。接收端通过拉低SDA数据线,给发送端发送一个应答信号,以提醒发送端我这边已经接受完成,数据可以继续传输,接下来,发送端就可以继续发送数据了。如此反复,直到发送完所有数据。

    即每一帧的数据传送与应答数据 共有9bit

    总线寻址:

    值得注意的是,IIC通信中,主机发送的第一个字节往往是某个从机在总线上的地址:

    数据读写方向:

    参考来源:

    IIC详解,包括原理、过程,最后一步步教你实现IIC_iic协议-CSDN博客

    4、通信终止信号:

    然后主机会在时钟线处于高电平时,将数据线拉高,通信终止信号。整段通信完成。

    起始信号和终止信号都是由主机发送的。在起始信号产生之后,总线就处于被占用的状态,在终止信号产生之后,总线就处于空闲状态。

    注意:每次数据传送总是由主机产生的终止信号来结束。但是,若主机希望继续占用总线进行新的数据传送,则可以不产生终止信号,马上再次发出起始信号对另一从机进行寻址。

    模拟IIC协议代码实现

    代码实现-学习视频推荐

    iic读取函数书写_哔哩哔哩_bilibiliiic读取函数书写, 视频播放量 2012、弹幕量 4、点赞数 57、投硬币枚数 17、收藏人数 62、转发人数 0, 视频作者 小远课堂, 作者简介 作者已关闭了评论提醒,相关视频:I2C时序图解讲解[上],IIC的代码不会写?,秒懂I2C时序图,IIC时序图讲解【中】,I2C入门第一节-I2C的基本工作原理,I2C写字节的基本流程,lcd1602看时序图写代码,I2C时序图讲解【下】,学完C语言,做不出小程序,做不出图形化界面,只有黑乎乎的窗口,自学编程的几点建议,7分钟看懂时序图,不懂你骂我,花了四个多小时画了人生第一块PCBicon-default.png?t=N7T8https://www.bilibili.com/video/BV1Vj411Z7qN/?spm_id_from=333.788&vd_source=f443c8140671d1c361aa817ad1193312代码更详细实现-博客推荐

    【通信协议】IIC通信协议详解-CSDN博客IIC的基本介绍IIC总线的发展: 芯片间总线(Inter Interface Circuit,IIC),是应用广泛的芯片间串行扩展总线。目前世界上采用的IIC总线一共有两个规范,分别由荷兰飞利浦公司和日本索尼公司提出的,现在基本采用荷兰飞利浦的IIC总线的技术规范。IIC总线的优点:1、IIC总线优点中最主要的优点是其简单性(IIC只有两条信号线)和有效性(根据SCL线上的时钟线来判断)。带有IIC总线的接口的单片机都可直接与具有IIC总线接口的各种扩展器件..._iic通信协议https://blog.csdn.net/qq_53918631/article/details/124810934?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-124810934-blog-107078170.235%5Ev38%5Epc_relevant_anti_vip_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-124810934-blog-107078170.235%5Ev38%5Epc_relevant_anti_vip_base&utm_relevant_index=2

    1. 头文件
    2. myiic.h
    3. #ifndef __MYIIC_H
    4. #define __MYIIC_H
    5. #include "sys.h"
    6. //IO方向设置
    7. //CRH,CRL 端口输入输出模式寄存器。CRH为8-15引脚,CRL为0-7引脚
    8. #define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}//PC11引脚为上拉/下拉输入
    9. #define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}//PC11为推挽输出
    10. //IO操作函数
    11. #define IIC_SCL PCout(12) //SCL
    12. #define IIC_SDA PCout(11) //SDA
    13. #define READ_SDA PCin(11) //输入SDA
    14. //IIC所有操作函数
    15. void IIC_Init(void); //初始化IIC的IO口
    16. void IIC_Start(void); //发送IIC开始信号
    17. void IIC_Stop(void); //发送IIC停止信号
    18. void IIC_Send_Byte(u8 txd); //IIC发送一个字节
    19. u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
    20. u8 IIC_Wait_Ack(void); //IIC等待ACK信号
    21. void IIC_Ack(void); //IIC发送ACK信号
    22. void IIC_NAck(void); //IIC不发送ACK信号
    23. //一下两个函数实际并未被定义
    24. void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
    25. u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
    26. #endif
    27. .c文件
    28. #include "myiic.h"
    29. #include "delay.h"
    30. //初始化IIC
    31. //硬件I2C必须开漏输出
    32. //模拟I2C则为推挽输出(方便输出高低电平?)
    33. void IIC_Init(void)
    34. {
    35. GPIO_InitTypeDef GPIO_InitStructure;
    36. //RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟
    37. RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );
    38. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
    39. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出
    40. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    41. GPIO_Init(GPIOC, &GPIO_InitStructure);
    42. IIC_SCL=1;//PCout(12)
    43. IIC_SDA=1;//PCout(11)
    44. }
    45. //产生IIC起始信号
    46. //SCL为高时,SDA拉低,准备开始传数据。(记得再拉低SCL,这个是为什么?)
    47. //SCL为高时,SDA拉高,结束传输数据。
    48. //传输数据时,SCL为高时数据有效
    49. void IIC_Start(void)
    50. {
    51. SDA_OUT(); //sda线输出
    52. IIC_SDA=1; //SDA = 1,SCL = 1 空闲状态
    53. IIC_SCL=1;
    54. delay_us(4);
    55. IIC_SDA=0;//START:when CLK is high,DATA change form high to low
    56. delay_us(4);
    57. IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
    58. }
    59. //产生IIC停止信号
    60. void IIC_Stop(void)
    61. {
    62. SDA_OUT();//sda线输出
    63. IIC_SCL=0;
    64. IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
    65. delay_us(4);
    66. IIC_SCL=1;
    67. IIC_SDA=1;//发送I2C总线结束信号
    68. delay_us(4);
    69. }
    70. //等待应答信号到来
    71. //返回值:1,接收应答失败
    72. // 0,接收应答成功
    73. u8 IIC_Wait_Ack(void)
    74. {
    75. u8 ucErrTime=0;
    76. SDA_IN(); //SDA设置为输入
    77. IIC_SDA=1;delay_us(1);
    78. IIC_SCL=1;delay_us(1); //设置数据有效
    79. while(READ_SDA)//READ_SDA为0时表示接收到应答
    80. {
    81. ucErrTime++;
    82. if(ucErrTime>250)
    83. {
    84. IIC_Stop();
    85. return 1;
    86. }
    87. }
    88. IIC_SCL=0;//时钟输出0
    89. return 0;
    90. }
    91. //产生ACK应答
    92. void IIC_Ack(void)
    93. {
    94. IIC_SCL=0;
    95. SDA_OUT();
    96. IIC_SDA=0;
    97. delay_us(2);
    98. IIC_SCL=1;
    99. delay_us(2);
    100. IIC_SCL=0;
    101. }
    102. //不产生ACK应答
    103. void IIC_NAck(void)
    104. {
    105. IIC_SCL=0;
    106. SDA_OUT();
    107. IIC_SDA=1;
    108. delay_us(2);
    109. IIC_SCL=1;
    110. delay_us(2);
    111. IIC_SCL=0;
    112. }
    113. //IIC发送一个字节
    114. //返回从机有无应答
    115. //1,有应答
    116. //0,无应答
    117. void IIC_Send_Byte(u8 txd)
    118. {
    119. u8 t;
    120. SDA_OUT();
    121. IIC_SCL=0;//拉低时钟开始数据传输
    122. for(t=0;t<8;t++)
    123. {
    124. IIC_SDA=(txd&0x80)>>7;//先发高位
    125. txd<<=1;
    126. delay_us(2); //对TEA5767这三个延时都是必须的
    127. IIC_SCL=1;
    128. delay_us(2);
    129. IIC_SCL=0;
    130. delay_us(2);
    131. }
    132. }
    133. //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
    134. u8 IIC_Read_Byte(unsigned char ack)
    135. {
    136. unsigned char i,receive=0;
    137. SDA_IN();//SDA设置为输入
    138. for(i=0;i<8;i++ )
    139. {
    140. IIC_SCL=0;
    141. delay_us(2);
    142. IIC_SCL=1;
    143. receive<<=1;
    144. if(READ_SDA)receive++;
    145. delay_us(1);
    146. }
    147. if (!ack)
    148. IIC_NAck();//发送nACK
    149. else
    150. IIC_Ack(); //发送ACK
    151. return receive;
    152. }
    153. ————————————————
    154. 版权声明:本文为CSDN博主「碑 一」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    155. 原文链接:https://blog.csdn.net/dedell/article/details/96628955

    模拟IIC应用实战:

    stm32无人机:利用上面基础模拟IIC代码把数据从mpu6050传感器数据读取出来(未完成)

    1. *stm32 HAL库 实现和使用IIC总线*
    2. #include "stm32xxxxx.h"
    3. #include "stm32xxxxx_hal.h"
    4. I2C_HandleTypeDef hi2c1;
    5. void SystemClock_Config()
    6. {
    7. // 配置系统时钟
    8. // ...
    9. }
    10. void GPIO_Configuration()
    11. {
    12. // 配置GPIO引脚
    13. // ...
    14. }
    15. void I2C_Configuration()
    16. {
    17. // 配置I2C外设
    18. hi2c1.Instance = I2C1;
    19. hi2c1.Init.Timing = 0x00303D5B; // 根据具体系统时钟和I2C时钟频率调整这个值
    20. hi2c1.Init.OwnAddress1 = 0;
    21. hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    22. hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    23. hi2c1.Init.OwnAddress2 = 0;
    24. hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    25. hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    26. // 初始化I2C外设
    27. HAL_I2C_Init(&hi2c1);
    28. }
    29. int main(void)
    30. {
    31. uint8_t sendData[] = {0x01, 0x02, 0x03};
    32. uint8_t receiveData[3];
    33. // 初始化系统时钟
    34. SystemClock_Config();
    35. // 配置GPIO引脚
    36. GPIO_Configuration();
    37. // 配置I2C外设
    38. I2C_Configuration();
    39. // 发送数据
    40. HAL_I2C_Master_Transmit(&hi2c1, DeviceAddress, sendData, sizeof(sendData), HAL_MAX_DELAY);
    41. // 延时等待数据发送完成
    42. HAL_Delay(1); // 根据实际情况调整延时时间
    43. // 接收数据
    44. HAL_I2C_Master_Receive(&hi2c1, DeviceAddress, receiveData, sizeof(receiveData), HAL_MAX_DELAY);
    45. while (1)
    46. {
    47. // 主程序逻辑
    48. }
    49. }

    参考:

    【物联网】I2C(IIC)通信协议详解与应用_iic通信_嵌入式小白—小黑的博客-CSDN博客

    【通信协议】IIC通信协议详解-CSDN博客IIC的基本介绍IIC总线的发展: 芯片间总线(Inter Interface Circuit,IIC),是应用广泛的芯片间串行扩展总线。目前世界上采用的IIC总线一共有两个规范,分别由荷兰飞利浦公司和日本索尼公司提出的,现在基本采用荷兰飞利浦的IIC总线的技术规范。IIC总线的优点:1、IIC总线优点中最主要的优点是其简单性(IIC只有两条信号线)和有效性(根据SCL线上的时钟线来判断)。带有IIC总线的接口的单片机都可直接与具有IIC总线接口的各种扩展器件..._iic通信协议https://blog.csdn.net/qq_53918631/article/details/124810934?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-124810934-blog-107078170.235%5Ev38%5Epc_relevant_anti_vip_base&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~CTRLIST~Rate-1-124810934-blog-107078170.235%5Ev38%5Epc_relevant_anti_vip_base&utm_relevant_index=2

    案例:利用IIC从单片机读取温湿度显示到电脑

    数据显示到电脑上:

    前几节用到的串口以及串口调试助手 - 从单片机发送数据到pc上,显示出来

    IIC写驱动

    项目架构

    直接看“传感器数据手册”

    重点关注:设备从机地址 0X71

    【STM32入门教程-2023】第12集 IIC通信与温湿度传感器AHT20(DHT20)_哔哩哔哩_bilibili本期视频我们一起来了解一下如何使用STM32的IIC通信, 获取你房间的温度与湿度~------------------------------------------------------------------------------学习套件获取: https://b23.tv/sblUuvI 或者直接某宝搜索"keysking stm32", 认准店铺"波特律, 视频播放量 24904、弹幕量 140、点赞数 1026、投硬币枚数 605、收藏人数 1354、转发人数 109, 视频作者 keysking, 作者简介 立志做最好最简洁最易懂的教程!!!,相关视频:【STM32入门教程-2023】第14集 如何在OLED屏幕上挥毫,STM32物联网入门30步--STM32CubeMX+HAL库 CubeIde蓝牙 WIFI ESP8266 嵌入式物联网开发教学 基于F103 30集全,STM32入门100步→100集系统化STM32入门方案=STM32F103+KEIL标准库+C语言基础+代码逐行分析+独家教学PPT+人机界面开发全过程,【STM32入门教程-2023】第13集 IIC的中断与DMA以及状态机编程,【洋桃电子】STM32入门F4:F407+CubeMX+HAL库(CubeIDE)+蓝牙 WIFI ESP8266+原创例程+独家PPT图表(更新中),【STM32入门教程-2023】应该是全B站最好的STM32教程了,5分钟看懂!串口RS232 RS485最本质的区别!,电路里为什么要摆这两个电容?,【洋桃电子】洋桃补习班(为0基础的初学者补足基础知识)STM32入门100步系列视频,10行代码,就能让你真正理解DMA!你用的可能很少,但是在单片机中非常重要!icon-default.png?t=N7T8https://www.bilibili.com/video/BV1QN411D7ak/?spm_id_from=333.788&vd_source=f443c8140671d1c361aa817ad1193312

    从面试角度看IIC的提问点:

    1、为什么选择IIC通信,和SPI UART 的区别,哪个更快?

    2、IIC最大速率

    3、IIC协议,帧格式,收发数据的时序流程

    4、介绍一下IIC

    5、调试IIC过程中遇到的问题

    6、iic寻址,主机从机如何对接的

  • 相关阅读:
    从零搭建个人博客项目并通过github部署上线
    实验13 简单拓扑BGP配置
    【ACWing】3531. 哈夫曼树
    Day10--配置uni-app的开发环境
    你把 css:hover 玩明白
    一线大厂Redis高并发缓存架构实战与性能优化
    UI/UX design
    2023高频前端面试题-TCP
    ubuntu_24.04 Noble LTS安装docker desktop启动无窗口及引擎启动失败的解决方法
    新一代网状网协议T-Mesh无线通信技术优势介绍
  • 原文地址:https://blog.csdn.net/weixin_46697509/article/details/133357847
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号