zoukankan      html  css  js  c++  java
  • 嵌入式框架Zorb Framework搭建六:定时器的实现

    我是卓波,我是一名嵌入式工程师,我万万没想到我会在这里跟大家吹牛皮。

    嵌入式框架Zorb Framework搭建过程

    嵌入式框架Zorb Framework搭建一:嵌入式环境搭建、调试输出和建立时间系统

    嵌入式框架Zorb Framework搭建二:环形缓冲区的实现

    嵌入式框架Zorb Framework搭建三:列表的实现

    嵌入式框架Zorb Framework搭建四:状态机的实现

    嵌入式框架Zorb Framework搭建五:事件的实现

    嵌入式框架Zorb Framework搭建六:定时器的实现

    嵌入式框架Zorb Framework搭建七:任务的实现

    一、前言

      在嵌入式开发中,我们常常会用到定时器,我们可以用芯片的定时器外设,可以用内核的systick,也可以使用操作系统的定时器。本篇要设计的定时器类似与操作系统的定时器,是软件定时器。如果Zorb Framework运行在操作系统上面,大可以不使用本篇的功能,直接使用操作系统自带的定时器。

    二、定时器设计

      我们先来看看要实现的定时器提供什么功能:

      初步要提供的功能如下:

      1、可以设置定时时间

      2、可以设置定时器是单次还是重复运行

      3、可以设置定时器处理函数

      4、定时器函数可以直接运行或者推送异步事件

      5、可以打开和关闭定时器

      因此,初步设计的数据结构如下: 

     1 /* 定时器处理程序 */
     2 typedef void (*ITimerProcess)(void);
     3 
     4 /* 定时器结构 */
     5 typedef struct _Timer
     6 {
     7     uint8_t Priority;               /* 事件优先级 */
     8     uint32_t Interval;              /* 时间间隔(ms) */
     9     uint32_t AlarmTime;             /* 定时到达时间 */
    10     bool IsAutoReset;               /* 重复运行(默认开) */
    11     bool IsRunning;                 /* 是否正在运行(默认关) */
    12     /* 事件的处理者,事件将推送到处理者的队列 */
    13     /* 不设置处理者则本地执行(挂载Timer_process的地方) */
    14     EventHandler *pEventHandler;
    15     /* 处理事件 */
    16     ITimerProcess TimerProcess;
    17     
    18     /* 开始定时器 */
    19     void (*Start)(struct _Timer * const pTimer);
    20     
    21     /* 关闭定时器 */
    22     void (*Stop)(struct _Timer * const pTimer);
    23     
    24     /* 重新运行定时器 */
    25     void (*Restart)(struct _Timer * const pTimer);
    26     
    27     /* 销毁定时器(释放空间) */
    28     bool (*Dispose)(struct _Timer * const pTimer);
    29 } Timer;

      事件和事件处理器已经设计好了,再把定时器的处理程序添加到系统滴答程序中即可:

     1 /******************************************************************************
     2  * 描述  :系统滴答程序(需挂在硬件的时间中断里边)
     3  * 参数  :无
     4  * 返回  :无
     5 ******************************************************************************/
     6 void ZF_timeTick (void)
     7 {
     8     /* 系统滴答计数 */
     9     ZF_tick++;
    10     
    11     /* 软件定时器程序 */
    12     Timer_process();
    13 }

      具体实现请看附件代码或在文末的github地址拉框架源码。

    三、定时器结果测试

      简单的测试代码如下:

     1 /**
     2   *****************************************************************************
     3   * @file    app_timer.c
     4   * @author  Zorb
     5   * @version V1.0.0
     6   * @date    2018-06-28
     7   * @brief   定时器测试的实现
     8   *****************************************************************************
     9   * @history
    10   *
    11   * 1. Date:2018-06-28
    12   *    Author:Zorb
    13   *    Modification:建立文件
    14   *
    15   *****************************************************************************
    16   */
    17 
    18 #include "app_timer.h"
    19 #include "zf_includes.h"
    20 
    21 /* 事件处理器 */
    22 static EventHandler *pEventHandler;
    23 /* 定时器1 */
    24 static Timer *pTimer1;
    25 /* 定时器2 */
    26 static Timer *pTimer2;
    27 
    28 /******************************************************************************
    29  * 描述  :定时器程序1
    30  * 参数  :void
    31  * 返回  :无
    32 ******************************************************************************/
    33 void TimerProcess1(void)
    34 {
    35     ZF_DEBUG(LOG_D, "%dms:timer process 1 run
    ", ZF_SYSTIME_MS());
    36 }
    37 
    38 /******************************************************************************
    39  * 描述  :定时器程序2
    40  * 参数  :void
    41  * 返回  :无
    42 ******************************************************************************/
    43 void TimerProcess2(void)
    44 {
    45     ZF_DEBUG(LOG_D, "%dms:timer process 2 run
    ", ZF_SYSTIME_MS());
    46 }
    47 
    48 /******************************************************************************
    49  * 描述  :任务初始化
    50  * 参数  :无
    51  * 返回  :无
    52 ******************************************************************************/
    53 void App_Timer_init(void)
    54 {
    55     /* 初始化事件处理器 */
    56     EventHandler_create(&pEventHandler);
    57     
    58     /* 创建定时器1 */
    59     Timer_create(&pTimer1);
    60     pTimer1->Priority = 1;
    61     pTimer1->Interval = 500;
    62     pTimer1->TimerProcess = TimerProcess1;
    63     pTimer1->IsAutoReset = true;
    64     pTimer1->pEventHandler = pEventHandler;
    65     pTimer1->Start(pTimer1);
    66     
    67     /* 创建定时器2 */
    68     Timer_create(&pTimer2);
    69     pTimer2->Priority = 2;
    70     pTimer2->Interval = 1000;
    71     pTimer2->TimerProcess = TimerProcess2;
    72     pTimer2->IsAutoReset = true;
    73     pTimer2->pEventHandler = pEventHandler;
    74     pTimer2->Start(pTimer2);
    75 }
    76 
    77 /******************************************************************************
    78  * 描述  :任务程序
    79  * 参数  :无
    80  * 返回  :无
    81 ******************************************************************************/
    82 void App_Timer_process(void)
    83 {
    84     while(1)
    85     {
    86         /* 执行事件 */
    87         if (pEventHandler->GetEventCount(pEventHandler) > 0)
    88         {
    89             pEventHandler->Execute(pEventHandler);
    90         }
    91         else
    92         {
    93             /* 可在此实现低功耗 */
    94         }
    95     }
    96 }
    97 /******************************** END OF FILE ********************************/

      结果:

    500ms:timer process 1 run
    1000ms:timer process 1 run
    1002ms:timer process 2 run
    1500ms:timer process 1 run
    2000ms:timer process 1 run
    2002ms:timer process 2 run
    2500ms:timer process 1 run
    3000ms:timer process 1 run
    3002ms:timer process 2 run
    3500ms:timer process 1 run
    4000ms:timer process 1 run
    4002ms:timer process 2 run
    4500ms:timer process 1 run
    5000ms:timer process 1 run
    5002ms:timer process 2 run

    省略...

      在测试程序中,定时器1周期为500ms,定时器2周期为1000ms。至于定时器2程序第一次执行的时间为1002ms的原因:定时器1和定时器2同时在1000ms处响应,但定时器1 的优先级比定时器2的优先级高,因此事件处理器先处理完定时器1的事件再处理定时器2的事件,而调试串口波特率115200,定时器1程序把调试数据发送完的时间大约2ms,因此定时器2的第一次执行时间为1002ms。

    四、最后

      本篇为Zorb Framework提供了定时器功能。在对定时精度要求不高(毫秒级),完全可以使用软件定时器。软件定时器是在硬件定时器的基础上开发的,好处在于可以挂载多个定时器,不用再为芯片的定时器资源不够而烦恼。

     

      Zorb Framework github:https://github.com/54zorb/Zorb-Framework

      版权所有,转载请打赏哟

    如果你喜欢我的文章,可以通过微信扫一扫给我打赏哟

  • 相关阅读:
    Druid 使用 Kafka 将数据载入到 Kafka
    Druid 使用 Kafka 数据加载教程——下载和启动 Kafka
    Druid 集群方式部署 —— 启动服务
    Druid 集群方式部署 —— 端口调整
    Druid 集群方式部署 —— 配置调整
    Druid 集群方式部署 —— 配置 Zookeeper 连接
    Druid 集群方式部署 —— 元数据和深度存储
    Druid 集群方式部署 —— 从独立服务器部署上合并到集群的硬件配置
    Druid 集群方式部署 —— 选择硬件
    Druid 独立服务器方式部署文档
  • 原文地址:https://www.cnblogs.com/54zorb/p/9325510.html
Copyright © 2011-2022 走看看