Arduino UNO R4系列带有CAN通信接口。CAN是一种串行总线协议,主要用于汽车行业。本教程讲讲解Arduino CAN总线库的使用。教程目标了解CAN库的使用 了解如何连接到CAN模块 通过CAN总线,使两个Arduino开发板通信 软硬件准备Arduino IDE(先安装UNO R4 Board Package) Arduino UNO R4 Minima/WiFi SN65HVD230模组 CAN通信概要CAN总线使用两条线:CAN高和CAN低。在Arduino UNO R4 Minima上,这些引脚是: D5/CANRX0 (receive) D4/CANTX0 (transmit)
然而,要与其他CAN设备通信,您需要一个收发器模块。在本教程中,我们将使用SN65HVD230转接头。要连接此电路,您可以按照以下部分中的电路图进行操作。 在本教程中,我们将使用一个简单的示例,在两个UNO R4设备之间发送CAN消息。如果您愿意,您还可以将现有的Can设备连接到UNO R4。 连接方式要连接CAN收发器,请按照下表和电路图进行操作: UNO R4 Minima | CAN Transceiver |
---|
D5 (CANRX0) | CANRX | D4 (CANTX0) | CANTX | 3.3 V | VCC | GND | GND |
在CAN收发器之间连接以下部件: CAN Transceiver 1 | CAN Transceiver 2 |
---|
CANH (HIGH) | CANH (HIGH) | CANL (LOW) | CANL (LOW) |
代码示例以下代码示例需要上传到每个UNO R4 Minima板,一个发送消息,一个接收消息。这些示例在UNO R4板包中可用,使用Arduino IDE,您可以通过导航到 文件>示例>Arduino_CAN > CANWrite/CANRead来访问示例程序。 CAN通信库已经内置于Arduino UNO R4包中,无需再次安装。 初始化CAN通信可以使用以下代码初始化CAN通信,初始化时需要设置通信速率。 CAN.begin(CanBitRate::BR_250k)
CAN通信支持速率有: BR_125k (125000) BR_250k (250000) BR_500k (500000) BR_1000k (1000000)
CAN写操作要发送CAN消息,需要先构造一个CanMsg对象,其中应包含CAN_ID、大小和消息数据。下面是一个如何创建此类对象的示例。 uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg msg(CAN_ID, sizeof(msg_data), msg_data);
在构造完CAN消息后,可以使用CAN.write()方法将其发送出去。以下示例创建了一个CAN消息,该消息在每次执行void loop()时都会增加。
#include <Arduino_CAN.h>
static uint32_t const CAN_ID = 0x20;
void setup()
{
Serial.begin(115200);
while (!Serial) { }
if (!CAN.begin(CanBitRate::BR_250k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
static uint32_t msg_cnt = 0;
void loop()
{
uint8_t const msg_data[] = {0xCA,0xFE,0,0,0,0,0,0};
memcpy((void *)(msg_data + 4), &msg_cnt, sizeof(msg_cnt));
CanMsg const msg(CanStandardId(CAN_ID), sizeof(msg_data), msg_data);
if (int const rc = CAN.write(msg); rc < 0)
{
Serial.print ("CAN.write(...) failed with error code ");
Serial.println(rc);
for (;;) { }
}
msg_cnt++;
delay(1000);
}
CAN读操作要读取传入的CAN消息,请先使用CAN.available() 检查数据是否可用,然后再使用CAN.read()读取消息。
#include <Arduino_CAN.h>
void setup()
{
Serial.begin(115200);
while (!Serial) { }
if (!CAN.begin(CanBitRate::BR_250k))
{
Serial.println("CAN.begin(...) failed.");
for (;;) {}
}
}
void loop()
{
if (CAN.available())
{
CanMsg const msg = CAN.read();
Serial.println(msg);
}
}
总结本教程展示了如何使用UNO R4 Minima上可用的CAN总线,以及如何使用Arduino_CAN库发送和接收数据。 |