欢迎光临
我们一直在努力

Arduino的I2C主从机通信试验

11232323

==概述==

什么的 I2C 呢? I2C 即 Inter-Integrated Circuit 串行总线的缩写, 是 PHILIPS 公司推出的芯片间串行传输总
线。 它以 1 根串行数据线(SDA) 和 1 根串行时钟线(SCL) 实现了双工的同步数据传输。 具有接口线少, 控制方式简
化, 器件封装形式小, 通信速率较高等优点。 在主从通信中, 可以有多个 I2C 总线器件同时接到 I2C 总线上, 通过地
址来识别通信对象。
幸运的是, Arduino 已经为我们提供了 I2C 的库函数(Wire.h) , 这样我们就可以很轻松的玩 IIC 通讯了 。

I2C 总线也是主从方式通讯, I2C 总线允许连接多个微控制器, 显然不能同时存在两个主器件, 先控制总线的器件
成为主器件, 这就是总线竞争。 在竞争过程中数据不会被破坏、 丢失。 数据只能在主、 从器件中传送, 结束后, 主、
从器件将释放总线, 退出主、 从器件角色。

==函数介绍==

Arduino官方网站函数介绍:https://www.arduino.cc/en/Reference/Wire

此库中包含
1 Wire.begin()
2 Wire.requestFrom()
3 Wire.beginTransmission()
4 Wire.endTransmission()
5 Wire.write()
6 Wire.available()
7 Wire.read()
8 Wire.onReceive()
9 Wire.onRequest()

Wire.begin() 和 Wire.begin(address)

描述
初始化wire库 ,并且加入到I2C网络,前者作为Master 或 Slaver,并且只能调用一次

参数
address :7位的器件地址(可选),如果没有输入,则以Master的形式加入到I2C网络

Wire.requestFrom()

描述
主设备请求从设备一个字节,这个字节可以被主设备用 read()或available()接受
Wire.requrstFrom(addtess,quantity)
Wire.requrstFrom(addtess,quantity,stop)

参数
addtess : 7位的器件地址
quantity : 请求得到的数量
stop :布尔形,‘1’ 则在请求结束后发送一个停止命令,并释放总线。‘0’则继续发送请求保持连接

返回
字节形 ,从从机接受到的字节数目

Wire.beginTransmission(address)

描述
开始一次传输数据,发送一个I2C开始字符

参数
address : 器件的7位地址

返回
none

Wire.endTransmission()和Wire.endTransmission(stop)

描述
结束一个由beginTransmission()开始的并且由write()排列的从机的传输。在Arduino中 endTransmission()接受到
一个布尔形变量,如果为1 则endTransmission()发送一个停止信息;如果为0 则发送开始信息

返回
0 成功 1 数据溢出 2 发送addtess时从机接受到NACK 3 发送数据时接受到 NACK 4 其他错误

Wire.write()

描述
向从机发送数据

形式
Wire.write(value)
Wire.write(string)
Wire.write(data, length)

参数
value :要发送的数值
string :字符组的指针
data :一个字节数组
length :传输的数量

库文件示例程序,仅供参考:

#include <Wire.h>  
  
byte val = 0;  
  
void setup()  
{  
   Wire.begin(); // join i2c bus  
}  
  
void loop()  
{  
   Wire.beginTransmission(44); // transmit to device #44 (0x2c)  
                               // device address is specified in datasheet  
   Wire.write(val);             // sends value byte    
   Wire.endTransmission();     // stop transmitting  
  
   val++;        // increment value  
   if(val == 64) // if reached 64th position (max)  
   {  
     val = 0;    // start over from lowest value  
   }  
   delay(500);  
}  
Wire.available()

描述
Wire.requestFrom()请求从机数据后,可以使用available接收

Wire.read()

描述
Wire.requestFrom()请求从机数据后,可以使用read接收

Wire.onReceive()

描述
从机接收主机发来的数据

Wire.onRequest()

描述
从机请求主机发送数据

==接线方式==

3333_副本

主机A4———–从机A4

主机A5————从机A5

==例子程序==

主机A:

#include <Wire.h>
void setup()
{
Wire.begin(); //启动 I2C 总线, 地址缺省表示为主机
Serial.begin(9600); //启动串口, 设置波特率为 9600
Serial.println("Ready"); //发送字符
}
void loop()
{
int val;
if(Serial.available() > 0) //判断串口缓冲器是否有数据装入
{
val=Serial.read(); //读串口
if(val==49)//1
{
Wire.beginTransmission(2); // 与地址 2 的从机连接通讯
Wire.write(1); // 发送数字 1 开 LED
Wire.endTransmission(); // 停止发送
Serial.println("49 OK"); // 串口上显示 49 OK 表示完成, 49 表示为数字 1 的 ASCII 码
delay(10); //
}
else if(val==50)//2
{
Wire.beginTransmission(2); // 与地址 2的从机连接通讯
Wire.write(0); // 发送数字 0 关 LED
Wire.endTransmission(); // 停止发送
Serial.println("50 OK"); // 串口上显示 50 OK 表示完成
delay(10);
}
else Serial.println(val);
}
}

==============================================================

从机B:

#include <Wire.h>
int LED = 13;
void setup()
{
Wire.begin(2); // 设置从机地址为 2
Wire.onReceive(receiveEvent); //从机接收主机发来的数据
pinMode(LED,OUTPUT); // 设置 IO 口为输出模式
}
void loop()
{
delay(100);
}
void receiveEvent(int howMany) // 接收从主机发过来的数据
{
int c = Wire.read(); // 接收单个字节
if(c==1)
{
digitalWrite(LED,HIGH); // 如果为 1 开 LED
}
else if(c==0)
{
digitalWrite(LED,LOW); // 如果为 0 关 LED
}
}

==试验效果==

当主机A在字符框内发送1时,从机B点亮13引脚的LED灯,实现I2C主从机通信。

22222_副本

试验扩展:

   本实验只是简单的2个Arduino之间的I2C通信,您可以尝试其他I2C设备之间的通信。

未经允许不得转载:Arduino-Maker » Arduino的I2C主从机通信试验

支付宝扫码打赏 微信打赏

原创文章,若帮到您,欢迎打赏

分享到:更多 ()

评论 抢沙发

评论前必须登录!

 

线上商城

中贝斯特创客空间蘑菇云创客教育