目录
- 前言
- 一、STM32定时器10是个什么定时器?
- 二、工程创建、环境配置
- 三、程序代码
- 四、运行
前言
在rtthread中,STM32F4的定时器10有些驱动并不完整,对比与其它定时器在使用时需要手动的添加一些代码,我在使用上拆踩了一些坑,因此写这篇文章分享出来,帮助大家避坑
一、STM32定时器10是个什么定时器?
TIM10是一个简化版的通用定时器,它功能精简,只可实现基础的定时 / 脉冲控制场景。
STM32F4定时器分类:
定时器类型 | 代表型号 | 核心特点 | 适用场景 |
---|---|---|---|
高级定时器 | TIM1、TIM8 | 16/32 位、支持死区控制、互补输出、刹车功能 | 电机控制(如 BLDC、步进电机)、大功率 PWM |
通用定时器 | TIM2~TIM5(全功能) | 16/32 位、4 个捕获比较通道、支持多种计数模式 | 复杂定时、多路 PWM、多通道输入捕获 |
通用定时器(简化版) | TIM9~TIM14 | 16 位、仅 1 个捕获比较通道、功能精简 | 简单定时、单路 PWM / 捕获 |
基本定时器 | TIM6、TIM7 | 16 位、无捕获比较通道、仅定时 + DAC 触发 | 纯定时中断、DAC 同步触发 |
二、工程创建、环境配置
1、 新建一个工程
2、打开CubeMX Settings,
3、时钟源配置,使用外部晶振
4、调试口配置
5、开启TIM10,这里的预分频系数不需要配置,因为我们最终会使用到RTthread的API函数对其频率进行配置,因此就算这里配置了最终也会被覆盖
6、串口一顺便也打开
7、时钟树配置
8、选择MDK-ARM工具链
9、生成.c 和.h文件
10、生成代码
11、打开HWTIMER设备驱动程序
12、使能定时器模块
13、打开TIM10的宏
14、没看到单独的tim.c文件,是因为脚本里面没有添加,我们在脚本里面添加
15、然后打开CubeMX重新生成代码
16、现在就能看到tim.c文件了
17、找到TIM10初始化函数,添加TIM10的时钟初始化
18、添加TIM10的CONFIG,这个需要自己手动补充
19、补充TIM10的中断,这个也是库里没有,需要手动补充
20、补充TIM10的回调,这个库里也没有
三、程序代码
代码里的注释写的很清楚,就不对代码进行解释了,在主函数里写入以下就行
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>/* 硬件定时器设备名称 - 根据实际BSP配置修改 */
#define HWTIMER10_DEV_NAME "timer10"/* 定时器超时时间(微秒) */
#define HWTIMER10_TIMEOUT_US 1000000 // 1秒/* 定时器频率(Hz) */
#define HWTIMER10_FREQ 1000000 // 1MHz/* 定时器模式 */
#define HWTIMER10_MODE HWTIMER_MODE_PERIOD/* 硬件定时器设备句柄 */
static rt_device_t hwtimer10_dev = RT_NULL;int main(void)
{int count = 1;while (count++){//rt_kprintf("hello world!\r\n");rt_thread_mdelay(1000);}return RT_EOK;
}/* 硬件定时器回调函数 */
static rt_err_t hwtimer10_callback(rt_device_t dev, rt_size_t size)
{/* 定时器中断处理 */rt_kprintf("Hardware Timer timeout! Tick: %d\n", rt_tick_get());return RT_EOK;
}/* 硬件定时器初始化函数 */
static int hwtimer10_init(void)
{rt_err_t ret = RT_EOK;rt_hwtimerval_t timeout_val;/* 查找硬件定时器设备 */hwtimer10_dev = rt_device_find(HWTIMER10_DEV_NAME);if (hwtimer10_dev == RT_NULL){rt_kprintf("Failed to find %s device!\n", HWTIMER10_DEV_NAME);return -RT_ERROR;}/* 打开硬件定时器设备 */ret = rt_device_open(hwtimer10_dev, RT_DEVICE_OFLAG_RDWR);if (ret != RT_EOK){rt_kprintf("Failed to open %s device!\n", HWTIMER10_DEV_NAME);return ret;}/* 设置定时器频率 */rt_uint32_t freq = HWTIMER10_FREQ;ret = rt_device_control(hwtimer10_dev, HWTIMER_CTRL_FREQ_SET, &freq);if (ret != RT_EOK){rt_kprintf("Failed to set %s frequency!\n", HWTIMER10_DEV_NAME);return ret;}/* 设置定时器模式 */rt_hwtimer_mode_t mode = HWTIMER10_MODE;ret = rt_device_control(hwtimer10_dev, HWTIMER_CTRL_MODE_SET, &mode);if (ret != RT_EOK){rt_kprintf("Failed to set %s mode!\n", HWTIMER10_DEV_NAME);return ret;}/* 设置超时时间 */timeout_val.sec = 0; // 秒部分timeout_val.usec = HWTIMER10_TIMEOUT_US; // 微秒部分/* 写入超时值以启动定时器 */if (rt_device_write(hwtimer10_dev, 0, &timeout_val, sizeof(timeout_val)) != sizeof(rt_hwtimerval_t)){rt_kprintf("Failed to set %s timeout!\n", HWTIMER10_DEV_NAME);return -RT_ERROR;}/* 设置回调函数 */ret = rt_device_set_rx_indicate(hwtimer10_dev, hwtimer10_callback);if (ret != RT_EOK){rt_kprintf("Failed to set %s callback!\n", HWTIMER10_DEV_NAME);return ret;}rt_kprintf("Hardware Timer %s initialized successfully! Interval: %d us\n",HWTIMER10_DEV_NAME, HWTIMER10_TIMEOUT_US);return RT_EOK;
}/* 停止硬件定时器函数 */
static void hwtimer10_stop(void)
{if (hwtimer10_dev != RT_NULL){/* 关闭设备会自动停止定时器 */rt_device_close(hwtimer10_dev);rt_kprintf("Hardware Timer %s stopped!\n", HWTIMER10_DEV_NAME);}
}/* 导出到MSH命令列表 */
MSH_CMD_EXPORT(hwtimer10_init, initialize and start hardware timer10);
MSH_CMD_EXPORT(hwtimer10_stop, stop hardware timer10);
在主函数里写入上面贴出的代码
四、运行
程序下载后。
在命令行执行指令
可以看到1s进一次回调函数,说明我们的TIM10配置成功了
敲入停止指令可停止回调