在本教程中,我们将了解如何在Arduino上设置和使用I2C通信。本Arduino I2C教程解释了Arduino中的I2C引脚,配置主和从,最后是一个简单的演示,其中两个Arduino UNO板通过I2C进行通信。
I2C是什么?
I2C或者我2C是Inter-Integrated Circuit的缩写,这是一种同步串行通信协议,由Phillips开发,用于在快速的微控制器和相对较慢的外围设备(如内存或传感器)之间使用两根电线进行通信。因此,它有时也被称为TWI(双线接口)。
使用I2C,可以以100kbit /s(时钟100khz -标准模式),400kbit /s(时钟400khz -快速模式),1mbit /s(时钟1mhz -快速模式+)和3.4 Mbit/s(时钟3.4 MHz -高速模式)的速率传输数据。
这可能看起来不多,但它足以在小距离上连接传感器、存储器和显示器。
I2C总线
I2C总线由两根导线组成,称为串行数据(SDA)和串行时钟(SCL)。数据通过SDA线传输,SCL线用于设备与时钟信号的同步。
这两条总线线路都是开放式排水驱动器,因此你必须使用上拉电阻来保持它们的高。
有两种类型的设备连接到I2C总线:主设备和从设备。总线主负责向从设备发送和接收数据。时钟信号也由主机提供。
I2C网络支持多主多从(但我们通常看到的是单主多从)。连接到I2C总线的每个从设备都有一个唯一的7位地址。
使用这个地址,主服务器选择一个特定的从服务器进行数据传输(发送或接收),所选从服务器根据请求进行响应。
我做了一个关于I的基础知识的广泛教程2C通信。欲了解更多信息,请访问“I2C通信基础”。
I2C的Arduino
Arduino支持I2C通信。如果你看一下教程中Arduino UNO的pinoutARDUINO UNO引出线,模拟输入引脚A4和A5具有I2C的替代功能。
A4引脚作为SDA, A5引脚作为SCL。在原有的Arduino UNO R3中,在Digital IO Pin 13(靠近USB插座)附近还有两个引脚,专门用于SDA和SCL。
如果您正在使用任何其他板,那么下表将对您有用,因为它描述了所有流行的Arduino板上的I2C引脚。
董事会 | SDA和SCL引脚 |
Arduino UNO | A4和A5 |
Arduino纳米 | A4和A5 |
Arduino超级2560 | 20和21 |
Arduino微 | 2和3 |
Arduino达芬奇 | 2和3 |
ATmega328P微控制器用于Arduino UNO和Nano支持高达400khz的I2C数据传输速度。
如何使用Arduino I2C接口?
为了演示I2C在Arduino中的工作,让我们构建一个小电路。在这个演示中,我连接了两块Arduino UNO板,通过I2C总线进行通信。为了让事情变得有趣,并真正看到通信,我添加了一对led和电位器(每个UNO板一套)。
电位器连接到各自的模拟输入引脚(A0), led连接到具有PWM的数字IO引脚(pin9)。一个UNO板配置为I2C总线主,另一个UNO配置为从设备。
当我调整连接到主Arduino UNO的电位器时,它从POT捕获模拟读数,将其转换为数字值(在0 - 1023的范围内),将其映射到适当的PWM值(在0 - 255的范围内),并通过I2C总线将该值传输到从Arduino。
Slave Arduino,在接收到PWM值后,调整其LED的亮度。此外,从Arduino发送自己的电位器值转换为PWM数字到主Arduino(从主请求)。
然后主Arduino从从Arduino读取PWM值,并根据该值调整其LED的亮度。这种通信在I2C总线上无缝地继续和重复。
这是一个简单的电路,只是为了了解Arduino I2C通信。你可以修改电路,使一个复杂的I2C总线网络与不同的从设备,如I2C LCD, EEPROM IC, BMP180气压传感器等(有数据记录的气象站)。
组件的要求
- Arduino UNO x 2
- 10 kΩ电位器x 2
- 5mm LED x 2
- 330Ω电阻x 2
- 电路试验板
- 连接电线
- 面包板电源(可选)
线路图
下图是Arduino I2C在两块Arduino UNO板之间演示的电路图。
代码
为了在Arduino中对I2C外设进行编程,您需要了解Wire库。这是允许您通过I2C总线(SDA和SCL线)与I2C或TWI设备通信的主库。
线库
它附带Arduino IDE,你不需要下载任何额外的东西。你所要做的就是在Arduino中包含与I2C一起工作的Wire库。
# include < Wire.h >
Wire库提供了10个用于开发I2C相关应用程序的函数。它们是:
- Wire.begin ()
- Wire.requestFrom ()
- Wire.beginTransmission ()
- Wire.endTransmission ()
- Wire.write ()
- Wire.available ()
- Wire.read ()
- Wire.SetClock ()
- Wire.onReceive ()
- Wire.onRequest ()
现在让我们详细了解一些重要的Wire Library函数。
线库函数
Wire.begin ()
该功能用于发起I2C通信。如果将7位设备地址作为参数传递给该函数,则设备将作为从设备加入I2C总线,否则将作为主设备加入。
- Wire.begin()——的主人
- Wire.begin(地址)——奴隶
Wire.beginTransmission(地址)
使用此功能可以开始向指定地址的从设备传输数据。
Wire.write ()
使用上述函数开始传输之后,现在就可以使用Wire.write()函数开始发送实际数据了。
当Master使用Wire.RequestFrom()函数时,你也可以使用这个函数将数据从Slave写到Master。
- Wire.write(值)—发送单个字节值
- Wire.write(字符串)—以字符串形式发送一系列字节
- 电线。写(数据长度)—发送指定长度的数据数组
Wire.endTransmission ()
要结束I2C数据传输,请使用Wire.endTransmission()函数。
Wire.read ()
当Master调用Wire.requestFrom()函数时,使用此函数读取从Master传输到Slave或从Slave传输到Master的数据字节。
Wire.requestFrom ()
主I2C设备使用该功能向从设备请求字节数据。使用Wire.read()函数来检索数据。
- 电线。requestFrom(地址、数量)—向从设备请求以数量为单位的数据字节数,并在address字段中指定地址。
Wire.onReceive ()
这是一个处理函数,用于定义当Slave从Master接收数据时调用的函数。
Wire.onRequest ()
这是一个处理函数,用于定义当Master向slave请求数据时调用的函数。
主代码
利用上述功能,我为Master Arduino写了一个简单的代码,发送PWM值,并向Slave请求一个字节的数据。
奴隶的代码
在Slave Arduino代码中,我将Slave地址定义为0x14。它可以是任何小于128的值。关于ArduinoI2C线库I需要注意的一点是,它使用7位的I2C地址,没有读/写位。
因此,如果您有一个8位地址(包括R / W位),右移地址1,然后在Wire Library中使用它。库将根据读或写操作自动调整地址。
另外,确保从服务器地址是唯一的,没有两个从服务器有相同的地址。
回到代码中,我声明了两个函数“DataReceive”和“DataRequest”,在从服务器接收数据或从服务器请求数据时调用它们。DataReceive函数中Slave接收到的数据包含Master发送的PWM值。
通过DataRequest功能传输的数据就是从Slave到Master的PWM值。
结论
本教程演示了使用I2C通信在两个Arduino板之间进行简单的双向通信。您了解了Arduino I2C外围设备、I2C通信的一些重要基础知识、Wire库以及如何设置和使用Arduino I2C通信。
一个回应
谢谢一个好的教程,非常有帮助