示波器解析IIC通讯

通过示波器解析IIC通讯

可以通过示波器捕获IIC SDA数据线,SCL时钟线波形,结合协议规则,加深我对IIC协议的学习和理解

文章目录

  • 通过示波器解析IIC通讯
  • 一、IIC数据协议简要介绍
  • 二、IIC硬件准备
  • 三、IIC代码实现
  • 四、示波器捕获IIC波形
  • 五、总结

一、IIC数据协议简要介绍

IIC主要用于SOC与其外围设备的通信, 属于串行通信,并且其通信速率较低,可在软件中设置外围设备的最高速率,不过一般就几百KHZ,一般用到IIC的设备有TP、Sensor、EEPROM等。
SCL:时钟信号,主设备向从设备提供时钟的通道;
SDA:数据信号,所有的数据以位为单位在SDA上传输。
1、通信的两方分主设备和从设备,整个通信由主设备发起并主导,从设备只是根据主设备的通信数据进行响应;
2、多个从设备可以挂在一个主设备上,主设备通过调动总线来决定某一时间与哪一个从设备通信,并且当与某一个从设备出于通信状态,其他从设备即保持沉默状态,每个从设备都有自己的专有属性的地址,主设备与从设备就是通过这个地址进行“碰头”。所谓“碰头”即:主设备在每个通信周期会先发8位的从设备地址(但其实8位中只有7位是从设备地址,还有1位表示主设备“读”或“写”)到总线(主设备是以广播的形式发送的,只要是总线上的所有从设备其实都能收到这个信息)。然后总线上的每个从设备都能收到这个地址,并且收到地址后和自己的设备地址比较看是否一致。如果一致则说明主设备本次通信就是给我说话,如果不一致说明这次通信与我无关,不是需要的通信对象;发送方发送一段数据后,接收方需要回应一个ACK。这个响应本身只有1个bit位,不能携带有效信息,只能表示2个意思(要么表示收到数据,即有效响应;要么表示未收到数据,即无效响应);在某一个通信时刻,主设备和从设备只能有一个在发(占用总线,也就是向总线写),另一个在收(从总线读)。不能在某个时间主设备和从设备都试图向总线写。
3.为什么开漏输出
1、防止短路,主从GPIO链接在一起,如果设置为推挽输出一个输出1一个输出0,那么直接就短路了。
2、线与
数电的知识,两个输出端直接互连就可以实现"AND"的逻辑功能。如果输入都是高电平,那么输出的就是高电平,否则输出就是低电平。
3、线与的作用:多主设备抢占总线的仲裁。
IIC支持多主机多从机通讯,当多个主机需要开始启动总线通讯的时候,线与就起到作用了
主机 SCL 高电平,SDA
IIC总线工作原理
(1)主机首先发出开始信号,接着发送1字节的数据,其中高7位的地址码和最低1位的方向位组成,方向位表示主机和从机间的传输方向 0 表示主机向从机写数据,1表示主机向从机读数据。
(2)系统中的所有从机将自己的地址和主机发送到总线的地址进行比较,如果从机地址与总线地址相同,那从机与主机进行数据交互。
(3)根据方向位,主机从从机接收数据或向从机发送数据。
(4)当数据发送完成后,主机发送一个停止信号,释放IIC总线。
(5)所有的从机等待下一次的开始信号。

二、IIC硬件准备

硬件选用arduino UNO 两块开发板,一个做主机,一个做从机,实现主从通讯。因为IIC SDA SCK是开漏输出没有高电平输出能力,在SCK和SDA加上3.3K上拉电阻。
示波器解析IIC通讯_第1张图片

三、IIC代码实现

主机代码是IIC发送变量x,x++。
从机代码是IIC接收数据,并printf。

#include 
#include 

#define enable 1  //1表示选择编译主机代码  0表示选择编译从机代码

#if(enable)

void setup() {
  Wire.begin(); 		// Wire初始化,作为主机加入到IIC总线
}

byte x = 0;					// 定义一个byte变量以便串口调试
void loop() {
  Wire.beginTransmission(8); 		// 向地址为8的从机传送数据
  Wire.write(x);              	    // 发送变量X数据
  Wire.endTransmission();    	 	// 结束传送
  x++;
  delay(500);
}

#else

// 直接在Arduino IDE选择“文件”→“示例”→Wire→slave_receiver,可以打开该文件

// 当主机发送的数据被收到时,将触发 receiveEvent() 事件
void receiveEvent(int howMany) {
// 循环读取收到的数据,最后一个数据单独读取
  while (1 < Wire.available()) { 
    char c = Wire.read(); 			// 以字符形式接收数据
    Serial.print(c);         		// 串口输出该字符串
  }
  int x = Wire.read();    			// 以整型形式接收数据
  Serial.print(x);         		// 串口输出该整型变量
}


void setup() {
  Wire.begin(8);                // Wire初始化, 并以从设备地址8的身份加入IIc总线
  Wire.onReceive(receiveEvent); // 注册一个IIC事件,用于响应主机的数据发送
  Serial.begin(9600);           // 初始化串口并设置波特率为9600
}

void loop() {
  delay(100);
}


#endif

四、示波器捕获IIC波形

使用示波器选择IIC协议解析,清晰呈现波形和解析数据可以得到关键数据
地址:0x08
R/W: 主机写
Data: 发送数据0xAB
示波器解析IIC通讯_第2张图片
下面通过辨别比较SDA和SCL 波形状态读出关键数据内容
示波器解析IIC通讯_第3张图片

五、总结

通过示波器观察IIC数据协议,加深了对IIC的理解。

你可能感兴趣的:(arduino,单片机,stm32,嵌入式硬件)