- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
本篇技术指南以 RT-Thread 仓库中 STM32L475 潘多拉 BSP 的 Arduino 引脚排布说明 为骨架,系统讲解如何在该开发板上开启 RTduino(RT-Thread 的 Arduino 生态兼容层)、理解 Arduino 引脚与 STM32 引脚的映射关系,以及如何直接用 Arduino 风格的pinMode、digitalWrite、analogRead、analogWrite、Wire、SPI、Serial等 API 操作板载外设。读完本文,你将掌握潘多拉板 40 路数字引脚(D0–D39)、4 路模拟输入(A0–A3)、1 路真模拟输出(DAC0)的完整排布,并能基于源码级证据独立完成 Arduino 风格的应用开发。
1 RTduino:RT-Thread 的 Arduino 生态兼容层
STM32L475 潘多拉 BSP 已完整适配 RTduino 软件包——即 RT-Thread 的 Arduino 生态兼容层。开启后,用户既可以保持 RT-Thread 原生的线程、设备框架编程方式,又可以按照 Arduino 的编程习惯(setup()/loop()、pinMode/digitalWrite等)操作该 BSP,并能复用 Arduino 社区丰富的外设库,是对 RT-Thread 生态的极大增强。
从构建脚本可以确认该兼容层的挂载方式:arduino_pinout/SConscript 中通过depend = ['PKG_USING_RTDUINO']将pins_arduino.c等引脚映射源文件条件性地纳入编译,也就是说,只有在包配置中启用了 RTduino 后,引脚排布代码才会参与构建。
1.1 如何开启针对本 BSP 的 Arduino 生态兼容层
在 Env 工具下敲入menuconfig命令,或在 RT-Thread Studio IDE 下选择 RT-Thread Settings,按如下路径勾选:
Hardware Drivers Config ---> Onboard Peripheral Drivers ---> [*] Compatible with Arduino Ecosystem (RTduino)该选项对应 board/Kconfig 中的BSP_USING_ARDUINO配置项。它不仅仅是一个开关,还会自动把 RTduino 运行所需的全部底层驱动一并选中:
- 串口:
BSP_USING_STLINK_TO_USART(uart1,同时作为调试串口); - GPIO:
BSP_USING_GPIO; - PWM:
BSP_USING_PWM1/PWM2/PWM4及其用到的通道(PWM1-CH1、PWM2-CH3/CH4、PWM4-CH1/CH3/CH4),以及 Tone 功能所需的BSP_USING_TIM7; - ADC:
BSP_USING_ADC1(覆盖 A0–A3 共 4 路模拟输入); - DAC:
BSP_USING_DAC1(覆盖 DAC0 真模拟输出); - SPI:
BSP_USING_SPI2(WIRELESS 用户插槽),并默认开启BSP_SPI2_TX_USING_DMA/BSP_SPI2_RX_USING_DMA; - 软件 I2C:
BSP_USING_SOFT_I2C与RT_USING_SOFT_I2C1(PC7-SDA / PC6-SCL 用户 I2C); - RTduino 自身的 Wire/SPI 支持:
RTDUINO_USING_WIRE、RTDUINO_USING_SPI,并隐含RTDUINO_USING_SERVO。
从源码结构可以看出,这些依赖关系保证了"勾选一个选项、整套硬件就绪"的零配置体验。
1.2 Arduino 程序的入口
开启 RTduino 后,用户程序入口从原生 applications/main.c(默认的rt_pin_mode点灯示例)切换为 Arduino 风格的 applications/arduino_main.cpp,其结构完全遵循 Arduino 标准:
#include <Arduino.h> void setup(void) { /* put your setup code here, to run once: */ pinMode(LED_BUILTIN, OUTPUT); } void loop(void) { /* put your main code here, to run repeatedly: */ digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); delay(100); }默认例程让板载 LED(LED_BUILTIN,即 D22 绿色 LED)以 100ms 周期闪烁,可作为验证兼容层是否正常工作的最快途径。
2 Arduino 引脚排布统览
该 BSP 遵照 Arduino UNO 板的引脚排列方式,并扩展增加了潘多拉自身的板载资源功能引脚。完整的映射关系定义在 pins_arduino.c 与 pins_arduino.h 中。
2.1 Arduino 数字/模拟引脚与 STM32 引脚映射表
| Arduino 引脚编号 | STM32 引脚编号 | 5V 容忍 | 备注 |
|---|---|---|---|
| 0 (D0) | PA10 | 是 | Serial-Rx,被 RT-Thread 的 UART 设备框架 uart1 接管 |
| 1 (D1) | PA9 | 是 | Serial-Tx,被 RT-Thread 的 UART 设备框架 uart1 接管 |
| 2 (D2) | PB9 | 是 | 普通 IO |
| 3 (D3) | PD15 | 是 | PWM4-CH4,默认被 RT-Thread 的 PWM 设备框架 pwm4 接管 |
| 4 (D4) | PA8 | 是 | 普通 IO |
| 5 (D5) | PD14 | 是 | 普通 IO |
| 6 (D6) | PB11 | 是 | PWM2-CH4,默认被 RT-Thread 的 PWM 设备框架 pwm2 接管 |
| 7 (D7) | PB14 | 是 | 普通 IO |
| 8 (D8) | PB12 | 是 | 普通 IO |
| 9 (D9) | PD12 | 是 | PWM4-CH1,默认被 RT-Thread 的 PWM 设备框架 pwm4 接管 |
| 10 (D10) | PB10 | 是 | PWM2-CH3,默认被 RT-Thread 的 PWM 设备框架 pwm2 接管 |
| 11 (D11) | PB8 | 是 | PWM4-CH3,默认被 RT-Thread 的 PWM 设备框架 pwm4 接管 |
| 12 (D12) | PB15 | 是 | 普通 IO |
| 13 (D13) | PB13 | 是 | 普通 IO |
| 14 (D14) | PA1 | 是 | 振动电机-A |
| 15 (D15) | PA0 | 是 | 振动电机-B |
| 16 (D16) | PB2 | 是 | 蜂鸣器 |
| 17 (D17) | PD10 | 是 | KEY0 |
| 18 (D18) | PD9 | 是 | KEY1 |
| 19 (D19) | PD8 | 是 | KEY2 |
| 20 (D20) | PC13 | 是 | KEY-WKUP |
| 21 (D21) | PE7 | 是 | 用户红色 LED |
| 22 (D22, LED_BUILTIN) | PE8 | 是 | 用户绿色 LED |
| 23 (D23) | PE9 | 是 | 用户蓝色 LED,PWM1-CH1,默认被 RT-Thread 的 PWM 设备框架 pwm1 接管 |
| 24 (D24) | PB0 | 3.6V 容忍 | 红外发送 |
| 25 (D25) | PB1 | 是 | 红外接收 |
| 26 (D26) | PD4 | 是 | 无线模块 CE |
| 27 (D27) | PD3 | 是 | 无线模块 中断 |
| 28 (D28, SS) | PD5 | 是 | 无线模块 片选 CS |
| 29 (D29) | PB13 | SPI2-SCK,默认被 RT-Thread 的 SPI 设备框架 spi2 总线接管 | |
| 30 (D30) | PB14 | SPI2-MISO,默认被 RT-Thread 的 SPI 设备框架 spi2 总线接管 | |
| 31 (D31) | PB15 | SPI2-MOSI,默认被 RT-Thread 的 SPI 设备框架 spi2 总线接管 | |
| 32 (D32) | PC7 | 是 | I2C1-SDA,默认被 RT-Thread 的 I2C 设备框架 i2c1 总线接管 |
| 33 (D33) | PC6 | 是 | I2C1-SCL,默认被 RT-Thread 的 I2C 设备框架 i2c1 总线接管 |
| 34 (D34) | PA2 | Serial2-Tx,默认被 RT-Thread 的 UART 设备框架 uart2 接管 | |
| 35 (D35) | PA3 | Serial2-Rx,默认被 RT-Thread 的 UART 设备框架 uart2 接管 | |
| 36 (D36) | PD7 | 是 | LCD 片选 CS |
| 37 (D37) | PB6 | 是 | LCD 复位 RESET |
| 38 (D38) | PB4 | 是 | LCD D/C 数据命令选择,即 RW 读写选择 |
| 39 (D39) | PB7 | 是 | LCD 背光电源,PWM4-CH2,默认被 RT-Thread 的 PWM 设备框架 pwm4 接管 |
| A0 | PC2 | 是(但不建议) | ADC1-CH3,默认被 RT-Thread 的 ADC 设备框架 adc1 接管 |
| A1 | PC4 | 是(但不建议) | ADC1-CH13,默认被 RT-Thread 的 ADC 设备框架 adc1 接管 |
| A2 | -- | 芯片内部参考电压 ADC1-CH0,默认被 RT-Thread 的 ADC 设备框架 adc1 接管 | |
| A3 | -- | 芯片内部温度 ADC1-CH17,默认被 RT-Thread 的 ADC 设备框架 adc1 接管 | |
| DAC0 | PA4 | 3.6V 容忍 | 真模拟输出 DAC1-CH1,默认被 RT-Thread 的 DAC 设备框架 dac1 接管 |
注意:
- 驱动舵机和
analogWrite函数要选择不同定时器发生的 PWM 信号引脚。由于 STM32 的定时器 4 个通道需要保持相同的频率,如果采用相同的定时器发生的 PWM 分别驱动舵机和analogWrite,可能会导致舵机失效。
2.2 引脚映射的源码实现
上述表格并非注释文档,而是直接由 pins_arduino.c 中的pin_map_table[]数组定义并驱动 RTduino 运行时工作的。该数组每行按{Arduino Pin, RT-Thread Pin [, Device Name, Channel]}格式组织,其中方括号内为可选字段:
const pin_map_t pin_map_table[] = { { D0, GET_PIN(A, 10), "uart1" }, /* Serial-Rx */ { D1, GET_PIN(A, 9), "uart1" }, /* Serial-Tx */ { D2, GET_PIN(B, 9) }, { D3, GET_PIN(D, 15), "pwm4", 4 }, /* PWM */ ... { A0, GET_PIN(C, 2), "adc1", 3 }, /* ADC */ { A1, GET_PIN(C, 4), "adc1", 13 }, /* ADC */ { A2, RT_NULL, "adc1", RT_ADC_INTERN_CH_VREF }, /* On-Chip: internal reference voltage */ { A3, RT_NULL, "adc1", RT_ADC_INTERN_CH_TEMPER }, /* On-Chip: internal temperature sensor */ { DAC0, GET_PIN(A, 4), "dac1", 1 }, /* DAC */ };关键约定:
- 数字引脚(Digital pins)必须不给出设备名和通道,否则会被误判为复用功能;
- 模拟引脚(Analog pins)必须给出设备名和通道(ADC、PWM 或 DAC 三者之一);
- Arduino 引脚编号必须按顺序排列(从源码注释可以确认这是一条硬性约束),便于 RTduino 通过数组下标直接索引;
- A2、A3 对应的
GET_PIN字段为RT_NULL,因为它们是芯片内部通道(参考电压、温度传感器),没有物理引脚,直接由adc1设备的内部通道号RT_ADC_INTERN_CH_VREF、RT_ADC_INTERN_CH_TEMPER驱动。
而在 pins_arduino.h 中,所有引脚编号被定义为从 0 开始的连续宏,且RTDUINO_PIN_MAX_LIMIT被设定为DAC0,作为引脚编号的上限校验依据:
#define D0 (0) ... #define D39 (39) #define A0 (40) #define A1 (41) #define A2 (42) #define A3 (43) #define DAC0 (44) #define RTDUINO_PIN_MAX_LIMIT DAC0 /* pin number max limit check */ #define F_CPU 80000000L /* CPU:80MHz */ #define LED_BUILTIN D22 /* Default Built-in LED */F_CPU被定义为 80MHz,与 STM32L475 在该 BSP 下的系统主频一致,供依赖延时计算的 Arduino 库使用;LED_BUILTIN指向 D22(绿色 LED),因此 Arduino 例程中的LED_BUILTIN无需任何配置即可直接点亮板载绿灯。
3 板载排针的 Arduino 引脚排布
潘多拉开发板两侧排针的物理排布如下(左右两列同时列出,便于对照焊接/接线):
| STM32 引脚编号 | Arduino 引脚编号 | 备注 | STM32 引脚编号 | Arduino 引脚编号 | 备注 |
|---|---|---|---|---|---|
| PB8 | 11 (D11) | PWM | PB9 | 2 (D2) | 普通 IO |
| PC7 | A4 | I2C1-SDA | PA8 | 4 (D4) | 普通 IO |
| PD15 | 3 (D3) | PWM | PC6 | A5 | I2C1-SCL |
| PD13 | -- | -- | PD14 | 5 (D5) | 普通 IO |
| PC2 | A0 | ADC | PD12 | 9 (D9) | PWM |
| PB14 | 7 (D7) | 普通 IO | PB15 | 12 (D12) | 普通 IO |
| PB12 | 8 (D8) | 普通 IO | PB13 | 13 (D13) | 普通 IO |
| PB10 | 10 (D10) | PWM | PB11 | 6 (D6) | PWM |
| PC4 | A1 | ADC | PA4 | DAC0 | DAC |
需要说明的是,上表中 A4/A5 是 Arduino UNO 排针布局习惯上 I2C 所在的位置,在本 BSP 中 A4 对应 PC7(I2C SDA)、A5 对应 PC6(I2C SCL),与 2.1 节中 D32/D33 的映射保持一致;PD13 未分配 Arduino 功能(--)。
4 板载外设的 Arduino 引脚排布
潘多拉板载外设全部映射为 Arduino 引脚,可直接用 Arduino API 操作:
| 外设名称 | Arduino 引脚编号 | STM32 引脚编号 |
|---|---|---|
| 振动电机-A | 14 (D14) | PA1 |
| 振动电机-B | 15 (D15) | PA0 |
| 蜂鸣器 | 16 (D16) | PB2 |
| KEY0 | 17 (D17) | PD10 |
| KEY1 | 18 (D18) | PD9 |
| KEY2 | 19 (D19) | PD8 |
| KEY-WKUP | 20 (D20) | PC13 |
| 红 LED | 21 (D21) | PE7 |
| 绿 LED,Arduino 默认 LED | 22 (D22, LED_BUILTIN) | PE8 |
| 蓝 LED,具有 PWM 功能 | 23 (D23) | PE9 |
| 红外发射 | 24 (D24) | PB0 |
| 红外接收 | 25 (D25) | PB1 |
在 pins_arduino.c 中,这些外设同样以普通数字引脚注册(如{ D14, GET_PIN(A, 1) } /* BSP: MOTOR-A */、{ D16, GET_PIN(B, 2) } /* BSP: BEEP */、{ D21, GET_PIN(E, 7) } /* BSP: RED-LED */),因此digitalWrite(D14, HIGH)即可直接启动振动电机,digitalWrite(D16, HIGH)即可驱动蜂鸣器,digitalRead(D17)即可读取 KEY0 状态,无需关心底层 GPIO 号。
5 通信接口
5.1 I2C 总线
潘多拉 BSP 为 Arduino 提供三条 I2C 总线,均可通过#include <Wire.h>(Arduino 官方 I2C 头文件)直接使用,因为引脚已被 RT-Thread I2C 设备框架接管,无需直接操控引脚电平:
- 用户总线(swi2c1):PC7 为 SDA、PC6 为 SCL,用户可以通过杜邦线连接其他 I2C 传感器/芯片;
- 板载外设总线(swi2c3):连接板载 ICM20608(陀螺仪和加速度传感器)和 AP3216C(距离和光亮度传感器)芯片;
- 板载外设总线(swi2c4):连接板载 AHT10(温湿度传感器)芯片。
默认总线由 pins_arduino.h 中的RTDUINO_DEFAULT_IIC_BUS_NAME宏决定,并且会根据你在 menuconfig 中使能的传感器库自动切换:
#if defined(BSP_USING_ARDUINO_AHT10) #define RTDUINO_DEFAULT_IIC_BUS_NAME "swi2c4" /* swi2c4 - AHT10 (On Board) */ #elif defined(BSP_USING_ARDUINO_AP3216) || defined(BSP_USING_ARDUINO_ICM20608) #define RTDUINO_DEFAULT_IIC_BUS_NAME "swi2c3" /* swi2c3 - ICM20608, AP3216C (On Board) */ #else #define RTDUINO_DEFAULT_IIC_BUS_NAME "swi2c1" /* swi2c1 - PC7-SDA PC6-SCL (User I2C) */ #endif也就是说:使能 AHT10 库时默认总线为 swi2c4,使能 AP3216 或 ICM20608 库时默认总线为 swi2c3,都不使能时默认总线为用户可自由接线的 swi2c1。这三条均为 RT-Thread 软件 I2C(swi2c)总线,其默认引脚可在 board/Kconfig 中查到:swi2c1 的 SCL 为引脚 38(对应 PC6)、SDA 为引脚 39(对应 PC7);swi2c3 的 SCL 为 32、SDA 为 33;swi2c4 的 SCL 为 54、SDA 为 33。
5.2 SPI 总线
潘多拉板的 Arduino SPI 总线是spi2 总线,位置为板上左上角的WIRELESS插槽。SCK(PB13)、MISO(PB14)、MOSI(PB15)引脚均被 RT-Thread SPI 设备框架接管,无需直接操控,直接引用#include <SPI.h>(Arduino 官方 SPI 头文件)即可使用。按照 Arduino 的编程标准,用户需要自行控制片选信号,默认为SS,即D28(PD5,无线模块片选 CS)。
当通过 board/Kconfig 使能BSP_USING_ARDUINO_ST7789(板载 LCD 的 Arduino 库)时,默认 SPI 总线会切换为 spi3 并重新定义片选,这一点在 pins_arduino.h 中通过条件编译实现:
#if defined(BSP_USING_ARDUINO_ST7789) #define SS D36 /* LCD-SPI-CS PD7 */ #define RTDUINO_DEFAULT_SPI_BUS_NAME "spi3" /* LCD SPI Bus */ #else /* spi2 - PB13-SCK PB14-MISO PB15-MOSI */ #define SS D28 /* Chip select pin of default spi */ #define RTDUINO_DEFAULT_SPI_BUS_NAME "spi2" #endifLCD 模式下的引脚约定(见头文件注释):LCD-SPI-SDA 为 PB5、LCD-SPI-SCK 为 PB3、LCD-SPI-CS 为 PD7、LCD-POWER 为 PB7、LCD-RESET 为 PB6、LCD-WR/DC 为 PB4,并会启用BSP_USING_PWM4_CH2用于背光控制。
5.3 串口
默认支持通过Serial.方法调用uart1串口设备(对应 D0/D1,PA10/PA9,即板载 ST-Link 转串口);通过Serial2.方法调用uart2串口设备(对应 D34/D35,PA2/PA3)。设备名与引脚的对应关系可以在 pins_arduino.h 中找到:
/* Serial2 - PA2-TX PA3-RX */ #define RTDUINO_SERIAL2_DEVICE_NAME "uart2"配合 board/Kconfig 中 uart1/uart2 的BSP_UARTx_RX_BUFSIZE(默认 256)、BSP_UARTx_TX_BUFSIZE(默认 0)等可调参数,串口缓冲可以在 menuconfig 中按需调整。
5.4 USB 虚拟串口
本 BSP 还支持 USB 虚拟串口,但默认关闭,需要手动使能:
RT-Thread online packages ---> Arduino libraries ---> [*] RTduino: Arduino Ecological Compatibility Layer [*] Enable USB Serial使能后即可像普通串口一样通过 Arduino 的 Serial 类与上位机通信。
6 特殊功能说明
6.1 芯片内部 ADC 通道
本 BSP 适配了 STM32 的两个芯片内部 ADC 通道,可以通过analogRead函数直接读取,无需外接任何引脚:
| 特殊功能 | Arduino 引脚编号 | STM32 引脚编号 |
|---|---|---|
| 芯片内部参考电压 ADC | A2 | -- |
| 芯片内部温度 ADC | A3 | -- |
在 pins_arduino.c 中,A2/A3 通过RT_ADC_INTERN_CH_VREF与RT_ADC_INTERN_CH_TEMPER两个内部通道号映射到adc1设备。典型用法:
uint16_t vref = analogRead(A2); /* 读取芯片内部参考电压 */ uint16_t temp = analogRead(A3); /* 读取芯片内部温度 */6.2 真模拟输出功能(True Analog Output)
Arduino 的analogWrite函数虽名为"模拟写",但早期 AVR 平台实际输出的是 PWM 数字信号而非真正的模拟信号——这是 Arduino 历史上沿用下来的习惯。随着支持芯片的丰富,部分高级芯片已内建 DAC(如 Arduino 官方板 MKR、Zero 等),Arduino 的analogWrite函数因此也支持了真模拟输出功能。
| 特殊功能 | Arduino 引脚编号 | STM32 引脚编号 |
|---|---|---|
| 真模拟输出 (True Analog Output) | DAC0 | PA4 |
在潘多拉板上,使用 PA4 作为真模拟输出功能引脚(dac1设备通道 1),使用方法为:
analogWrite(DAC0, 128);写入值范围为 0–255(与 PWM 风格analogWrite保持一致的取值范围,由 RTduino 换算为 DAC 的实际分辨率)。PA4 标注为 3.6V 容忍,注意不要施加超过该阈值的电压。
7 实战要点小结
- 开启方式:
Hardware Drivers Config → Onboard Peripheral Drivers → Compatible with Arduino Ecosystem (RTduino),依赖驱动自动使能; - 默认 LED:
LED_BUILTIN即 D22(PE8 绿色 LED),直接可点; - PWM 引脚:D3/D9/D11/D39 走 pwm4、D6/D10 走 pwm2、D23 走 pwm1;驱动舵机与
analogWrite务必选择不同定时器的 PWM 引脚,避免因同一定时器各通道同频导致舵机失效; - ADC 引脚:A0(PC2)、A1(PC4)为外部模拟输入,A2/A3 为芯片内部参考电压与温度通道;
- DAC 引脚:DAC0(PA4)支持真模拟输出,
analogWrite(DAC0, 128)即可产生真实模拟电压; - 通信总线:Wire 默认挂 swi2c1/swi2c3/swi2c4(随使能传感器库自动切换),SPI 默认挂 spi2(SS=D28),Serial 对应 uart1、Serial2 对应 uart2。
所有引脚映射、默认总线和设备名均以 pins_arduino.c 与 pins_arduino.h 为最终依据,若需自定义映射或新增板载外设,可在这两个文件中按pin_map_table[]的格式扩展,并通过 SConscript 与 board/Kconfig 纳入构建与配置体系。
- 操作系统
- 嵌入式
- 物联网
- 嵌入式OS
- RTOS
【免费下载链接】rt-thread
RT-Thread is an open source IoT Real-Time Operating System (RTOS). https://rt-thread.github.io/rt-thread/
相关推荐
RT-Thread 与 Arduino 生态兼容:STM32F411 WeAct BlackPill 开发板 RTduino 适配与引脚排布全指南
RT Thread 与 Arduino 生态兼容:STM32F411 WeAct BlackPill 开发板 RTduino 适配与引脚排布全指南 导读 本文面
操作系统嵌入式物联网嵌入式OSRTOSSTM32U575-NUCLEO 开发板 RTduino Arduino 生态兼容层:开启配置与引脚排布完全解析(RT-Thread)
STM32U575 NUCLEO 开发板 RTduino Arduino 生态兼容层:开启配置与引脚排布完全解析(RT Thread) 本文围绕 RT Thre
操作系统嵌入式物联网嵌入式OSRTOSRT-Thread 的 PSoC6 Evaluation Kit 062S2 开发板 Arduino 生态兼容指南:RTduino 引脚排布与配置实战
RT Thread 的 PSoC6 Evaluation Kit 062S2 开发板 Arduino 生态兼容指南:RTduino 引脚排布与配置实战 导读 本
操作系统嵌入式物联网嵌入式OSRTOS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考