STM32 底层固件架构与驱动设计

STM32 底层固件架构与驱动设计说明书

适用硬件: STM32F103 系列 (基于野火 F103-MINI 开发板修改)
模块功能: 运动控制、传感器数据采集、底层通信

1. 系统概述 (System Overview)

本固件运行于机器人底盘控制器的 STM32 MCU 上,作为底层驱动核心,承担以下职责:

  1. 运动执行:通过 I2C 总线控制四轮差速电机驱动板,实现全向移动与平滑调速。
  2. 数据感知:采集 IMU (MPU6050) 的姿态数据与电机编码器的里程计数据。
  3. 数据交互:通过 UART 串口与上位机 (ROS 2 节点) 进行高频数据通讯。

2. 硬件资源配置 (Hardware Configuration)

根据 USER/main.c 及相关 BSP 文件,系统硬件资源分配如下:

外设 (Peripheral) 引脚/总线 (Pin/Bus) 功能描述 (Description) 备注
USART1 PA9 (TX), PA10 (RX) 上位机通讯接口 波特率 115200, 开启接收中断
I2C (Hard/Soft) PB10 (SCL), PB11 (SDA) 电机驱动板通信 用于下发速度与读取编码器
I2C (Sensor) I2C1 (配置依赖) MPU6050 通信 读取六轴传感器数据
TIM3 内部定时器 系统时基/定时任务 提供精确延时或中断源

3. 核心驱动模块详细设计

3.1 电机控制与里程计 (Motor & Odometry)

代码文件: USER/main.c, BSP/motor_model/bsp_motor_iic.c

3.1.1 物理参数模型

系统采用运动学模型解算里程计,关键物理参数定义如下:

  • 减速比与线数: 1:30 减速比,11 线霍尔编码器。
  • 脉冲系数 (PULSE_PER_REVOLUTION): 11.0×30.0=330.011.0 \times 30.0 = 330.011.0×30.0=330.0 (每圈脉冲数)。
  • 轮胎参数: 直径 0.067m,周长约 0.21m。
3.1.2 编码器读取与死区过滤

为了解决静态时的信号抖动问题,代码中实现了智能死区过滤策略 (CalculateOdometry 函数):

  • 机制:系统检测当前是否接收到运动指令 ('W', 'A', 'S', 'D')。

  • 逻辑 :

    • 运动中:不做过滤,保留微小的脉冲变化,确保 SLAM 建图精度。
    • 静止中 :若脉冲变化量 Δ∈−2,2\Delta \in -2, 2Δ∈−2,2,强制置零。
  • 实现代码片段 :

    c 复制代码
    bool is_moving = (current_cmd == 'W' || current_cmd == 'A' || ...);
    if (!is_moving) {
        if(delta_pulse[i] >= -2 && delta_pulse[i] <= 2) delta_pulse[i] = 0;
    }
3.1.3 平滑速度控制

为保护电机齿轮箱并减少机器人急停急启带来的冲击,实现了加速度限制逻辑 (SmoothControlSpeed 函数):

  • 最大加速度 :max_acceleration = 100。
  • 每次循环仅允许速度值在当前值基础上增加或减少最大加速度值,实现梯形速度规划的简易版本。

3.2 惯性测量单元 (IMU)

代码文件: USER/mpu6050.c

  • 初始化流程 :
    1. 硬件复位等待电源稳定。
    2. ID 校验 :循环 5 次读取 WHO_AM_I 寄存器 (期望值 0x68 或 0x69),确保硬件连接正常。若失败则通过串口打印错误诊断。
    3. 配置电源管理、采样率分频、低通滤波及量程。
  • 数据采集:提供原始加速度 (Accel)、角速度 (Gyro) 和温度 (Temp) 的读取接口。

4. 主程序架构与调度 (Main Loop Logic)

系统采用 "前后台系统" (Foreground-Background System) 架构:

4.1 中断层 (后台)

  • USART1_IRQHandler :
    • 负责接收上位机指令。
    • 解析单字符控制指令 ('W', 'A', 'S', 'D', 'T')。
    • 时间同步 :收到 'T' 指令后解析随后的时间戳字符串,计算 STM32 与 ROS 系统的时间偏移量 system_time_offset。

4.2 主循环层 (前台)

main() 函数中的 while(1) 循环通过轮询系统时间 (GetSystemTime) 实现非阻塞的多任务调度:

  1. 指令执行任务:

    • 调用 ExecuteCommand(current_cmd) 执行当前速度控制。
    • 超时保护 :调用 CheckCommandTimeout(),若超过 500ms 未收到新指令,自动停车,防止失控。
  2. 里程计发布任务 (20ms 周期):

    • 调用 CalculateOdometry() 计算脉冲增量。
    • 通过串口发送格式化数据:/four_wheel_encoder,e1,e2,e3,e4,timestamp\n。
  3. IMU 发布任务 (10ms 周期):

    • 读取 MPU6050 数据。
    • 通过串口发送格式化数据:/imu_data,ax,ay,az,gx,gy,gz,temp,timestamp\n。
  4. 状态监控任务 (约 2-4秒):

    • 每 200 次循环打印一次系统摘要,用于调试。

5. 关键算法与原子操作

5.1 时间戳获取

为了保证多任务环境下时间的单调递增性,GetSystemTime 函数使用了原子保护:

c 复制代码
__disable_irq(); // 关中断
current_time = monotonic_time_ms;
__enable_irq(); // 开中断

这防止了在读取时间变量时被定时器中断打断从而导致的数据竞争。

6. 接口协议摘要 (Interface Summary)

为了配合后续 ROS 驱动开发,底层固定的数据格式如下:

  • 上行 (STM32 -> ROS):纯文本 CSV 格式,以换行符结尾。
  • 下行 (ROS -> STM32) :
    • 单字节指令:W/A/S/D (前后左右)。
    • 时间同步指令:T + 时间戳文本。
相关推荐
FakeOccupational9 小时前
【电路笔记 STM32】Cortex-M7 UART DMA模式(DMA&空闲中断&普通模式+DMA&半满/全满中断&循环模式)
笔记·stm32·嵌入式硬件
sramdram9 小时前
国产32位CH32V系列RISC-V单片机
单片机·嵌入式硬件·risc-v·国产32位单片机·risc-v单片机
万物智能信息科技9 小时前
人体感应芯片PIR模块驱动开发—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
驱动开发·嵌入式硬件·华为·开源·harmonyos
youcans_10 小时前
【STM32C5教程】(4)GPIO 外部中断实验
stm32·单片机·嵌入式硬件·mcu·stm32c5
深圳市恒锐丰科技杨生11 小时前
# CSM9118|芯晞微电 7.5V/1.5A 单通道 H 桥电机 / 线圈驱动
嵌入式硬件·硬件工程
硅基手札11 小时前
【I2C 技术系列 09】I2C 传输模式:轮询 / 中断 / DMA
驱动开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
Zw-awa12 小时前
让机器回答“我在哪”:激光雷达与 SLAM
stm32
启友玩AI12 小时前
微安级唤醒、毫安级识别:基于 CI3422 的 AI 眼镜语音交互开发实战
c语言·人工智能·科技·嵌入式硬件·ai·ar·语音识别
wuyk55512 小时前
样章-第10讲-看门狗异常恢复与卡机排查方法论
stm32·单片机·嵌入式硬件·重构
开发笔记-阿牛12 小时前
AM收音机蓝牙二合一设计复盘
人工智能·单片机·嵌入式硬件·音视频·音频