Arduino Wire库

Wire库可以让Arduino与IIC / TWI设备进行通信。 与SPI总线一样, IIC也是主从方式通讯, 因此不能同时存在两个主设备,只能是一个主设备与一个或多个从设备进行通讯。
使用之前使用以下语句进行Wire库声明
#include <Wire.h>

下表显示了TWI引脚在各种Arduino板上的位置。

Board
I2C / TWI pins
Uno
A4 (SDA), A5 (SCL)
Mega2560
20 (SDA), 21 (SCL)
Leonardo
2 (SDA), 3 (SCL)

注意
一般来说I2C地址有7位和8位的版本。 7位是设备标识码,而第8位则是为了确认设备当前状态是正在写入还是读取。 而Arduino -Wire库始终使用的是7位地址。 如果您使用了8位,则需要删除低位,从而得到0到127之间的地址。但是,地址从0到7 被保留了, 因此您在开发的时候请不要使用它们!!! 可以从8开始使用。
另外,连接SDA / SCL引脚时需要一个上拉电阻。 MEGA 2560开发板上引脚20-21具有上拉电阻。
Wire库的实现使用32字节缓冲区,因此任何通信的数据长度都必须在此限制之内,单次传输中超出的字节将被丢弃。


库函数

函数 用途 参数说明 返回值
begin()
begin(address)
初始化Wire库,并以主机或从机身份加入I2C总线。
通常来说这个函数只调用一次。
address(可选):7位从机的地址; 如果这个参数未指定,则默认以主机身份加入总线。
注:地址从0到7 被保留了, 因此您在开发的时候请不要使用它们!!! 可以从8开始使用。
requestFrom(address , quantity)
requestFrom(address , quantity, stop)
由主设备用来向从设备请求字节。
请求发送之后可以使用available()和read()来接受并读取数据。
从Arduino 1.0.1开始,requestFrom()接受一个布尔参数来适配某些I2C设备来达到兼容的目的。
address: 设备的7位地址,用于请求字节
quantity: 请求的字节数
stop (bool): 值为true则在请求后发送停止消息,释放总线。值为 false则在请求后发送重启信息,以保持连接处于活动状态。默认值是true。
返回值类型 :byte
返回从设备响应的字节数
beginTransmission(address) 使用指定的地址开始向I2C从设备进行传输。
在调用了Wire.beginTransmission(address)函数之后,使用write()函数对要传输的字节进行队列,并通过调用endTransmission()进行传输。
address: 要传输数据的目的设备的7位地址
endTransmission()
endTransmission(stop)
停止与从机的数据传输,与beginTransmission配对使用。 stop(bool): 参数值为true时将在请求后发送停止指令并释放总线;
参数值为false时将在请求后发送重新启动的指令,保持连接状态。
返回值类型:byte
返回传输的状态值:
0: 成功
1: 数据量超过传送缓存容纳限制
2: 传送地址时收到 NACK
3: 传送数据时收到 NACK
4: 其它错误
write(value)
wrtie(string)
write(data, length)
对于从设备来说: write()用于响应来自主设备的请求,即从设备写入数据
对于主设备来说: write()将数据进行队列, 用以从主设备传输到从设备, 这个函数通常在beginTransmission()和endTransmission()之间进行调用。
value: 一个要发送的单字节
string: 一系列要发送的字符串
data: 要作为字节发送的数组数据
length: 要传输的字节数
返回值类型 : byte
返回写入的字节数
available() available() 函数可用于检查是否接收到数据。该函数将会返回等待读取的数据字节数。
应该在调用requestFrom()之后再在主设备上调用此函数,或者在从设备的onReceive()的事件处理函数内的调用此函数。
返回缓冲区中可读取的字节数。
read() 读取在requestFrom()调用后从从设备响应发送到主设备的字节,或从主设备发送到从设备的字节。 读取的下一个字符,返回值为接读取到的数据流中的1个字符。
如果没有数据时,返回值为-1
setClock(clockFrequency) SetClock()函数用于修改I2C通信的时钟频率。
I2C从设备没有最低的工作时钟频率,但是通常以100KHz为基准。
clockFrequency:所需通信时钟的值(以赫兹为单位)。
可接受的值为100000(标准模式)和400000(快速模式)。一些处理器还支持10000(低速模式),1000000(加快速模式)和3400000(高速模式)。请参考特定的处理器文档,以确保支持所需的模式。
onReceive(handler) 当从设备接收到来自主机的传输时,注册要调用的函数。 handler:从机接收数据时要调用的函数;
这个函数应该使用一个int参数(用于从主设备读取字节数),并且这个函数不应返回任何内容,
例如: void recHandler(int num)


onRequest(handler) 当主设备请求从从设备发送数据时,从设备通过onRequest设置调用的函数。 handler:当主设备请求从从设备发送数据时,从设备要调用的函数。此函数不带参数,不返回任何值,例如: void reqHandler()


两块UNO通过IIC进行通讯

所需硬件
  • 2块Arduino开发板
  • 杜邦线
电路连接

将主设备开发板的引脚4(或SDA数据引脚)和引脚5(或SCL时钟引脚)连接到从设备开发板的对应引脚上。图示电路图以两块UNO为例进行连接

为了保证串口通信的运行,必须通过USB将开发板连接到计算机上并保证各个开发板的供电。

Arduino Wire库Wire板间通讯电路图Arduino


一、主设备读取,从设备发送

在这个示例中,将使用两块开发板通过I2C通讯协议在主设备读取/从设备发送的方式进行通信。

Arduino UNO主设备通过使用Wire库, 可以请求并读取从唯一寻址的从设备 Arduino UNO发送来的6字节数据。 收到该消息后,便可以在Arduino IDE 串口监视器窗中进行查看。

主设备读取

// 引入Wire库文件
#include <Wire.h>
 
void setup()
{
    // Wire初始化, 加入i2c总线
    // 如果未指定,则以主机身份加入总线。
    Wire.begin();
    // 初始化串口并设置波特率为9600
    Serial.begin(9600);
}
 
void loop()
{
    // 向从设备#8请求6个字节
    Wire.requestFrom(8, 6);
    // 当从从设备接收到信息时值为true
    while (Wire.available())
    {
        // 接受并读取从设备发来的一个字节的数据
        char c = Wire.read();
        // 向串口打印该字节
        Serial.print(c);
    }
    // 延时500毫秒
    delay(500);
}

从设备发送

// 引入Wire库文件
#include <Wire.h>
 
void setup()
{
    // Wire初始化, 并以从设备地址#8的身份加入i2c总线
    Wire.begin(8);
    // 注册请求响应事件
    Wire.onRequest(requestEvent);
}
 
void loop()
{
    delay(100);
}
 
// 每当接收到来自主机的数据时执行的事件函数
// 此函数被注册为事件,调用请见setup()
void requestEvent()
{
    // 用6个字节的消息进行响应
    Wire.write("hello ");
    // 以此回应主设备的请求
}


二、主设备写入, 从设备接受

在这个示例中,将使用两个开发板通过I2C同步串行协议以主机写入从机接受的方式相互通信。

Arduino UNO(主设备)经过编程,每半秒向唯一寻址的从设备发送6个字节的数据。 从设备收到该消息后,可以在Arduino IDE 的串口监视器窗口中查看该数据。

主设备写入

// 引入Wire库文件
#include <Wire.h>
 
void setup()
{
    // Wire初始化, 加入i2c总线
    // 如果未指定,则以主机身份加入总线。
    Wire.begin();
}
 
// 定义一个byte变量以便串口调试
byte x = 0;
 
void loop()
{
    // 将数据传送到从设备#8
    Wire.beginTransmission(8);
    // 发送5个字节
    Wire.write("x is ");
    // 发送一个字节
    Wire.write(x);
    // 停止传送
    Wire.endTransmission();
 
    x++;
    delay(500);
}

从设备接受

// 引入Wire库文件
#include <Wire.h>
 
void setup()
{
    // Wire初始化, 并以从设备地址#8的身份加入i2c总线
    Wire.begin(8);
    // 注册接受事件函数
    Wire.onReceive(receiveEvent);
    // 初始化串口并设置波特率为9600
    Serial.begin(9600);
}
 
void loop()
{
    delay(100);
}
 
// 每当接收到来自主机的数据时执行的事件函数
// 此函数被注册为事件,调用请见setup()
void receiveEvent(int howMany)
{
    // 循环读取数据(除了最后一个字符)
    while (1 < Wire.available())
    {
        // 接收字节数据并赋值给变量c(char)
        char c = Wire.read();
        // 打印该字节
        //太极创客团队 / Taichi-Maker (www.taichi-maker.com)
        Serial.print(c);
    }
    // 以int整数的形式接受字节数据并赋值给x(int)
    int x = Wire.read();
    // 打印该int变量x
    Serial.println(x);
}


- 本文为本站原创文章,转载请保留出处。
- 文章链接:https://www.xpstem.com/article/10401

2022-06   阅读(3152)   评论(0)
 标签: maker Arduino I2C

涨知识
PWM

PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过调节占空比的变化来调节信号、能量等的变化。

评论:
相关文章

ESP32 使用DAC模拟输出完成两路呼吸灯

ESP32的DAC函数可以实现真正的模拟输出。


在 ESP32 上使用 LEDC (PWM)

ESP32 没有Arduino输出 PWM 的 analogWrite(pin, value) 方法,取而代之的 ESP32 有一个 LEDC 来实现PWM功能。


《米思齐实战手册:Arduino图形化编程指南》

本书由少年创学院联合创始人兼院长、知名创客程晨撰写,以Arduino作为硬件平台,介绍了使用米思齐(Mixly)软件进行程序开发的方法。


ESP32 使用 MicroPython:I2C 总线

本文以一个简单的例程帮助大家在 MicroPython 下使用 I2C


ESP32 I2C

ESP32有2个硬件I2C总线接口,接口可以配置为主机或从机模式。


Arduino UNO R4 WiFi 官方介绍文档

本文档作为UNO R4 WiFi的技术概览,您将找到一系列资源和指南链接,帮助您开始下一个项目。


OneButton: 用于使用单个按钮进行多用途输入的Arduino库

Arduino OneButton库是一个用于简化按钮操作的库,它可以轻松地处理按钮的单击、双击和长按等操作。适用于Arduino开发板以及ESP32等其他基于Arduino的开发板。


Arduino Bootloader

本文从Arduino Uno入手,看看怎样在这个"简单"的8bit单片机搭建一个属于自己的bootloader


Arduino IDE第三方开发包的制作

许多硬件厂商都希望自己的开发板能被Arduino IDE集成开发环境所支持。这里就以小脚丫开发板所使用的开发包为例,介绍一下第三方开发包的制作方法。

搜索
小鹏STEM教研服务

专属教研服务系统,助您构建STEM课程体系,打造一站式教学环境。