目錄
- 前言
- 一、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配置成功了
敲入停止指令可停止回調