硬件介绍
- 底盘:幻尔阿克曼底盘;2个直流霍尔电机、1个PWM舵机
- 开发板:幻尔Ros Controller V1.2(STM32F407VET6)
- 电源:因为是学习阶段,没有配电池,使用120W可调电源(3V~12V)
- 屏幕:0.96存OLED
- 蓝牙:蓝牙转串口接收器
过程文档及资源
链接 | 说明 |
---|---|
https://gitee.com/jori-wang/car-demo.git | 源代码地址。从SPL -> STM32CubeMX+LL -> STM32CubeMX+LL+FreeRTOS |
https://gitee.com/jori-wang/mcu-tool-set.git | 所有需要用到的软件工具及说明 |
https://gitee.com/jori-wang/hardware-dataset.git | 所有用到的资料。开发板说明、芯片手册等 |
遇到的问题及解决方案
使用UART通信时,设置的波特率和实际值不匹配
进行单片机开发的第一步就是时钟设置。
本人没有进行时钟设置导致实际时钟频率(HSE 16MHz)和代码使用的时钟频率(HSE 25MHz)不匹配,导致上述问题。
所有频率不匹配的问题,几乎都和时钟相关
将printf映射到串口时,重写 fputc 函数导致系统卡死(没进main函数)
使用 printf
需要导入 <stdio.h>
但是单片机没有标准C中的对应实现(硬件不一样),因此有以下三种解决方法:
- 使用
MicroLib
; - 自己实现并覆盖默认实现(
void _sys_exit(intx)
和定义结构体struct __FILE
); - 如果使用Keil开发,在
Run-Time Environment
中勾选STDERR-ITM
。将消息重定向到调试面板(debug window)
调试模式下系统卡死,没有触发断点
默认情况下,进调试模式系统会在 main 函数的最开始触发一个断点,开发者需要手动点击 continue 才能继续执行。
所以如果没有进 main 函数,那就说明代码在启动时就出错了或者触发了死循环。大概率时出错了。
此时可以观察调用栈,断点停留在哪个函数,然后观察寄存器中的数据;同时通过watch功能观察函数体中变量的值,来排查可能的错误。
这种情况,大概率是缺少函数实现(如前面的 stdio 导致的程序卡死)
调试模式代码正常,直接运行系统无反应
排查时钟问题;排查代码报错;排查宏定义值。
调试模式有两点比较特殊:
- 人为增加延时。虽然断点停止了代码的执行,但是硬件电路还在实际工作,此时断点人为引入delay;部分场景下会导致报错代码被跳过
- 调试模式不一定会重置所有参数值,特别是全局参数;预编译宏等
如果调试模式下,在不是断点的地方触发了断点,大概率是代码出错,IDE自行停在出错的位置方便调试