4、嵌入式系统基础:微控制器(MCU)架构、外设接口(GPIO、SPI、I2C、UART)、传感器数据采集与处理
在边缘AI与TinyML的工程实践中,绝大多数推理任务并非运行在手机或树莓派上,而是运行在功耗受限、资源受限的微控制器(MCU)中。理解MCU的哈佛架构与冯·诺依曼架构差异、存储映射、时钟树、中断系统,以及GPIO、SPI、I2C、UART等外设接口的电气特性与通信时序,是完成传感器数据采集、预处理和模型输入张量构建的前提。本章将从芯片内部结构出发,逐步拆解外设通信机制,并给出传感器数据采集与信号调理的完整工程链路。
4.1 微控制器(MCU)核心架构与存储映射
MCU 是 TinyML 推理的物理载体,其架构决定了模型参数存储方式、数据搬运路径和计算吞吐上限。当前主流边缘 AI 设备多采用 ARM Cortex-M 系列内核(如 M0+、M4、M7、M33),这些内核采用哈佛架构或改进型哈佛架构,即指令总线与数据总线物理分离,允许 CPU 在同一时钟周期内同时取指和读写数据,显著提升流水线效率。以 STM32F4 系列为例,其内部结构可划分为四个主要域:内核域(CPU、FPU、NVIC、调试接口)、存储域(Flash、SRAM、OTP)、外设域(GPIO、SPI、I2C、UART、ADC、定时器等)以及总线矩阵(AHB、APB1、APB2)。
存储映射是嵌入式开发的基础认知。ARM Cortex-M 采用统一编址方式,4GB 地址空间被划分为多个区域:0x00000000-0x1FFFFFFF 为代码区(Flash),0x20000000-0x3FFFFFFF 为 SRAM 区,0x40000000-0x5FFFFFFF 为外设区,0xE0000000-0xFFFFFFFF 为系统控制空间(包含 NVIC、SysTick、FPU 寄存器)。在 TinyML 部署中,模型权重通常存放在 Flash 中(如 256KB-2MB),推理时的中间张量、激活值则存放在 SRAM 中(如 128KB-512KB)。由于 SRAM 容量远小于 Flash,内存规划成为模型部署的关键约束——例如 TensorFlow Lite Micro 的 arena 大小设置必须精确匹配模型峰值内存需求。
4.2 外设接口:GPIO、SPI、I2C、UART 的工程应用
外设接口是 MCU 与传感器、执行器通信的物理通道。每种接口在速率、引脚数、拓扑结构、抗干扰能力上各有优劣,选型需根据传感器输出类型、采样率、传输距离和功耗要求综合决定。
| 接口 | 信号线 | 速率范围 | 拓扑 | 典型传感器 | TinyML 场景 |
|---|---|---|---|---|---|
| GPIO | 1 根(数字输入/输出) | 最高 ~50MHz(翻转率) | 点对点 | 按键、LED、中断引脚 | 触发信号、唤醒源、状态指示 |
| UART | TX、RX(+GND) | 9600bps - 4Mbps | 点对点 | GPS 模块、蓝牙模块 | 日志输出、与主机通信 |
| SPI | SCLK、MOSI、MISO、CS | 最高 ~40Mbps | 一主多从(片选) | Flash 存储、加速度计、显示屏 | 高速数据流、模型参数存储 |
| I2C | SCL、SDA(开漏+上拉) | 100kbps - 3.4Mbps | 多主多从(地址寻址) | 温湿度、气压计、IMU | 低速传感器配置与读取 |
4.2.1 GPIO:数字信号采集与事件触发
GPIO(通用输入输出)是最基础的外设,每个引脚可配置为输入、输出、复用功能或模拟模式。在 TinyML 场景中,GPIO 常用于读取数字传感器(如 PIR 人体红外传感器输出高/低电平)、检测外部中断(如运动传感器 INT 引脚唤醒 MCU)以及控制执行器(如 LED 指示推理结果)。GPIO 配置需注意:上拉/下拉电阻的选择(内部上拉通常 30-50kΩ,外部上拉可精确控制)、输出速度等级(低速 2MHz、中速 10MHz、高速 50MHz,高速率会增加 EMI)、以及中断触发方式(上升沿、下降沿、双边沿、低电平)。
// STM32 HAL 库 GPIO 外部中断配置示例
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发
GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
HAL_NVIC_SetPriority(EXTI0_IRQn, 2, 0); // 优先级分组
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
4.2.2 SPI:高速同步串行接口
SPI(串行外设接口)采用主从模式,由主机产生时钟信号 SCLK,通过 MOSI 发送数据、MISO 接收数据,CS 片选信号决定通信对象。SPI 的显著优势是速率高(可达 40Mbps 以上)且全双工,适合传输大量数据。在 TinyML 场景中,SPI 常用于:读取高采样率传感器(如 1kHz 以上的 9 轴 IMU)、连接外部 Flash 存储模型参数、驱动 TFT 显示屏显示推理结果。SPI 配置需关注时钟极性(CPOL)和时钟相位(CPHA),必须与从设备数据手册严格匹配,否则通信数据将完全错乱。
4.2.3 I2C:双线制多设备总线
I2C(Inter-Integrated Circuit)仅需 SCL(时钟)和 SDA(数据)两根线,通过 7 位或 10 位地址寻址,支持一总线上挂载多个设备。I2C 采用开漏输出+外部上拉电阻(典型 4.7kΩ),因此通信速率受限(标准模式 100kbps,快速模式 400kbps,高速模式 3.4Mbps)。在 TinyML 场景中,I2C 是连接低速环境传感器(温湿度 SHT30、气压 BMP280、光照 BH1750)的首选接口,因为这类传感器采样率低(1-10Hz),I2C 速率完全满足需求且节省引脚。I2C 通信需注意地址冲突(多个同型号传感器可通过 ADDR 引脚修改地址)、总线死锁(从设备拉低 SDA 不放,需主机发送 9 个时钟脉冲复位)以及电平匹配(1.8V 传感器与 3.3V MCU 需电平转换)。
// I2C 读取 SHT30 温湿度传感器(地址 0x44)示例
uint8_t cmd[2] = {0x2C, 0x06}; // 高精度测量命令
HAL_I2C_Master_Transmit(&hi2c1, 0x44<<1, cmd, 2, 100);
HAL_Delay(20); // 等待测量完成
uint8_t buf[6];
HAL_I2C_Master_Receive(&hi2c1, 0x44<<1, buf, 6, 100);
uint16_t temp_raw = (buf[0]<<8) | buf[1];
float temp = -45.0f + 175.0f * (temp_raw / 65535.0f);
4.2.4 UART:异步串行通信
UART(通用异步收发器)只需 TX 和 RX 两根线,通信双方需约定相同的波特率(每秒传输的比特数)。UART 是异步通信,没有时钟线,依靠起始位和停止位同步帧。在 TinyML 场景中,UART 主要用于:调试日志输出(printf 重定向)、与蓝牙/WiFi 模块通信(如 ESP32 透传推理结果)、与上位机进行模型参数交互。UART 配置需注意波特率误差(双方误差需小于 2%)、数据位/停止位/校验位匹配,以及流控(RTS/CTS 可选)。
4.3 传感器数据采集与信号处理链路
传感器数据采集是 TinyML 推理的输入源头,其质量直接影响模型准确率。完整的数据采集链路包括:传感器选型 → 接口配置 → 数据读取 → 信号调理 → 数据缓存 → 特征提取 → 模型输入张量构建。每个环节都有特定的工程陷阱。
4.3.1 信号调理与抗混叠滤波
对于模拟输出传感器(如麦克风、光电二极管),MCU 的 ADC 模块负责将连续模拟信号转换为离散数字值。ADC 采样率必须满足奈奎斯特采样定理(采样率 ≥ 2 倍信号最高频率),否则会产生混叠失真。例如,语音信号最高频率 4kHz,则采样率至少 8kHz,实际工程中通常取 16kHz。在 ADC 前端需加入抗混叠低通滤波器(RC 一阶或运放二阶),截止频率设为采样率的 1/2 以下。此外,ADC 参考电压(VREF)的稳定性至关重要,建议使用外部精密基准源(如 REF3030)而非 MCU 内部 VREF。
4.3.2 数据缓存与 DMA 传输
对于连续高频采样(如 1kHz 加速度计、16kHz 麦克风),若每次采样都触发 CPU 中断,将导致大量上下文切换开销,甚至影响推理任务实时性。标准方案是使用DMA 环形缓冲区:ADC 或 SPI 外设通过 DMA 将数据持续写入 SRAM 中的环形缓冲区,当缓冲区半满或全满时触发一次中断,CPU 批量处理数据。以 16kHz 采样、16 位精度为例,每秒产生 32KB 数据,若 SRAM 分配 8KB 环形缓冲区,则每 250ms 触发一次中断,CPU 负载极低。
// ADC + DMA 环形缓冲区配置(伪代码)
#define BUF_SIZE 4096
uint16_t adc_buf[BUF_SIZE];
// 配置 ADC 为连续扫描模式,DMA 循环模式
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, BUF_SIZE);
// 在 DMA 半传输完成中断中处理前一半数据
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
process_audio_data(adc_buf, BUF_SIZE/2);
}
4.3.3 数据预处理与特征构建
原始传感器数据通常不能直接输入 TinyML 模型,需经过预处理。常见操作包括:去直流偏置(减去均值)、归一化(映射到 [-1,1] 或 [0,1])、滑动窗口(如 256 点音频帧,50% 重叠)、特征提取(MFCC、FFT 频谱、时域统计量)。预处理环节需注意定点化问题——MCU 通常无 FPU(如 Cortex-M0+),浮点运算需软件模拟,耗时严重。建议将归一化系数预先计算为定点数(Q15 格式),在整数域完成运算。
4.4 实战案例:基于 STM32 的振动异常检测系统
本案例展示一个完整的传感器数据采集与 TinyML 推理链路。某工业设备需监测电机轴承振动,异常时提前预警。选用 STM32F407(Cortex-M4,168MHz,192KB SRAM)作为主控,ADXL345 三轴加速度计(SPI 接口,±16g,3200Hz 最大采样率)作为振动传感器。
初始现象与目标:设备正常运行时振动频率约 50Hz(电机转速 3000rpm),异常时出现 200-500Hz 高频冲击。目标:以 1kHz 采样率采集振动数据,每 1 秒输出一次异常概率。
关键参数与配置:
- SPI 速率:2.25Mbps(ADXL345 最大 5MHz,留有余量)
- 采样率:1kHz(ADXL345 内部滤波带宽设为 500Hz)
- DMA 环形缓冲区:2048 个样本(约 2 秒数据),半满中断
- 特征提取:每 256 点计算 RMS、峰值、FFT 频谱能量比(高频/低频)
- 模型:2 层全连接神经网络(输入 6 维特征,隐藏层 16 节点,输出 2 类)
分析判断过程:初始调试时发现 SPI 读取数据偶发错位,示波器测量发现 SCLK 波形存在过冲,且 CS 片选信号建立时间不足。解决方案:在 SPI 时钟线串联 33Ω 电阻,并将 SPI 速率降至 1.125Mbps,同时调整 CS 时序为提前 1μs 拉低。数据稳定后,采集 10 组正常/异常数据,提取特征并训练模型,量化后模型大小 1.2KB,推理耗时 0.8ms。
实际操作步骤:
- 初始化 SPI1(速率 1.125Mbps,CPOL=1,CPHA=1),配置 ADXL345 为测量模式,±16g,输出速率 1kHz。
- 配置 DMA2 通道 0 为 SPI1 RX 循环模式,缓冲区 2048 字节。
- 在 DMA 半传输完成中断中,对前 1024 个样本进行特征提取。
- 将 6 维特征输入 TFLite Micro 模型,获得异常概率。
- 若概率 > 0.8,GPIO 输出高电平触发报警 LED,并通过 UART 发送日志。
结果对比与复盘:系统运行 72 小时,成功识别 15 次异常事件,误报 2 次(均为外部冲击干扰)。误报原因分析:特征提取窗口过短(256 点),无法区分持续冲击与瞬时干扰。改进方案:将窗口延长至 512 点,并增加时域波形因子特征。优化后误报降至 0 次。本案例验证了 SPI+DMA 方案在 1kHz 采样场景下的可行性,同时说明特征工程对 TinyML 推理准确率的关键影响。
4.5 常见误区与设计复盘
在嵌入式系统与 TinyML 结合的实际项目中,以下误区高频出现,需特别警惕:
- 误区一:忽视时钟树配置。外设时钟未使能或分频错误,导致 SPI/I2C 速率异常。排查方法:核对 RCC 寄存器配置,使用逻辑分析仪实测 SCLK 频率。
- 误区二:中断优先级设置不当。ADC 采样中断优先级低于其他外设中断,导致采样间隔抖动,影响信号频谱分析。建议将采样相关中断设为最高优先级(数值最小)。
- 误区三:SRAM 分配不足。TFLite Micro 的 tensor arena 设置过小,模型加载失败。需通过模型分析工具(如 TFLite Model Analyzer)获取峰值内存需求,并预留 20% 余量。
- 误区四:忽略传感器上电稳定时间。部分传感器(如温湿度)上电后需 10-100ms 稳定,立即读取会得到错误数据。应在初始化后延时再读取。
- 误区五:浮点运算滥用。在无 FPU 的 MCU 上使用 float 类型进行大量运算,导致推理耗时剧增。应使用定点数或 Q 格式表示。
设计复盘时,建议从信号链路完整性(传感器→接口→DMA→预处理→模型)逐级检查,每一级都应有明确的验证指标(如 SPI 误码率 < 1e-6、ADC 信噪比 > 60dB、推理延迟 < 10ms)。只有建立量化指标体系,才能确保 TinyML 系统在真实环境中稳定运行。