定时器底层函数
2025/9/8大约 4 分钟
定时器底层函数
以下是与 STM32 定时器相关的常用底层宏(基于 HAL 库),以表格形式列出。这些宏主要用于操作定时器的寄存器,例如设置比较值、计数器值、自动重装载值等。表格包括宏的名称、功能描述和典型用法。
| 宏名称 | 功能描述 | 典型用法 |
|---|---|---|
__HAL_TIM_SET_COMPARE(htim, channel, compare) | 设置指定通道的比较值(CCR 寄存器),用于 PWM 或输出比较模式。 | __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 500); // 设置通道 1 的比较值为 500 |
__HAL_TIM_SET_COUNTER(htim, counter) | 设置定时器的计数器值(CNT 寄存器)。 | __HAL_TIM_SET_COUNTER(&htim3, 0); // 重置计数器为 0 |
__HAL_TIM_SET_AUTORELOAD(htim, arr) | 设置定时器的自动重装载值(ARR 寄存器),决定计数周期。 | __HAL_TIM_SET_AUTORELOAD(&htim3, 999); // 设置 ARR 为 999,计数周期为 1000 |
__HAL_TIM_GET_COUNTER(htim) | 获取当前计数器值(CNT 寄存器)。 | uint32_t count = __HAL_TIM_GET_COUNTER(&htim3); // 读取当前计数器值 |
__HAL_TIM_GET_COMPARE(htim, channel) | 获取指定通道的比较值(CCR 寄存器)。 | uint32_t compare = __HAL_TIM_GET_COMPARE(&htim3, TIM_CHANNEL_1); // 读取通道 1 的比较值 |
__HAL_TIM_GET_AUTORELOAD(htim) | 获取自动重装载值(ARR 寄存器)。 | uint32_t arr = __HAL_TIM_GET_AUTORELOAD(&htim3); // 读取 ARR 值 |
__HAL_TIM_SET_PRESCALER(htim, psc) | 设置定时器的预分频系数(PSC 寄存器),影响计数频率。 | __HAL_TIM_SET_PRESCALER(&htim3, 71); // 设置预分频系数为 71(例如 72 MHz 时钟,分频后 1 MHz) |
__HAL_TIM_ENABLE(htim) | 启用定时器(设置 CR1 寄存器的 CEN 位)。 | __HAL_TIM_ENABLE(&htim3); // 启动定时器 |
__HAL_TIM_DISABLE(htim) | 禁用定时器(清除 CR1 寄存器的 CEN 位)。 | __HAL_TIM_DISABLE(&htim3); // 停止定时器 |
__HAL_TIM_ENABLE_IT(htim, interrupt) | 启用定时器中断(例如更新中断、捕获中断)。 | __HAL_TIM_ENABLE_IT(&htim3, TIM_IT_CC1); // 启用通道 1 捕获中断 |
__HAL_TIM_DISABLE_IT(htim, interrupt) | 禁用定时器中断。 | __HAL_TIM_DISABLE_IT(&htim3, TIM_IT_UPDATE); // 禁用更新中断 |
__HAL_TIM_GET_FLAG(htim, flag) | 检查定时器标志位状态(例如更新标志、捕获标志)。 | if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE)) // 检查更新标志 |
__HAL_TIM_CLEAR_FLAG(htim, flag) | 清除定时器标志位。 | __HAL_TIM_CLEAR_FLAG(&htim3, TIM_FLAG_CC1); // 清除通道 1 捕获标志 |
__HAL_TIM_SET_CLOCKDIVISION(htim, div) | 设置定时器时钟分频(CKD 位),影响内部时钟频率。 | __HAL_TIM_SET_CLOCKDIVISION(&htim3, TIM_CLOCKDIVISION_DIV1); // 设置时钟分频为 1 |
__HAL_TIM_GET_CLOCKDIVISION(htim) | 获取定时器时钟分频设置。 | uint32_t div = __HAL_TIM_GET_CLOCKDIVISION(&htim3); // 读取时钟分频设置 |
__HAL_TIM_SET_CAPTUREPOLARITY(htim, channel, polarity) | 设置捕获极性(例如上升沿、下降沿)。 | __HAL_TIM_SET_CAPTUREPOLARITY(&htim3, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); // 设置通道 1 为上升沿捕获 |
HAL_UARTEx_ReceiveToIdle_DMA()
Ex 是 "Extended"(扩展) 的缩写
机制
- 功能:通过 DMA 接收 UART 数据,支持不定长数据。
- 工作原理:
- 将接收到的数据自动存入指定缓冲区(
pData)。 - 两种结束条件:
- 接收到指定字节数(
Size),触发传输完成(TC)。 - 检测到 UART 线路空闲(IDLE),提前结束。
- 接收到指定字节数(
- 完成后通过回调函数
HAL_UARTEx_RxEventCallback()返回实际接收字节数。
- 将接收到的数据自动存入指定缓冲区(
- 核心特点:DMA 高效传输 + 空闲检测,适合动态长度数据。
与其他函数的区别
对比
HAL_UART_Receive():HAL_UART_Receive()是阻塞式,CPU 逐字节接收,效率低。HAL_UARTEx_ReceiveToIdle_DMA()用 DMA,非阻塞,解放 CPU。
对比
HAL_UART_Receive_DMA():HAL_UART_Receive_DMA()只支持固定长度接收,需预知数据大小,否则等待超时。HAL_UARTEx_ReceiveToIdle_DMA()支持不定长,空闲时提前结束,更灵活。
对比
HAL_UART_Receive_IT():HAL_UART_Receive_IT()用中断接收,需指定长度,数据量大时中断频繁,影响性能。HAL_UARTEx_ReceiveToIdle_DMA()用 DMA + 空闲检测,减少中断开销。
总结
- 优点:高效(DMA)、灵活(空闲检测)、适合不定长数据。
- 适用场景:串口命令、传感器数据、通信协议等。
- 局限:需配置 DMA 和中断,回调处理需简洁。
简单记:DMA 接收 + 空闲触发,比普通接收更快、更灵活。

与普通接收函数不一样,size,意思是接收的最大元素数量,因为是不定长,一般填接受缓冲区的大小,尽量设大一点。

与普通回调函数不一样,多了个Size,意思是实际接收到的数据大小,这里TRANSMIT也用DMA算了

使用前要进行DMA的配置

在DMA模式下,接受到目标长度,空闲,接受过半都会引起中断回调
要关闭接受过半,别忘了这两个是一起的,回调函数里面要打开,main函数第一次用的时候也要一起哟

&hdma_usart1_rx会报错,需要在main.h中使用extern声明

这玩意在uart.c第一行

