Arduino 内部集成电路

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

如下图所示,一个设备始终是主设备。它在通信开始之前执行一个从芯片的寻址。这样,一个微控制器可以与112个不同的设备进行通信。波特率通常为100 Kb/sec(标准模式)或10 Kb/sec(慢波特率模式)。最近出现了波特率为3.4 Mb/s的系统。通过I2C总线通信的设备之间的距离限制在几米之内。


Arduino 内部集成电路


板的I2C引脚

I2C总线由两个信号组成 – SCL和SDA。SCL是时钟信号,SDA是数据信号。当前总线主机总是产生时钟信号。一些从设备可能迫使时钟低电平以延迟主设备发送更多数据(或者在主设备尝试将数据写出之前请求更多的时间来准备数据)。这被称为“时钟伸展”。

以下是不同Arduino板的引脚:

  • Uno, Pro Mini A4 (SDA), A5 (SCL)
  • Mega, Due 20 (SDA), 21 (SCL)
  • Leonardo, Yun 2 (SDA), 3 (SCL)

Arduino I2C

我们有两种模式 – 主代码和从代码 – 使用I2C连接两个Arduino板。它们是:

  • Master Transmitter / Slave Receiver 

    主发射器/从接收器

  • Master Receiver / Slave Transmitter 

    主接收器/从发射器

主发射器/从接收器

让我们现在看看什么是主发送器和从接收器。

主发射器

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

  • Wire.begin(地址) – 在我们的例子中,地址是7位从地址,因为未指定主机,它将作为主机加入总线。

  • Wire.beginTransmission(地址) – 开始向给定地址的I2C从设备发送数据。

  • Wire.write() – 用于从主设备传输到从设备的队列字节(在beginTransmission()和endTransmission()之间的调用)。

  • Wire.endTransmission() – 结束由beginTransmission()开始的对从设备的传输,并传输由wire.write()排队的字节。

示例

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

void setup() //this will run only once{
    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 <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);

  }  //-----this function will execute whenever data is received from master-----//
 
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 <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 <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++;

  }