这一章在干嘛?
剖析正点原子 SYSTEM 文件夹:delay 精确延时(SysTick 计时 + 循环校准)、sys 软复位 / 复位原因 / 时钟获取、usart printf 重定向 / 接收管理。理解后能直接搬到自己项目里用。
12.1 delay 文件夹代码介绍
12.1.1 SysTick 定时器
Cortex-M4 内核自带 24 位 SysTick 倒计时器。168 MHz 时每递减一次 = 1/168 us。
delay_init(168); // 传入主频,自动校准
delay_us(50); // 微秒延时
delay_ms(500); // 毫秒延时
原书图 12.1.1:SysTick 时序图
核心思路:先把 SysTick LOAD 设为 us * 主频 - 1,启动后等 COUNTFLAG 置位。校准用一个 us 延时测真实时间,反推 168 MHz 下的 fac_us 系数。
12.1.2 不使用 SysTick 的方案
有些应用 SysTick 已被 RTOS 占用,本文件夹备了通用定时器版(TIM7)延时,改宏 DELAY_TIMER 即可。
12.2 sys 文件夹代码介绍
sys 头文件暴露了:
| 函数 | 作用 |
|---|---|
HAL_Delay(n) | 毫秒级延时(依赖 SysTick 中断) |
WFI_SET() / WFI_EXIT() | __WFI() 进入睡眠 / 退出 |
Sys_Standby() / Sys_Enter_Standby() | 进入待机模式 |
Sys_Soft_Reset() | NVIC 软复位 |
Sys_GetRunTime() | ms 级运行时间戳(基于 TIM6) |
原书图 12.2.1:sys 文件夹功能一览
12.3 usart 文件夹代码介绍
12.3.1 printf 重定向
把 fputc 重定向到 USART1:
int fputc(int ch, FILE *f) {
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
return ch;
}
使用 MicroLIB → MDK 勾选 → 才能 printf 到串口。
12.3.2 接收管理
支持三种接收方式:
- 阻塞:
HAL_UART_Receive()适合一次性指令; - 中断:
HAL_UART_Receive_IT()适合不定长数据; - DMA:
HAL_UART_Receive_DMA()适合大数据量、不丢帧。
正点原子标准库中常用「USART 接收管理」方案:开接收中断 + 接收完成回调 + g_usart_rx_sta 状态机,实现「任意长度字符串接收」。
12.3.3 XCOM 串口助手
开发板光盘附带 XCOM 串口调试工具:发送区输入字符串 → 自动加回车换行;接收区显示时间戳。
delay_init 函数要传入什么参数?
系统主频(MHz),例如 delay_init(168)。
printf 重定向需要哪两步?
实现 fputc 函数 + MDK 勾选 Use MicroLIB。
接收管理三种方式各适合什么场景?
阻塞:测试;中断:不定长数据;DMA:大数据量流式接收。