Skip to main content

使用 Seeed Studio XIAO RA4M1 进行引脚复用

note

本文档由 AI 翻译。如您发现内容有误或有改进建议,欢迎通过页面下方的评论区,或在以下 Issue 页面中告诉我们:https://github.com/Seeed-Studio/wiki-documents/issues

数字引脚

XIAO RA4M1 提供多达 11 个常规 GPIO 引脚、6 个模拟引脚以及 8 个可复用的 IO 端口。在本示例中,我们将使用 XIAO RA4M1、XIAO 扩展板和一个继电器来演示如何使用不同的数字引脚进行读写操作。

硬件准备

Seeed Studio XIAO R4M1Seeed Studio 带 Grove OLED 的 XIAO 扩展底板Grove - 继电器

请将 XIAO RA4M1 或 Sense 安装到扩展板上,并通过 Grove 电缆将继电器连接到扩展板的 A0/D0 接口。最后,通过 USB-C 电缆将 XIAO 连接到计算机。

软件实现

在本示例中,我们将实现通过连接到 XIAO 扩展板的按钮来控制继电器的开/关状态。当按下按钮时,继电器打开;当释放按钮时,继电器关闭。

const int buttonPin = D1;     // 按钮引脚编号
int buttonState = 0; // 用于读取按钮状态的变量
const int relayPin = D0;

void setup() {
// 将继电器引脚初始化为输出模式:
pinMode(relayPin, OUTPUT);
// 将按钮引脚初始化为输入模式,并启用上拉电阻:
pinMode(buttonPin, INPUT_PULLUP);
}

void loop() {
// 读取按钮的状态:
buttonState = digitalRead(buttonPin);

// 检查按钮是否被按下。如果按下,buttonState 为 HIGH:
if (buttonState == HIGH) {
// 打开继电器:
digitalWrite(relayPin, HIGH);
} else {
// 关闭继电器:
digitalWrite(relayPin, LOW);
}
}

如果一切顺利,上传程序后,您应该会看到如下效果。

数字引脚作为 PWM 输出

XIAO RA4M1 的所有 GPIO 引脚均支持 PWM 输出。因此,您可以使用任意引脚输出 PWM 信号来调节灯光亮度、控制舵机等功能。

硬件准备

Seeed Studio XIAO RA4M1Seeed Studio 带 Grove OLED 的 XIAO 扩展底板Grove - 可变颜色 LED

请将 XIAO RA4M1 或 Sense 安装到扩展板上,然后通过 Grove 电缆将可变颜色 LED 连接到扩展板的 A0/D0 接口。最后,通过 USB-C 电缆将 XIAO 连接到您的计算机。

软件实现

在本示例中,我们将演示如何使用 PWM 输出来控制灯光的亮度。

int LED_pin = D0;    // LED 连接到数字引脚 10

void setup() {
// 将 LED 引脚声明为输出
pinMode(LED_pin, OUTPUT);
}

void loop() {
// 从最小值到最大值以 5 的增量渐亮:
for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 3) {
// 设置值(范围从 0 到 255):
analogWrite(LED_pin, fadeValue);
// 等待 30 毫秒以观察渐变效果
delay(30);
}

// 从最大值到最小值以 5 的增量渐暗:
for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 3) {
// 设置值(范围从 0 到 255):
analogWrite(LED_pin, fadeValue);
// 等待 30 毫秒以观察渐变效果
delay(30);
}
}

如果程序运行成功,您将看到以下运行效果。

模拟信号

XIAO RA4M1 开发板拥有高达 14 位的 ADC,用于高分辨率读取模拟传感器值,这可以帮助我们读取更精确的值。XIAO RA4M1 开发板上的模数转换器(ADC)默认分辨率设置为 10 位,可以调整为 12 位和 14 位分辨率,以提高模拟读取的精度。

ADC 精度的详细数据:

  • 10 位:0~1024
  • 12 位:0~4096
  • 14 位:0~16383

接下来,我们将选择两个传感器来反映 ADC 的特性。

硬件准备

Seeed Studio XIAO RA4M1Grove-可变颜色 LEDGrove-旋转角度传感器Seeed Studio Grove 基座用于 XIAO

软件实现

#define ADC_Bit_Fourteen 14
#define ADC_Bit_Twelve 12
#define ADC_Bit_Ten 10

const int analogInPin = A1; // 模拟输入引脚,连接到电位器
const int analogOutPin = 9; // 模拟输出引脚,连接到 LED

int sensorValue = 0; // 从电位器读取的值
int outputValue = 0; // 输出到 PWM(模拟输出)的值

void setup() {

Serial.begin(115200);
// Ten_Bite_ADC_Config(); // 10 位
// Twelve_Bite_ADC_Config(); // 12 位
Fourteen_Bite_ADC_Config(); // 14 位

}

void loop() {
sensorValue = analogRead(analogInPin);
outputValue = map(sensorValue, 0, 4095, 0, 255);
analogWrite(analogOutPin, outputValue);

Serial.print("传感器值 = ");
Serial.print(sensorValue);
Serial.print("\t 输出值 = ");
Serial.println(outputValue);
delay(100);
}

void Ten_Bite_ADC_Config() {
analogReadResolution(ADC_Bit_Ten);
}

void Twelve_Bite_ADC_Config() {
analogReadResolution(ADC_Bit_Twelve);
}

void Fourteen_Bite_ADC_Config() {
analogReadResolution(ADC_Bit_Fourteen);
}

如果一切顺利,在上传程序后,您应该看到以下效果。

串口通信

在使用 Arduino IDE 时,串口通信是许多项目的重要组成部分。要在 Arduino IDE 中使用串口通信,您需要首先打开串口监视器窗口。这可以通过点击工具栏中的 串口监视器 图标或按下快捷键 Ctrl+Shift+M 来完成。

常规用法

一些常用的串口函数包括:

  • Serial.begin() -- 初始化通信并指定波特率;
  • Serial.print() -- 以可读格式将数据发送到串口;
  • Serial.write() -- 将二进制数据发送到串口;
  • Serial.available() -- 检查串口是否有可读取的数据;
  • Serial.read() -- 从串口读取一个字节的数据;
  • Serial.flush() -- 等待传输的串口数据发送完成。

通过使用这些串口函数,您可以在 Arduino 板和计算机之间发送和接收数据,从而为创建交互式项目打开了许多可能性。

以下是翻译后的文档内容:

void setup() {
// 初始化串口通信,速率为每秒9600比特:
Serial.begin(9600);
}

void loop() {
// 向串口发送数据
Serial.println("你好,世界!");

// 从串口读取数据
if (Serial.available() > 0) {
// 读取传入的字节:
char incomingByte = Serial.read();
// 将接收到的字节打印到串口监视器:
Serial.print("我接收到:");
Serial.println(incomingByte);
}

// 等待一秒后重复循环
delay(1000);
}

使用 Serial1

根据上述 XIAO RA4M1 的引脚图,我们可以看到有 TX 引脚和 RX 引脚。这与普通的串口通信有所不同,但用法非常相似,只需添加一些参数即可。接下来,我们将使用芯片引出的引脚进行串口通信。


#define BAUD 115200

void setup() {
Serial1.begin(BAUD);
}

void loop() {
if(Serial1.available() > 0)
{
char incominByte = Serial1.read();
Serial1.print("我接收到:");
Serial1.println(incominByte);
}
delay(1000);
}

使用软件串口

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup() {
// 初始化硬件串口通信
Serial.begin(9600);
while (!Serial);

// 初始化软件串口
mySerial.begin(9600);
}

void loop() {
// 从软件串口读取数据
if (mySerial.available()) {
char data = mySerial.read();
Serial.print("接收到的数据:");
Serial.println(data);
}

// 向软件串口写入数据
mySerial.print("你好,世界!");

// 等待一秒后重复循环
delay(1000);
}

在这个程序中,我们首先包含了 SoftwareSerial.h 库以使用软件串口。然后,我们使用引脚 2 和 3 分别作为 RX 和 TX 创建了一个名为 mySerial 的 SoftwareSerial 对象。

setup() 函数中,我们初始化了硬件串口(Serial.begin())和软件串口(mySerial.begin())。

loop() 函数中,我们使用 mySerial.available() 函数检查是否有任何数据可从软件串口读取。如果有,我们使用 mySerial.read() 函数读取传入的字节并将其存储在名为 data 的变量中。然后,我们使用 Serial.print()Serial.println() 函数将 "接收到的数据:" 和 data 的值打印到硬件串口。

我们还使用 mySerial.print() 函数将 "你好,世界!" 写入软件串口。这将从 XIAO 发送数据到连接到软件串口的设备。

最后,我们添加了一个 delay() 函数,等待一秒后重复循环。

IIC

XIAO RA4M1 具有一个 I2C 接口,可用于许多传感器的数据传输和解析,也可用于一些 OLED 屏幕。

硬件准备

Seeed Studio XIAO RA4M1Seeed Studio XIAO 扩展板(带 Grove OLED)

XIAO 扩展板上的 OLED 显示屏使用 I2C 协议,并通过扩展板上的 I2C 电路连接到 XIAO 的 I2C 接口。因此,我们可以直接将 XIAO 插入扩展板并编程以在屏幕上显示内容。

软件实现

此示例介绍如何使用 Seeed Studio XIAO RA4M1 扩展板上的 OLED 显示屏。

第 1 步:将 Seeed Studio XIAO RA4M1 安装到扩展板上,然后连接 Type-C 数据线。

第 2 步:安装 u8g2 库。

第 3 步:复制代码并粘贴到 Arduino IDE 中,然后上传。

#include <Arduino.h>
#include <U8x8lib.h>
#include <Wire.h>

U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* clock=*/ SCL, /* data=*/ SDA, /* reset=*/ U8X8_PIN_NONE); // 无复位引脚的 OLED 显示屏

void setup(void) {
u8x8.begin();
u8x8.setFlipMode(1); // 设置数字从 1 到 3,屏幕内容将旋转 180 度
}

void loop(void) {
u8x8.setFont(u8x8_font_chroma48medium8_r);
u8x8.setCursor(0, 0);
u8x8.print("我是 XIAO RA4M1");
}

在代码的前几行中,我们包含了所需的库,例如 Arduino.h、U8x8lib.h 和 Wire.h。U8x8lib.h 库提供了控制 OLED 显示屏的功能,而 Wire.h 库提供了用于 I2C 通信的功能。

setup() 函数中,我们使用 u8x8.begin() 函数初始化 OLED 显示屏。我们还使用 u8x8.setFlipMode() 函数设置显示屏的翻转模式,以将屏幕旋转 180 度。

loop() 函数中,我们使用 u8x8.setFont() 函数设置字体,并使用 u8x8.setCursor() 函数指定显示屏上的光标位置。最后,我们使用 u8x8.print() 函数在 OLED 显示屏上显示字符串 "Hello World!"。

如果将程序上传到 XIAO RA4M1,您将在扩展板上的 OLED 显示屏上看到内容显示。

SPI

RA4M1 芯片集成了多个外设,包括一个 SPI 接口,可用于连接外部 SPI 设备,例如闪存、显示屏、传感器等。XIAO RA4M1 还支持高速 SPI 传输模式,最高可实现 80 MHz 的 SPI 传输速率,满足大多数 SPI 设备的数据传输需求。

硬件准备

Seeed Studio XIAO RA4M1Grove - OLED Display 1.12 (SH1107) V3.0 - SPI/IIC

按照上述硬件准备后,使用跳线连接 XIAO 和 OLED 的 SPI 接口。请参考以下连接方法图示。

软件实现

接下来,我们将以以下程序为例,介绍如何使用 SPI 接口控制 OLED 屏幕显示。

安装 u8g2 库。

#include <Arduino.h>
#include <U8g2lib.h>
#include <SPI.h>
#include <Wire.h>

U8G2_SH1107_128X128_1_4W_HW_SPI u8g2(U8G2_R3, /* cs=*/ D7, /* dc=*/ D4, /* reset=*/ D5);

void setup(void) {
u8g2.begin();
}

void loop(void) {
u8g2.firstPage();

do {
u8g2.setFont(u8g2_font_luBIS08_tf);
u8g2.drawStr(0,24,"Hello Seeed!");
} while ( u8g2.nextPage() );
}

setup() 函数中,U8G2_SH1107_128X128_1_4W_HW_SPI 类通过适当的构造函数参数实例化,这些参数指定了用于芯片选择 (cs)、数据/命令 (dc) 和复位 (reset) 的引脚。然后调用 u8g2.begin() 函数初始化显示屏。

loop() 函数中,使用 u8g2.firstPage()u8g2.setFont()u8g2.drawStr() 函数更新显示屏内容。u8g2.firstPage() 函数设置显示缓冲区以进行写入,而 u8g2.nextPage() 显示更新的内容。do-while 循环确保内容持续显示,直到程序停止。

总体而言,此代码演示了如何使用 U8g2 库控制 OLED 显示屏并在其上显示文本。

CAN

硬件准备

Seeed Studio XIAO RA4M1XIAO CAN Bus 扩展板

第一步:准备两个 CAN Bus Breakout Board 和 XIAO RA4M1

第二步:将这两个 XIAO RA4M1 分别插入 CAN Bus Breakout Board

第三步:准备杜邦线连接

软件准备

我们提供了一个 适用于 MCP2515 板的 Arduino 库


该库包含几个示例,包括:

  • OBDII-PIDs - 从 OBD-II 接口检索数据
  • send - 向 CAN 总线发送帧
  • recv - 从 CAN 总线接收帧
  • set_mask_filter_recv - 使用掩码和过滤器设置从 CAN 总线接收帧

软件实现

tip

不允许同时为两个 XIAO RA4M1 上电并下载程序,否则会导致串口下载错误。下载一个后,拔掉它,然后为另一个 XIAO RA4M1 上电并下载程序,最后同时上电以检查串口消息。

CAN 写入代码

/*  从 CAN 总线发送一帧数据

CAN 波特率定义:

#define CAN_5KBPS 1
#define CAN_10KBPS 2
#define CAN_20KBPS 3
#define CAN_25KBPS 4
#define CAN_31K25BPS 5
#define CAN_33KBPS 6
#define CAN_40KBPS 7
#define CAN_50KBPS 8
#define CAN_80KBPS 9
#define CAN_83K3BPS 10
#define CAN_95KBPS 11
#define CAN_100KBPS 12
#define CAN_125KBPS 13
#define CAN_200KBPS 14
#define CAN_250KBPS 15
#define CAN_500KBPS 16
#define CAN_666KBPS 17
#define CAN_1000KBPS 18
*/

#include <mcp_can.h>
#include <SPI.h>

/* 请根据您的板子修改 SPI_CS_PIN。

CANBed V1 - 17
CANBed M0 - 3
CAN Bus Shield - 9
CANBed 2040 - 9
CANBed Dual - 9
OBD-2G Dev Kit - 9
OBD-II GPS Kit - 9
Hud Dev Kit - 9

Seeed Studio CAN-Bus Breakout Board for XIAO 和 QT Py - D7
*/

#define SPI_CS_PIN D7

MCP_CAN CAN(SPI_CS_PIN); // 设置 CS 引脚

void setup()
{
Serial.begin(115200);
while(!Serial);

// 以下代码适用于 OBD-II GPS Dev Kit Atemga32U4 版本
// pinMode(A3, OUTPUT);
// digitalWrite(A3, HIGH);

// 以下代码适用于 OBD-II GPS Dev Kit RP2040 版本
// pinMode(12, OUTPUT);
// digitalWrite(12, HIGH);

while (CAN_OK != CAN.begin(CAN_500KBPS)) // 初始化 CAN 总线:波特率 = 500k
{
Serial.println("CAN 总线初始化失败!");
delay(100);
}
Serial.println("CAN 总线初始化成功!");
}

unsigned char stmp[8] = {0, 1, 2, 3, 4, 5, 6, 7};
void loop()
{
CAN.sendMsgBuf(0x00, 0, 8, stmp);
delay(100); // 每 100ms 发送一次数据
}

// 文件结束

CAN 读取代码

/*  从 CAN 总线接收一帧数据

CAN 波特率定义:

#define CAN_5KBPS 1
#define CAN_10KBPS 2
#define CAN_20KBPS 3
#define CAN_25KBPS 4
#define CAN_31K25BPS 5
#define CAN_33KBPS 6
#define CAN_40KBPS 7
#define CAN_50KBPS 8
#define CAN_80KBPS 9
#define CAN_83K3BPS 10
#define CAN_95KBPS 11
#define CAN_100KBPS 12
#define CAN_125KBPS 13
#define CAN_200KBPS 14
#define CAN_250KBPS 15
#define CAN_500KBPS 16
#define CAN_666KBPS 17
#define CAN_1000KBPS 18

CANBed V1: https://www.longan-labs.cc/1030008.html
CANBed M0: https://www.longan-labs.cc/1030014.html
CAN Bus Shield: https://www.longan-labs.cc/1030016.html
OBD-II CAN Bus GPS Dev Kit: https://www.longan-labs.cc/1030003.html
*/

#include <SPI.h>
#include "mcp_can.h"

/* 请根据您的板子修改 SPI_CS_PIN。

CANBed V1 - 17
CANBed M0 - 3
CAN Bus Shield - 9
CANBed 2040 - 9
CANBed Dual - 9
OBD-2G Dev Kit - 9
OBD-II GPS Kit - 9
Hud Dev Kit - 9

Seeed Studio CAN-Bus Breakout Board for XIAO 和 QT Py - D7
*/

#define SPI_CS_PIN D7

MCP_CAN CAN(SPI_CS_PIN); // 设置 CS 引脚

void setup()
{
Serial.begin(115200);
while(!Serial);

// 以下代码适用于 OBD-II GPS Dev Kit Atemga32U4 版本
// pinMode(A3, OUTPUT);
// digitalWrite(A3, HIGH);

// 以下代码适用于 OBD-II GPS Dev Kit RP2040 版本
// pinMode(12, OUTPUT);
// digitalWrite(12, HIGH);

while (CAN_OK != CAN.begin(CAN_500KBPS)) // 初始化 CAN 总线:波特率 = 500k
{
Serial.println("CAN 总线初始化失败!");
delay(100);
}
Serial.println("CAN 总线初始化成功!");
}

void loop()
{
unsigned char len = 0;
unsigned char buf[8];

if(CAN_MSGAVAIL == CAN.checkReceive()) // 检查是否有数据到来
{
CAN.readMsgBuf(&len, buf); // 读取数据,len: 数据长度,buf: 数据缓冲区

unsigned long canId = CAN.getCanId();

Serial.println("-----------------------------");
Serial.print("从 ID 获取数据: ");
Serial.println(canId, HEX);

for(int i = 0; i<len; i++) // 打印数据
{
Serial.print(buf[i], HEX);
Serial.print("\t");
}
Serial.println();
}
}

// 文件结束
tip

在此示例中,您需要焊接一个 CAN Bus Breakout Board 的端子引脚 P1,只有这样才能使用任意速度,否则只能使用低于 125 的 CAN 波特率。

什么时候需要连接终端电阻?

    1. 长距离通信:如果 CAN 总线较长(例如超过 1 米),必须在总线两端连接终端电阻,以避免因信号反射引起的通信问题。
    1. 多节点通信:如果多个节点连接到同一 CAN 总线,终端电阻也是必不可少的。它们可以确保总线的阻抗稳定,从而防止信号失真。

什么时候可以断开终端电阻?

    1. 短距离通信:在某些短距离应用中(通常小于 1 米),可以省略终端电阻,因为信号反射对通信的影响相对较小。
    1. 单节点通信:如果总线上只有一个节点(例如在调试环境中)且距离较短,可以暂时断开终端电阻。
发送端代码结果接收端代码结果

技术支持与产品讨论

感谢您选择我们的产品!我们致力于为您提供多种支持,确保您使用我们的产品时体验顺畅。我们提供了多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...