11.Arduino 内部集成电路(I2C)

有用的链接

  1. Arduino Wire参考:https://www.arduino.cc/en/Reference/Wire

  2. 我翻译的Wire库的应用说明:https://blog.csdn.net/acktomas/article/details/88069640

  3. I2C双向电平转换器(https://playground.arduino.cc/Main/I2CBi-directionalLevelShifter/),用于电平转换、上拉电阻和连接3.3V器件。

  4. Nick Gammon的有关I2C的页面(关于I2C的原理介绍很详细:http://gammon.com.au/i2c(该页面上还有一个“ I2C扫描程序”)。
    我将内容翻译:I2C-两线外设接口-用于Arduino:https://download.csdn.net/download/acktomas/11824487

  5. robtillaart制作了“ Multispeed I2C Scanner(https://forum.arduino.cc/index.php?topic=197360)” ,可以用不同的I2C速度进行扫描。如果您使用更长的导线或使用更高I2C速度的库,则Multispeed I2C扫描仪将非常有用。(与UNO一起验证,2009年,MEGA)

通信接口I2C

I2C接口的原意是"Inter IC",只用两条线来连接其他组件,为了方便同一个电路板上的各个组件相互通信。
I2C至少有一个主控端(master,通常由微处理器担任,负责发送时钟和地址信号)和至少一个从端(slave,通常是传感器组件),所有I2C组件的数据线和时钟线都连接在一起。此外,I2C的数据线和时钟线都要连接一个电阻到电源线,电阻值通常选择1~10KΩ,建议采用1.8kΩ。每个I2C组件的接地线必须相连。为了识别电路板上的不同组件,每个I2C从端都有一个唯一的地址编号。地址编号的长度为7位,总共可以表示27个地址(127个),详细I2C规范

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

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

[外链图片转存失败(img-1b8e23Nr-1569467307509)(https://img.w3cschool.cn/attachments/tuploads/arduino/i2c.jpg)]

板的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++; 
}

版权声明:本文为CSDN博主「acktomas」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/acktomas/article/details/84104641

生成海报
点赞 0

acktomas

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐

【翻译】arduino 内置示例

内置示例{#top} https://www.arduino.cc/en/Tutorial/BuiltInExamples 内置示例是Arduino软件(IDE)中包含的草图,单击工具栏菜单打开它们&