控制/MCU
本篇介绍中科蓝讯 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 的外设进行控制。
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !