RT-Thread论坛
直播中

石工

10年用户 319经验值
擅长:测量仪表
私信 关注
[经验]

【Vision Board创客营连载体验】HWTIMER设备体验

开发环境:

RT-Thread Studio:v2.2.7

开发板:RA8D1 Vision Board开发板

MCU:R7FA8D1BHEC337AS02

1、定时器简介

  硬件定时器一般有 2 种工作模式,定时器模式和计数器模式。不管是工作在哪一种模式,实质都是通过内部计数器模块对脉冲信号进行计数。下面是定时器的一些重要概念。

  1. 计数器模式: 对外部输入引脚的外部脉冲信号计数。
  2. 定时器模式: 对内部脉冲信号计数。定时器常用作定时时钟,以实现定时检测,定时响应、定时控制。
  3. 计数器: 计数器可以递增计数或者递减计数。16位计数器的最大计数值为65535,32位的最大值为4294967295。
  4. 计数频率: 定时器模式时,计数器单位时间内的计数次数,由于系统时钟频率是定值,所以可以根据计数器的计数值计算出定时时间,定时时间 = 计数值 / 计数频率。例如计数频率为 1MHz,计数器计数一次的时间则为 1 / 1000000, 也就是每经过 1 微秒计数器加一(或减一),此时 16 位计数器的最大定时能力为 65535 微秒,即 65.535 毫秒。

  本定时器设备框架内部会自动处理硬件定时器超时的问题,例如16位定时器在1MHz的频率下最大只能维持65.535ms。但是在本定时器框架下,用户可以将定时器的溢出时间设置为例如500ms,框架内部会自动处理硬件溢出问题。当时间达到500ms后,框架会调用用户预先设置好的回调函数。

函数 描述
rt_device_find 查找设备
rt_device_open 打开设备
rt_device_set_rx_indicate 设置超时回调函数
rt_device_control 设置定时器模式
rt_device_write 设置定时器参数
rt_device_read 获取定时器当前值

参考资料

2、FS配置

  1. 双击RA Smart Coniuator打开FS配置工具
    image.png
  2. 按照下图配置定时器参数
    image.png
  3. 点击 “Stacks” -> “New Stack” -> “Timers” -> “Timers,General PWM(r_gpt)”配置GPT如下图image.png
  4. 点击Generate Project Content 生成配置代码
    image.png

3、HWTIMER代码实现

  1. hwtimer配置代码
int hwtimer_sample(void)
{
    rt_err_t ret = RT_EOK;
    rt_hwtimerval_t timeout_s;
    rt_device_t hw_dev = RT_NULL;
    rt_hwtimer_mode_t mode;
    rt_uint32_t freq = 1875000; /* 1Mhz */

    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);

    rt_device_control(hw_dev, HWTIMER_CTRL_FREQ_SET, &freq);

    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;
    }

    /* Example Set the timeout period of the timer */
    timeout_s.sec = 1;  /* secend */
    timeout_s.usec = 0; /* microsecend */
    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;
    }

    /* read hwtimer value */
    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_CMD_EXPORT(hwtimer_sample, hwtimer sample);
  1. 回调函数
static rt_err_t timeout_cb(rt_device_t dev, rt_size_t size)
{
    rt_kprintf("this is hwtimer timeout callback fucntion!\n");
    rt_kprintf("tick is :%d !\n", rt_tick_get());

    return RT_EOK;
}

3、测试验证

image.png

更多回帖

发帖
×
20
完善资料,
赚取积分