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 寄存器 (期望值 0x680x69),确保硬件连接正常。若失败则通过串口打印错误诊断。
    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 + 时间戳文本。
相关推荐
某林2121 小时前
集成式人机交互与底层驱动系统设计说明书
人工智能·stm32·嵌入式硬件·算法·机器学习·人机交互
szxinmai主板定制专家1 小时前
JETSON orin+FPGA+GMSL+AI协作机器人视觉感知
网络·arm开发·人工智能·嵌入式硬件·fpga开发·机器人
程序员 _孜然1 小时前
linux调试外部RTC hym8563
linux·驱动开发·嵌入式硬件·ubuntu
顾安r2 小时前
12.8 脚本网页 井字棋
前端·stm32·django·html
金色光环2 小时前
基于STM32F407+dp83848实现ModbusTCP从站移植
驱动开发·stm32·嵌入式硬件
一枝小雨2 小时前
【OTA专题】12 APP中移植EEprom、W25Q驱动
stm32·单片机·嵌入式·freertos·ota·bootloader
1+2单片机电子设计2 小时前
STM32 智能外卖柜的设计与实现
人工智能·stm32·单片机·嵌入式硬件
l3538o675732 小时前
智能家居设备供电芯片:220v降压5v 12v-600ma电源芯片AH8966/AH8665
人工智能·科技·单片机·智能家居
一枝小雨3 小时前
【OTA专题】11 进一步优化OTA后台无感下载架构
stm32·单片机·架构·嵌入式·freertos·ota·bootloader