返回列表 发新帖我要提问本帖赏金: 50.00元(功能说明)

[资料干货] I2C总线原理与IO模拟时序实现

[复制链接]
1295|5
 楼主| forgot 发表于 2023-2-15 11:36 | 显示全部楼层 |阅读模式
本帖最后由 forgot 于 2023-2-15 11:38 编辑

  前面说到了三线制的SPI和四线制的SPI,今天说一下I2C总线,I2C总线由SDA(串行数据线)和SCL(串行时钟线)两条线构成,是典型的半双工,而不是全双工,同一时间只可以单向通信。而I2C的总从通讯主要由判断I2C总线上的每个设备的唯一的地址,来确保不同设备之间访问的准确性,也就是说挂在总线上的每个I2C设备,都由一个属于自己的固定地址,并且I2C总线规范规定,标准模式I2C,从机地址为7位长,其次是1个读/写位。该地址可由软件设定,也可以通过一些外部的配置进行改变,如一些液晶模块,可以通过电阻来选择不同的地址,比较灵活。但是在一主多从的设计中,只能允许有一个主机。

  由于总线结构的限制,I2C的通讯速率没有SPI高,标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下最高可达3.4 Mbit/s,具体要根据器件本身的通讯性能还有设计线路的可靠性进行速率匹配。

  I2C的通讯过程由起始、应答、结束三部分构成。
I2C开始条件:在SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据;
I2C应答信号:接收数据的乙方在接收到数据之后,向发送数据的一方发出特定的低电平脉冲,表示已经收到数据。主机向从机发出一个信号之后,等待从机发出应答信号,在主机接收到应答信号之后,根据实际情况进行数据传输。
I2C结束条件:在SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据;

  实际开发过程中,往往可以不检测应答信号,也是可以进行通讯的。现在的很多单片机都内置了I2C外设,在使用上只需要配置好对应的管脚、模式、速率以及地址等参数就可以进行通讯,但是由于硬件I2C设计的固定,对于应答等方面有了固定的要求,并不便于调整,还有很多单片机本身就没有I2C,所以现在很多设计都喜欢采用IO口模拟时序的方式来实现。实现过程如下:

首先先选择好对应SDA和SCL的管脚进行GPIO口的配置,然后通过GPIO的操作函数可实现管脚的置高于置低控制。
再根据前面提到的起始、应答、结束编写对应的功能函数:
开始信号,停止信号,等待应答信号、发送应答信号等
  1. void IIC_Start()
  2. {
  3.     OLED_SCLK_Set();
  4.     OLED_SDIN_Set();
  5.     MY_Delay(1);
  6.     OLED_SDIN_Clr();
  7.     MY_Delay(1);
  8. }
  1. void IIC_Stop()
  2. {
  3.     OLED_SCLK_Set();
  4.     MY_Delay(1);
  5.     OLED_SDIN_Clr();
  6.     MY_Delay(1);
  7.     OLED_SDIN_Set();
  8.     MY_Delay(1);
  9. }

最后根据实际需要编写读写函数:
发送一个字节,读取一个字节等,以SSD1306为例:

  1. void Write_IIC_Command(unsigned char IIC_Command)
  2. {
  3.     IIC_Start();
  4.     Write_IIC_Byte(0x78);//Slave address,SA0=0
  5.     IIC_Wait_Ack();
  6.     Write_IIC_Byte(0x00);//write command
  7.     IIC_Wait_Ack();
  8.     Write_IIC_Byte(IIC_Command);
  9.     IIC_Wait_Ack();
  10.     IIC_Stop();
  11. }

  12. void Write_IIC_Data(unsigned char IIC_Data)
  13. {
  14.     IIC_Start();
  15.     Write_IIC_Byte(0x78);//D/C#=0; R/W#=0
  16.     IIC_Wait_Ack();
  17.     Write_IIC_Byte(0x40);//write data
  18.     IIC_Wait_Ack();
  19.     Write_IIC_Byte(IIC_Data);
  20.     IIC_Wait_Ack();
  21.     IIC_Stop();
  22. }

  最后总结一下,I2C由于是两条总线构成,给开发节省了管脚和走线,简化了PCB的布局布线,降低了系统开发成本,对于速率要求不是特别高的地方,已经成为很多设计首选总线类型之一。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×

打赏榜单

21ic小管家 打赏了 50.00 元 2023-03-13
理由:签约作者奖励

王栋春 发表于 2023-2-15 22:38 | 显示全部楼层
资料非常不错,受教了。多谢楼主分享。                     
nongshengjiang 发表于 2023-2-16 09:22 来自手机 | 显示全部楼层
麻的这几天也io 口模拟,有的器件读得好好的,有器件的死活读不正常,晕,还是专口iic好点。
 楼主| forgot 发表于 2023-2-16 10:17 | 显示全部楼层
nongshengjiang 发表于 2023-2-16 09:22
麻的这几天也io 口模拟,有的器件读得好好的,有器件的死活读不正常,晕,还是专口iic好点。 ...

,你如果用st的I2C可能会更坑啊
coody 发表于 2023-2-16 14:33 | 显示全部楼层
forgot 发表于 2023-2-16 10:17
,你如果用st的I2C可能会更坑啊

STM32F103的I2C在2007年第一次用踩坑,后来一直没敢用,一直是用的IO模拟I2C。
还有RTC也不用,还是外挂RTC芯片。
 楼主| forgot 发表于 2023-2-16 14:55 | 显示全部楼层
coody 发表于 2023-2-16 14:33
STM32F103的I2C在2007年第一次用踩坑,后来一直没敢用,一直是用的IO模拟I2C。
还有RTC也不用,还是外挂R ...

RTC还好,就是哪个晶振选型很重要,不然是有点问题,那个I2C我真是没用成功过一次
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2115

主题

14686

帖子

59

粉丝
快速回复 在线客服 返回列表 返回顶部