本篇介紹中科藍訊 ab32vg1 的 timer 的用法,ab32vg1 有5個timer,其中timer0、timer1、timer2 只支持 32 位的定時器功能,timer3、timer4、timer5 能夠被配置成定時器模式、計數器模式、輸入捕獲模式和 pwm 模式。本文首先介紹 rt-thread 提供的 api函數,接著列出了使用 sdk 的詳細步驟,最后分析一次代碼。
1.rt-thread提供的 timer的API
?rt-thread是通過 I/O 設備模型來管理 soc 上的外設,從上到下分為三層:I/O 設備管理層、設備驅動框架層和設備驅動層。stm32 的 HAL 庫就屬于設備驅動層,比如熟知的 i2c、spi 的外設驅動在用 cubemx 生成代碼的時候就已經準備好。中科藍訊的 ab32vg1 的設備驅動已經在 sdk 中由藍訊的工程師實現。而在設備驅動層之上的設備驅動框架層和設備 I/O 管理層要說明一下:設備驅動框架層提供了一些接口留給設備驅動開發者去實現,只在做驅動移植的時候需要,作為普通用戶,只需要關心I/O 管理層即可,rt-thread 的 I/O 管理層提供了類似于 linux 中文件 IO 的API,常用的有 rt_device_find、rt_device_open、rt_device_read、rt_device_close 等。下面列舉了 hwtimer 的 api,結合示例去理解如何將這些API用起來實現定時器的功能。
rt_device_trt_device_find(const char* name):查找設備,name為設備名字。
rt_err_trt_device_open(rt_device_t dev, rt_uint16_t oflags):打開定時器設備,dev為定時器設備句柄,oflags:打開模式,一般取RT_DEVICE_OFLAG_RDWR。
rt_err_trt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_tdev,rt_size_t size)) :設置超時回調,dev:定時器設備句柄 rx_ind:超時回調函數
rt_err_trt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg): 控制定時器, dev:定時器設備句柄 cmd:控制命令,可取值如下:
HWTIMER_CTRL_FREQ_SET設置計數頻率
HWTIMER_CTRL_STOP停止定時器
HWTIMER_CTRL_INFO_GET獲取定時器特征信息
HWTIMER_CTRL_MODE_SET設置定時器模式
arg:控制命令參數 設置定時器模式時,可取值如下:
?HWTIMER_MODE_ONESHOT 單 次 定 時
?HWTIMER_MODE_PERIOD 周 期 性 定 時
rt_size_trt_device_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_tsize):設置定時器超時值,dev:定時器設備句柄 pos:偏移值,未使用,可取 0 值 buffer:指向超時時間結構體 size:超時時間結構體大小
rt_size_trt_device_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size ):獲取定時器當前值,dev:定時器句柄 pos:偏移值,未使用,可取 0值 buffer:超時時間結構體 size:超時時間結構體大小。
rt_err_trt_device_close(rt_device_t dev):關閉定時器。
2.硬件定時器的應用步驟
定時器的配置流程:首先用rt_device_find 根據設備名稱查找到定時器句柄、使用定時器句柄打開定時器、接著設置定時器的回調函數、配置完定時器后設置定時器的定時值后定時器啟動,之后每當定時器的計數器溢出就會執行一次定時器的回調函數。
3.具體應用案例
3.1利用rt-thread studio 新建BSP工程,選擇基于開發板的項目,開發型號選擇AB32VG1-AB-PROUGEN,點擊完成即可。
3.2 配置 rt-thread setting
雙擊 RT-Thread Setting,進入RT-Thread Setting配置界面,如下所示
然后點擊點擊更多配置
在硬件選項下勾選定時器,使能定時器1
?
按快捷鍵Ctrl+S,更新軟件包。然后編譯工程,將程序下載開發板。在Downloader軟件窗口中msh指令lsit_device,可以看到打印結果定時器設備timer1,這里的timer1就是定時器的名字name,這個名字在對定時器操作時用到。
3.3 增加測試源文件
?選中applications,點擊右鍵添加源文件timer.c。
然后復制如下示例代碼粘貼到timer.c中,
/*
?* Copyright (c) 2006-2021, RT-ThreadDevelopment Team
?*
?* SPDX-License-Identifier: Apache-2.0
?*
?* Change Logs:
?* Date?????????? Author?????? Notes
?* 2021-12-11???? admin?????? the first version
?*/
#include
#include
#defineHWTIMER_DEV_NAME?? "timer1"??? /* 定時器名稱 */
/* 定時器超時回調函數 */
staticrt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
??? rt_kprintf("this is hwtimer timeoutcallback fucntion!\n");
??? rt_kprintf("tick is :%d !\n", rt_tick_get());
??? return 0;
}
staticint hwtimer_sample(int argc, char *argv[])
{
??? rt_err_t ret = RT_EOK;
??? rt_hwtimerval_t timeout_s;????? /* 定時器超時值 */
??? rt_device_t hw_dev = RT_NULL;?? /* 定時器設備句柄 */
??? rt_hwtimer_mode_t mode;??????? /* 定時器模式 */
??? /* 查找定時器設備 */
??? hw_dev = rt_device_find(HWTIMER_DEV_NAME);
??? if (hw_dev == RT_NULL)
??? {
??????? rt_kprintf("hwtimer sample run failed!can't find %s device!\n", HWTIMER_DEV_NAME);
??????? return RT_ERROR;
??? }
??? /* 以讀寫方式打開設備 */
??? ret = rt_device_open(hw_dev,RT_DEVICE_OFLAG_RDWR);
??? if (ret != RT_EOK)
??? {
??????? rt_kprintf("open %s device failed!\n", HWTIMER_DEV_NAME);
??????? return ret;
??? }
??? /* 設置超時回調函數 */
??? rt_device_set_rx_indicate(hw_dev,timeout_cb);
??? /* 設置模式為周期性定時器 */
??? mode = HWTIMER_MODE_PERIOD;
??? ret = rt_device_control(hw_dev, HWTIMER_CTRL_MODE_SET, &mode);
??? if (ret != RT_EOK)
??? {
??????? rt_kprintf("set mode failed! ret is:%d\n", ret);
??????? return ret;
??? }
??? /* 設置定時器超時值為5s并啟動定時器 */
??? timeout_s.sec = 5;???? /* 秒 */
??? timeout_s.usec = 0;??? /* 微秒 */
??? if (rt_device_write(hw_dev, 0, &timeout_s, sizeof(timeout_s)) != sizeof(timeout_s))
??? {
??????? rt_kprintf("set timeout value failed\n");
??????? return RT_ERROR;
??? }
??? /* 延時3500ms */
??? rt_thread_mdelay(3500);
??? /* 讀取定時器當前值 */
??? rt_device_read(hw_dev, 0, &timeout_s, sizeof(timeout_s));
??? rt_kprintf("Read: Sec = %d, Usec =%d\n", timeout_s.sec, timeout_s.usec);
??? return ret;
}
/* 導出到 msh命令列表中 */
MSH_CMD_EXPORT(hwtimer_sample,hwtimer sample);
3.4 編譯工程
3.5 下載工程
3.6 運行效果
該例程導出了hwtimer_sample 命令到控制終端,命令調用格式:hwtimer_sample,只需要msh窗口中輸入hwtimer_sample即可啟動定時器。硬件定時器超時回調函數周期性的打印當前 tick 值,2 次 tick 值之差換算為時間等同于定時時間值。運行打印內容如下:兩次tick值為5000ms,即定時時間為5s。
4. 章節總結
使用 rt-threadstudio 進行 sdk 的開發是一件非常有效率的事情,新建 bsp 工程后只需要在 rt-thread setting 配置需要的硬件功能就可以使用 rt-thread 提供的設備 I/O 管理接口對底層的 soc 的外設進行控制。
審核編輯:劉清
評論