0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何仅在两个Aduino之间进行2路I²C通信

454398 来源:网络整理 作者:网络整理 2019-11-25 15:16 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

步骤1:您需要什么:

我们假设您具有以下部分:

两个Arduino UNO

一些公对母电线

一些公对公电线

一个旋转电位计

一个面包板

步骤2:I²C的工作方式

I²C是一种通信协议,使您可以在微控制器和某些传感器等电路之间进行通信。它仅使用两根线(如此高效!)。第一线是时钟线,通常在文档中写为SCL。第二根线是数据线,通常写为SDA。

I²C总线上的设备可以是“主机”或“从机”。仅主机控制时钟线上的电压,而主机和从机都可以操纵数据线上的电压。通过仔细轮流,网络上的所有设备都可以共享信息。

为了将信息发送到正确的位置,每个从站都有一个唯一的地址号码,就像每个电话都有一个唯一的号码一样。

当我看到I²C器件时,他们有文档说:“该电路希望接收N字节表示ABC的数据,并发送回M字节表示DEF的数据。”如果您要购买的设备不包含此信息,则不要购买。

有关I2C通信内部工作的更多详细信息,请查看以下链接:

http://www.robot-electronics.co.uk/i2c-tutorial

http://www.i2c-bus.org/结果

https://en.wikipedia.org/wiki/I%C2%B2C

步骤3:设置

上图中的设备使用引脚A4和A5进行I²C通信。每种类型的arduino和Wire库的I²C引脚说明如下:

https://www.arduino.cc/zh/Reference/Wire

主设置看起来像这样:

#include

void setup() {

// note that begin() has no parameter.

Wire.begin();

}

从站设置看起来像这样:

#include

void setup() {

// note that begin() has a parameter.

// Any number from 0.。..127 will work.

Wire.begin(1);

}

如果您要在该网络上使用第二个从站,则需要除#1外的地址,因为该地址已被使用。这意味着只能通过仔细计划来添加和删除网络上的设备。许多使用I²C的设备都将带有一个带拨码开关(小光开关)的PCB,可以将其拨动以更改地址。便宜的型号将有裸露的接触。要翻转这些开关,必须触摸裸触点。

第4步:发送数据

与之交谈的人,然后发送信息,然后说“我完成了。”

void loop() {

Wire.beginTransmission(1);

Wire.write(“hello, ”);

Wire.endTransmission();

}

从站仅需发送信息。每个人都假定从服务器正在与主机通信。

void loop() {

Wire.write(“world!”);

}

Wire.write()具有三个版本:一个用于单个数字,一个用于字符串,以及一个用于数据块。您必须告诉Wire数据块有多长时间。

步骤5:接收数据

主机可以使用

Wire.read()

从网络获取单个字节的数据,而不管是谁发送的。

Wire.read()是阻塞操作-您的Arduino在读取一个字节之前不会做其他任何事情。如果没有要读取的字节,则可能要等待很长时间!为避免此问题,还有

Wire.available()

将返回等待读取的字节数。

将两者放在一起,

while(Wire.available()) {

char c = Wire.read();

// do something with c

// maybe count how much we received,

// do something when we get the whole message.

}

// do other stuff while we wait for the whole message.

第6步:请求/接收

您已经拥有运行I²C网络所需的一切,但是我想让您了解另外一项功能,这有点棘手,所以请忍受我。实际上,我会说这完全是不需要,但是我将其包括在内是为了彻底。也许表明有很多方法可以完成相同的工作,有些方法比其他方法更好。

您已经知道,在C代码中,有诸如setup()和loop()之类的方法。您也可以创建自己的方法并按名称调用它们。您是否知道可以将方法名称作为参数发送给另一个方法?通常用于称为回调的东西。在这种情况下,我们将告诉线库(I²C)当从站从网络接收数据时调用哪种方法。

// a master is calling and requesting something.

void requestEvent() {

// definitely send something back.

Wire.write(2); // one byte as an example.

}

// a master has sent something.

// Might not be requesting anything.

// Might not be all the data that was sent (yet)

void receiveEvent(int bytes) {

int i;

for(i=0;i char c = Wire.read();

// do something with c.

}

// maybe send something back

}

void setup() {

Wire.begin(1); // slave address = 1

Wire.onRequest(requestEvent);

Wire.onReceive(receiveEvent);

}

void loop() {

// do nothing!

}

此处的一些注意事项:

requestEvent()不会收到数字,说明主机期望多少字节。

据我所知,这些事件是中断-无论loop()中发生了什么,它们都会尽快发生。如果时间和代码正确,那么无论循环做什么,都可能会严重混乱。由于很难重新创建导致问题的条件,因此很难诊断出它为什么混乱。

因此,正如我所说的,尽管您可以使用这些工具,但我不建议您这样做

第7步:双向通信

现在让我们将它们放在一起。

主代码:

#include

#define TO_MASTER_SIZE 3

#define TO_SLAVE_SIZE 4

#define START_NODE 1 // The starting I2C address of slave nodes

#define END_NODE 2 // last node to probe +1

#define NODE_READ_DELAY 100 // Some delay between I2C node reads

byte messageToMaster[TO_MASTER_SIZE];

byte messageToSlave[TO_SLAVE_SIZE];

void setup() {

Serial.begin(9600);

Serial.println(“MASTER”);

Wire.begin(); // Activate I2C link

}

void loop() {

for (int address = START_NODE; address 《 END_NODE; address++) {

sendToSlave(address);

readFromSlave();

}

delay(NODE_READ_DELAY);

}

void sendToSlave(int address) {

// message is 0123

for(int i = 0; i 《 SEND_SIZE; i++) {

messageToSlave[i] = (byte)i;

}

Wire.beginTransmission(address);

Wire.write(messageToSlave, TO_SLAVE_SIZE);

Wire.endTransmission();

}

void readFromSlave() {

// if data size is available from nodes

if(Wire.available() == TO_MASTER_SIZE) {

for (int i = 0; i 《 TO_MASTER_SIZE; i++) {

messageToMaster[i] = Wire.read(); // get data

}

int fromAddress = messageToMaster[0];

int value = ((int)messageToMaster[1] 《《 8 ) | (int)messageToMaster[2];

Serial.print(“Slave ”);

Serial.print(fromAddress);

Serial.print(“ says ”);

Serial.print(value);

}

}

从站代码:

#include

// Change this unique address for each I2C slave node

#define NODE_ADDRESS 1

// matches values on master side.

#define TO_MASER_SIZE 3

#define TO_SLAVE_SIZE 4

#define NODE_READ_DELAY 100

byte messageToMaster[TO_MASTER_SIZE];

byte nodeReceive[TO_SLAVE_SIZE];

void setup() {

Serial.begin(9600);

Serial.print(“SLAVE #”);

Serial.println(NODE_ADDRESS);

Wire.begin(NODE_ADDRESS); // Activate I2C network

}

void loop() {

delay(NODE_READ_DELAY);

if(Wire.avaialable() == TO_SLAVE_SIZE) {

readFromMaster();

sendToMaster();

}

}

void readFromMaster() {

for(int i = 0; i 《 TO_SLAVE_SIZE; i ++){

nodeReceive[i] = Wire.read();

}

Serial.print(“Master says ”);

for(int i = 0; i 《 TO_SLAVE_SIZE; i ++){

Serial.print(nodeReceive[i]);

}

Serial.println();

}

void sendToMaster() {

int x = analogRead(A0);

messageToMaster[0] = NODE_ADDRESS;

messageToMaster[1] = (x0》》8) & 0xff; // the top byte of x

messageToMaster[2] = (x0 ) & 0xff; // the bottom byte of x

Wire.write(messageToMaster,TO_MASTER_SIZE);

Serial.print(“Sensor value: ”);

Serial.println(x);

}

有趣的一点是,总线(网络)上的任何人都可以收听双向通信。从理论上讲,可以添加一个静默设备,其唯一的工作就是监视网络。

第8步:最终想法

单个I²C网络可能有多个主机,但这是多余的棘手的问题–主机之间必须进行协商以避免彼此之间的交谈,这会导致混乱。

责任编辑:wv

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • aduino
    +关注

    关注

    0

    文章

    3

    浏览量

    3629
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    I2C的优点介绍

    简单性和线路效率: I2C 仅使用条线路(SDA(串行数据线)和 SCL(串行时钟线))提供简单而高效的通信解决方案,而与总线上的设备数量无关。这种简单性降低了电路设计的复杂性,最大限度地减少
    发表于 11-27 07:49

    I2C通信异常问题怎么解决?

    我们在进行I2C通信,发现当写数据时SCL和SDA会有下降沿重合的情况,导致通信失败,请帮忙分析下如何处理? I2C
    发表于 08-12 07:45

    I2C总线通信,为什么要进行电气隔离?

    I2C总线采用双向二线制,支持多主机多从机通信,具备高可靠性、抗干扰能力强,广泛应用于嵌入式系统中。
    的头像 发表于 08-11 11:04 2297次阅读
    <b class='flag-5'>I2C</b>总线<b class='flag-5'>通信</b>,为什么要<b class='flag-5'>进行</b>电气隔离?

    第十八章 I2C通信测试

    本章介绍了I2C协议,其物理层用SDA和SCL双线,支持多设备:协议层含起始/停止信号、应答机制等。还讲解W55MH32的I2C外设及初始化,并进行通信测试代码的分析。
    的头像 发表于 06-19 17:07 1050次阅读
    第十八章 <b class='flag-5'>I2C</b><b class='flag-5'>通信</b>测试

    【技术说明】数字输出压力传感器的I2C通信

    介绍I2C总线是一简单的,串行8位面向计算机总线有效的I2C(集成电路间)控制。It提供了良好的支持不同电路板距离之间通信,例如与各种低
    的头像 发表于 06-19 11:02 1541次阅读
    【技术说明】数字输出压力传感器的<b class='flag-5'>I2C</b><b class='flag-5'>通信</b>

    当CY7C65215在两个通道上配置为 SPI 和 I2C 时,能否在Linux系统中看到两个设备?

    我的客户想知道,当 CY7C65215 在两个通道上配置为 SPI 和 I2C 时,他能否在 Linux 系统中看到两个设备。
    发表于 05-26 06:27

    DLPC350有两个I2C接口,I2C0和I2C1,手册上写的都是工作为从模式,请问可以工作为主模式吗?

    DLPC350有两个I2C接口,I2C0和I2C1,手册上写的都是工作为从模式,请问可以工作为主模式吗,我需要在DLPC350上挂一e
    发表于 03-03 07:34

    I2C总线通信原理 如何设计I2C总线电路

    I2C总线通信原理 I2C(Inter-Integrated Circuit)总线是一种用于集成电路之间进行
    的头像 发表于 01-31 15:01 1909次阅读

    基于I2C总线的智能家居应用

    随着科技的飞速发展,智能家居系统已经成为现代生活的一重要组成部分。I2C(Inter-Integrated Circuit)总线是一种串行通信协议,广泛应用于微控制器和各种传感器之间
    的头像 发表于 01-17 16:21 1016次阅读

    I2C总线的优缺点分析

    设备之间通信,这大大减少了所需的引脚数量,降低了硬件成本。此外,由于其简单性,I2C总线也易于实现和维护。 2. 多主机和多从机支持 I2C
    的头像 发表于 01-17 15:50 1778次阅读

    I2C总线与Arduino的接口示例

    基础 I2C总线由条线组成:数据线(SDA)和时钟线(SCL)。SDA用于传输数据,而SCL用于同步数据传输。I2C设备可以是主设备或从设备。主设备生成时钟信号并启动数据传输,从设备响应主设备的请求。 Arduino与
    的头像 发表于 01-17 15:34 2390次阅读

    I2C总线的工作模式介绍

    根线组成:数据线(SDA)和时钟线(SCL)。数据线负责传输数据,而时钟线则用于同步数据传输。I2C总线是全双工的,意味着数据可以在两个方向上传输。它支持多个主设备和从设备,但在同一时刻只能有一
    的头像 发表于 01-17 15:32 1667次阅读

    I2C总线应用实例分析

    I2C总线使用条线进行通信:数据线(SDA)和时钟线(SCL)。这种双线制设计使得I2C总线能够在多个设备
    的头像 发表于 01-17 15:09 1265次阅读

    I2C总线与SPI总线的比较

    在现代电子系统中,微控制器与各种外设之间通信是必不可少的。I2C和SPI是种流行的串行通信协议,它们各自具有独特的特点和应用场景。
    的头像 发表于 01-17 15:08 1779次阅读

    adc12d1800两个通道采样,Q正常,I异常,为什么?

    项目中一片adc12d1800,两个通道采样,Q正常,I异常。 异常的具体现象为:采集噪声测试,从chipscope上观察,DI与DID不重合,多次复位,
    发表于 12-26 06:01