RIOT 平台 SenseBox MCU(SAMD21)开发板支持指南:烧录、UART、I2C 与 XBEE 外设详解
【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT
SenseBox 是一套面向固定式与移动式环境传感器站的 DIY 套件,其核心控制板基于 Atmel SAMD21G18A 微控制器。本文以 RIOT 操作系统在boards/sensebox_samd21目录下的板级支持(Board Support Package,BSP)为主线,完整讲解该开发板的烧录流程、STDIO 串口访问、I2C 与 XBEE1/XBEE2 扩展口的使用与使能控制,并结合板级源码(board.c、include/board.h、include/periph_conf.h等)剖析时钟、外设映射、SPI 复位时序与硬件限制。读完本文,你将能够独立完成该板的固件烧录、串口调试,并为 LoRa 模块、SD 卡、温湿度/光照/气压传感器等外设完成正确接线与配置。
板级概览:从 SenseBox 到 SAMD21G18A
SenseBox(sensebox.de 与@ref cpu_samd21)。
在 RIOT 中,该板卡的支持代码位于 boards/sensebox_samd21,由 Makefile.features 声明其能力:
CPU = samd21 CPU_MODEL = samd21g18a FEATURES_PROVIDED += periph_adc FEATURES_PROVIDED += periph_i2c FEATURES_PROVIDED += periph_rtc FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_spi FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_usbdev FEATURES_PROVIDED += highlevel_stdio FEATURES_PROVIDED += sdcard_spi可以看到,该板默认提供 ADC、I2C、RTC、RTT、SPI、定时器、UART、USB 设备以及sdcard_spi能力,并支持highlevel_stdio(高级串行 IO,即通过 USB CDC 提供标准输入输出)。
板上的基础硬件资源在 include/board.h 中定义:
- LED0(红色,PA27)与LED1(绿色,PA28),并配套
LED0_ON/OFF/TOGGLE、LED1_ON/OFF/TOGGLE寄存器级操作宏; - 按键 BTN0(PA20),配置为上拉输入
GPIO_IN_PU; - XBEE1(PB3 使能,PA18 CS,PA21 INT)与XBEE2(PB10 使能,PA14 CS,PA15 INT)两个 XBEE 兼容扩展口;
- I2C 总线使能引脚(PB11);
- 板载HDC1000(0x40)温湿度传感器、TSL2561(
TSL2561_ADDR_LOW)光照传感器、BMP280(0x76)气压温度传感器的默认 I2C 地址。
这些 GPIO 还通过 include/gpio_params.h 注册为 SAUL 设备(saul_default模块启用时自动生效):LED(Red)、LED(Green)与BTN,从而可直接被 SAUL 生态的命令行工具读写。
烧录固件:进入 Bootloader 与 BOSSA 流程
SenseBox MCU 板在出厂时预烧录了 Arduino 兼容的引导程序(bootloader),RIOT 借助samdx1-arduino-bootloader公共目录(见 boards/common/samdx1-arduino-bootloader)支持通过 USB 直接烧录,无需外部调试器。
烧录步骤如下:
- 进入 Bootloader 模式:快速双击(double tap)复位按钮。当板卡进入 bootloader 模式时,红色用户 LED 会平滑地明暗振荡(oscillates smoothly),以此作为进入状态的视觉提示。
- 使用
make命令并指定板卡:以hello-world示例为例:
make BOARD=sensebox_samd21 -C examples/basic/hello-world flash在 Makefile.include 中可以找到该烧录流程的实现细节:
- 默认烧录器(programmer)为BOSSA(
PROGRAMMER ?= bossa),用于配合预烧录的 Arduino bootloader; - 由于 bootloader 占用了一段 flash,烧录时通过
ROM_OFFSET ?= 0x2000跳过前 0x2000 字节(8 KiB)空间,避免覆盖引导程序; - 若通过 SWD 引脚外接 J-Link,也可使用
JLINK_DEVICE = atsamd21以普通 CPU 内存模型调试; - 相关定义由 boards/common/samdx1-arduino-bootloader/Makefile.include 与 makefiles/boards/sam0.inc.mk 统一提供。
通过 USB 访问 STDIO(UART 重定向)
RIOT 的 STDIO 在该板上直接经由 USB 端口提供,即插上 USB 线后,即可在宿主机上打开串口终端与设备交互,无需额外转接芯片。
打开终端时,可通过TERM_DELAY环境变量在打开串口前插入一段延迟(单位:秒),用于等待串口设备稳定就绪。默认值为 2 秒,足以应对大多数情况:
TERM_DELAY=5 make BOARD=sensebox_samd21 -C examples/basic/hello-world term从 include/periph_conf.h 的 UART 配置可以看到,板上共有两个硬件 UART 实例:UART_0使用 SERCOM3(RX=PA23,TX=PA22,GPIO_MUX_C),UART_1使用 SERCOM4(RX=PB9,TX=PB8,GPIO_MUX_D)。其中 SERCOM3 所对应的 USB CDC 路径即承载了默认 STDIO。需要说明的是,文档所述“STDIO 直接可用”依赖highlevel_stdio特性与 USB CDC ACM 的自动初始化,具体由 sys/stdio_cdc_acm 等模块实现。
I2C 总线:默认使能、按需开关与板载传感器
板载 I2C 总线默认处于使能状态。其使能引脚为 PB11(定义于 include/board.h),对应两个宏:
I2C_DISABLE:关闭 I2C 总线供电/使能(将 PB11 置低);I2C_ENABLE:重新使能 I2C 总线(将 PB11 置高)。
宏的寄存器级实现为:
#define I2C_ENABLE (I2C_EN_PORT.OUTSET.reg = I2C_EN_MASK) #define I2C_DISABLE (I2C_EN_PORT.OUTCLR.reg = I2C_EN_MASK)在board_init()(见 board.c)中,I2C 使能引脚会被初始化为输出并默认使能:
/* initialize I2C bus enable pin */ gpio_init(I2C_EN_PIN, I2C_EN_MODE); /* enable I2C bus */ I2C_ENABLE;从 include/periph_conf.h 看,I2C 外设共有两个实例:I2C_0(SERCOM0,SCL=PA8,SDA=PA9)与I2C_1(SERCOM2,SCL=PA12,SDA=PA13),均运行于I2C_SPEED_NORMAL标准速率,时钟源为SAM0_GCLK_MAIN。
该板出厂即面向环境监测场景,板载传感器的默认 I2C 地址已在 include/board.h 中给出,可直接配合对应驱动模块(hdc1000、tsl2561、bmp280/bmx280)使用:
| 传感器 | 功能 | 默认地址/参数 |
|---|---|---|
| HDC1000 | 温度与湿度 | HDC1000_PARAM_ADDR = 0x40 |
| TSL2561 | 可见光强度 | TSL2561_PARAM_ADDR = TSL2561_ADDR_LOW |
| BMP280 | 气压与温度 | BMX280_PARAM_I2C_ADDR = 0x76 |
XBEE1 / XBEE2 扩展口:使能控制、SPI 复位延迟与引脚映射
XBEE1 与 XBEE2 两个扩展口(用于挂接 LoRa Bee、mSD-Bee 等模块)同样默认使能:
- 关闭 XBEE1:
XBEE1_DISABLE(PB3 置高);重新使能:XBEE1_ENABLE(PB3 置低); - 关闭 XBEE2:
XBEE2_DISABLE(PB10 置高);重新使能:XBEE2_ENABLE(PB10 置低)。
注意 XBEE 的使能逻辑与 I2C 相反:XBEEn_ENABLE将使能引脚清低(OUTCLR),XBEEn_DISABLE将使其置高(OUTSET);而 I2C 的I2C_ENABLE使用OUTSET置高。接线或二次开发时需留意各总线的有效电平极性。
各扩展口的引脚定义(include/board.h):
| 信号 | XBEE1 | XBEE2 |
|---|---|---|
| 使能引脚 | PB3 | PB10 |
| 片选 CS | PA18 | PA14 |
| 中断 INT | PA21 | PA15 |
| SPI 时钟 | PA17 | PA17 |
| SPI MOSI | PA16 | PA16 |
| SPI MISO | PA19 | PA19 |
300ms 的 SPI 复位延迟
板上为 XBEE 扩展口设计了一个复位电路:复位信号相对使能信号被延迟约 300ms。这意味着使能引脚拉高后,插在扩展口上的 SPI 设备需要一小段时间才能完成复位上电。
为此,board_init()在完成 XBEE1、XBEE2、I2C 三条总线的使能后,插入了一段约 300 万次 NOP 的忙等待(WAIT_FOR_SPI_RESET = 3000000UL,见 board.c):
/* delay for SPI reset. Read README.md for more information. */ for (unsigned i = 0; i < WAIT_FOR_SPI_RESET; i++) { __asm__("nop"); }这样,任何连接在扩展口上的 SPI 设备都能在系统初始化阶段完成复位,避免后续 SPI 通信因设备未就绪而失败。
挂载 LoRa 模块:SX127X 配置(XBEE1)
SX127X 系列 LoRa 无线模块的引脚配置在 include/board.h 中预设为连接在XBEE1口上:
#define SX127X_PARAM_SPI (SPI_DEV(0)) #define SX127X_PARAM_SPI_NSS XBEE1_CS_PIN /* D23 */ #define SX127X_PARAM_RESET GPIO_UNDEF #define SX127X_PARAM_DIO0 XBEE1_INT_PIN /* D24 */ #define SX127X_PARAM_DIO1 GPIO_UNDEF #define SX127X_PARAM_DIO2 GPIO_UNDEF #define SX127X_PARAM_DIO3 GPIO_UNDEF #define SX127X_PARAM_PASELECT (SX127X_PA_BOOST)其中射频功放选择SX127X_PA_BOOST(PA_BOOST 模式,常用于大功率发射)。若你的接线方案不同,需要直接修改该文件中的相应宏定义。
挂载 SD 卡:mSD-Bee 配置(XBEE2)
mSD-Bee 模块(micro SD 卡)的引脚配置位于 include/sdcard_spi_params.h,默认假定其连接在XBEE2口上:
#define CARD_DETECT_PIN (XBEE2_INT_PIN) static const sdcard_spi_params_t sdcard_spi_params[] = { { .spi_dev = SPI_DEV(0), .cs = XBEE2_CS_PIN, .clk = GPIO_PIN(PA, 17), .mosi = GPIO_PIN(PA, 16), .miso = GPIO_PIN(PA, 19), .power = GPIO_UNDEF, .power_act_high = true }, };SD 卡的卡检测(card detect)信号复用了 XBEE2 的中断引脚 PA15。若采用不同接线,需要修改此文件。
在模块依赖层面(Makefile.dep),该板自动完成了 SD 卡与文件系统的联动:
# default to using fatfs on SD card ifneq (,$(filter vfs_default,$(USEMODULE))) USEMODULE += fatfs_vfs USEMODULE += mtd endif即启用vfs_default时,会自动挂上 FATFS 文件系统与 MTD 抽象层;而启用mtd时,会自动加入mtd_sdcard_default。板载 SD 卡对应的 MTD 设备 0 在 include/board.h 中声明为MTD_0(即mtd_dev_get(0)),其实例定义在board.c中。
时钟与外设配置细节
内核时钟:PLL 与内部振荡器两种方案
include/periph_conf.h 提供了两种内核时钟方案,由CLOCK_USE_PLL宏选择:
PLL 方案(默认):由内部 8MHz 振荡器经 8 分频后馈入 PLL,目标频率按公式计算:
CORECLOCK = ((PLL_MUL + 1) * 1MHz) / PLL_DIV默认
CLOCK_PLL_MUL = 47、CLOCK_PLL_DIV = 1,即CORECLOCK = 48MHz。该方案频率范围更宽、时钟更稳定、抖动更小。注意 PLL 电路要求工作在 32MHz 至 96MHz 之间,因此PLL_MUL必须在31~95之间。内部振荡器直通方案:直接使用 8MHz 内部振荡器(可再分频),频率计算为
CORECLOCK = 8MHz / CLOCK_DIV。该方案功耗略优但时钟稳定性较差,且核心频率低于 1MHz 不被推荐,仅建议在明确知道影响时使用。
其他外设映射速览
- 定时器:
timer_config[]定义了两个 TC 定时器实例(TC3 用于系统时钟,TC4/TC5 为 32 位计数器),时钟源在 PLL 方案下为SAM0_GCLK_1MHZ; - SPI:唯一 SPI 实例
SPI_DEV(0)基于 SERCOM1(MISO=PA19、MOSI=PA16、SCK=PA17),启用periph_dma模块时还会注册 DMA 触发通道; - ADC:板载 6 个 ADC 通道,映射到数字引脚 1~6(PA04/PA05/PA06/PA07/PA03/PA02),默认 1x 增益、内部 1V 参考、512 分频;
- USB:
sam_usbdev_config[]配置了 USB D-/D+ 引脚(PA24/PA25),这是板上 STDIO 与 BOSSA 烧录的物理基础; - RTT:默认频率 32768Hz,如需修改需同步参考
rtc_rtt.c的时钟配置。
已知限制:XBEE 中断引脚的 OR 门复用
XBEE 扩展头只有一个中断引脚。这意味着 LoRa Bee 模块的 DIO0 与 DIO1 中断信号在板上经过一个OR 门合路后接入唯一的中断引脚(XBEE1 为 PA21,XBEE2 为 PA15)。这在 include/board.h 的 SX127X 配置注释中有直接说明:驱动在 ISR 中会检查中断类型,因此仅需配置 DIO0 引脚即可同时处理 DIO0 与 DIO1 事件。
该硬件设计带来以下限制:
- FSK 模式不可用:SX127X 的 FSK 模式依赖对 DIO1 等独立中断的精确区分,OR 门合路后无法可靠支持;
- 中断引脚配置需谨慎:由于 DIO0 与 DIO1 可能被配置为不同的中断类型/模式,修改中断配置时必须充分理解合路后的行为,避免中断丢失或误触发。
小结
SenseBox MCU(SAMD21)在 RIOT 中的板级支持覆盖了从烧录到外设使用的完整链路:双击复位进入 bootloader 后即可通过 BOSSA 经 USB 烧录;STDIO 直接走 USB CDC 串口;I2C、XBEE1、XBEE2 三条总线默认使能并可通过*_ENABLE/*_DISABLE宏控制;SX127X LoRa 与 mSD-Bee SD 卡分别预设接在 XBEE1 与 XBEE2 口上,相关引脚与参数集中在 include/board.h 与 include/sdcard_spi_params.h 中,便于按实际接线调整。唯一需要特别留意的是 XBEE 中断引脚的 OR 门复用带来的 FSK 模式与中断配置限制。以此为起点,你可以参考 examples/basic/hello-world 验证烧录链路,再结合hdc1000、tsl2561、bmp280、sx127x、sdcard_spi等驱动模块逐步构建完整的环境监测节点。
【免费下载链接】RIOTRIOT - The friendly OS for IoT项目地址: https://gitcode.com/GitHub_Trending/riot/RIOT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考