中科蓝讯 AB32VG1 上的 Timer 实验

本篇介绍中科蓝讯 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<rtthread.h>

#include<rtdevice.h>

#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 的外设进行控制。

猜你喜欢

转载自blog.csdn.net/chanchairen/article/details/121868283