IIC通信

内部集成电路(IIC或I2C)是用于微控制器和新一代专用集成电路之间的串行数据交换系统。当它们之间的距离很短(接收器和发射器通常在同一个印刷电路板上)时使用。通过两根导线建立连接。一个用于数据传输,另一个用作同步(时钟信号)。

如下图所示,一个设备始终是主设备,主设备在通信开始之前执行一个从芯片的寻址。这样,利用一个主设备控制多个仆从设备,而一个微控制器可以最多与112个不同的设备进行通信。通过I2C总线通信的设备之间的距离限制在几米之内。

Stduino的IIC通信需要使用wire库(Wire.h),该库包含以下方法:

  • begin()
  • requestFrom()
  • beginTransmission()
  • endTransmission()
  • write()
  • available()
  • read()
  • onReceive()
  • onRequest()

使用方法,参见Wire库函数。

IIC引脚引脚连接

I2C总线由两个信号组成

  • SCL
  • SDA

SCL 是时钟信号,SDA是数据信号。内部总线主机总是产生时钟信号。一些从设备可能时钟时钟以连续主设备发送更多数据(或者在主设备尝试将数据写出之前请求更多的时间来准备数据)。这被称为“时钟脉冲”。

以下是部分Stduino开发板的引脚说明

I2C引脚
Stduino UNO

接下来将讲解主设备和从设备两者是如何实现IIC通信的。

主设备发射/仆从设备接收

主设备发射

以下函数用于初始化Wire库,将I2C总线作为主器件或从器件加入。这通常只被调用一次。

  • Wire.begin(地址) -在我们的示例中,地址是7位从地址,因为未指定主机,因此作为主机加入总线。
  • Wire.beginTransmission(地址) -开始向给定地址的I2C从设备发送数据。
  • Wire.write(值) -用于从主设备传输到从设备的串行字节(在beginTransmission()和endTransmission()之间的调用)。
  • Wire.endTransmission() -结束由beginTransmission()开始的对从设备的传输,并传输由wire.write()排队的字节。

示例

#include <Arduino.h>
#include <Wire.h> 

void setup() { 
   Wire.begin(); // join i2c bus as master
} 

short age = 0; 

void loop() {   
   Wire.beginTransmission(2); 
   // transmit to device #2
   Wire.write("age is = ");
   Wire.write(age); // sends one byte
   Wire.endTransmission(); // stop transmitting
   delay(1000); 
}

仆从设备接收

使用以下函数:

  • Wire.begin(地址) -地址是7位从地址。
  • Wire.onReceive(收到的数据处理程序) -当从设备从主设备接收数据时调用的函数。
  • Wire.available() -返回Wire.read()可用于检索的字节数,应在Wire.onReceive()处理程序中调用。

示例

#include <Arduino.h>
#include <Wire.h> //include wire library

void setup() {  //this will run only once
   Wire.begin(2); // join i2c bus with address #2
   Wire.onReceive(receiveEvent); // call receiveEvent when the master send any thing 
   Serial.begin(9600); // start serial for output to print what we receive 
}

void loop() {   
   delay(250); 
}

void receiveEvent(int howMany) { 
   while (Wire.available()>1) // loop through all but the last {
      char c = Wire.read(); // receive byte as a character
      Serial.print(c); // print the character
   }
}

主设备接收/仆从设备发射

主接收器

主机被编程为请求,然后读取从唯一寻址的从机Arduino发送的数据字节。

使用以下函数:

Wire.requestFrom(地址,字节数) -主设备用于请求从设备的字节。然后可以使用函数wire.available()和wire.read()检索字节。

示例

#include <Arduino.h>
#include <Wire.h> //include wire library void setup() { 
   Wire.begin(); // join i2c bus (address optional for master) 
   Serial.begin(9600); // start serial for output
} 

void loop() { 
   Wire.requestFrom(2, 1); // request 1 bytes from slave device #2
   while (Wire.available()) // slave may send less than requested {
      char c = Wire.read(); // receive a byte as character
      Serial.print(c); // print the character
   } 
   delay(500); 
}

从发射器

使用以下函数:

Wire.onRequest(处理程序) -当主设备从此设备请求数据时调用该函数。

示例

#include <Arduino.h>
#include <Wire.h> 

void setup() { 
   Wire.begin(2); // join i2c bus with address #2
   Wire.onRequest(requestEvent); // register event
} 

Byte x = 0;

void loop() { 
   delay(100); 
} 

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()

void requestEvent() { 
   Wire.write(x); // respond with message of 1 bytes as expected by master
   x++; 
}
文档更新时间: 2021-02-14 14:27   作者:admin