当前位置: 首页 > news >正文

适合单片机裸机环境的运行的软件定时器框架

如下这篇文档介绍了一个适用于裸机环境的软件定时器模块,其核心功能和实现如下:

  1. 模块功能:该模块通过硬件定时器中断实现时基累加,适合用于裸机程序的调度处理。它使用硬件定时中断(如1ms一次)来增加hw_timer_ticks,当hw_timer_ticks大于设定的延迟时间时,执行回调函数。
  2. 数据结构:定义了一个`timer_struct 结构体,包含延迟时间delay自动重载时间auto_repeat和回调函数callback。
  3. 函数接口
    timer_start:启动定时器,设置延迟、循环模式和回调函数。
    timer_stop:停止定时器,清零延迟并置空回调函数。
    timer_is_running:检查定时器是否在运行。
    timer_loop:主循环,检查并执行到期的定时器任务。
  4. 实现细节
    hw_timer_ticks:全局变量,用于记录时基。
    my_timer:定时器参数数组,支持最多10个定时器。
  5. 应用示例:提供了一个应用示例,展示了如何使用该模块定时执行两个任务:每2秒执行一次func1,每6秒执行一次`func2。
  6. 适用场景:适用于8位单片机系统,如果硬件资源有限或系统时钟太低,可以调整硬件定时中断的精度。
  7. 优势:实现基础框架后,应用层只需要简单的操作即可实现定时任务,如定时读取ADC结果或延时关闭LED显示。
  8. 代码实现:文档提供了完整的代码实现,包括头文件和主程序,以及如何启动和停止定时器,以及定时器的主循环处理。

这个模块提供了一个简单而有效的软件定时器解决方案,适用于裸机环境,通过硬件定时器中断实现精确的定时任务调度。

该程序的hw_timer_ticks进行时基的累加,建议放在一个硬件的定时器中。主程序通过timer_loop 处理注册的定时器任务,该模块适合对裸机程序进行调度处理。使用硬件定时中断,例如1ms中断一次,每次中断hw_timer_ticks自增一次。主程序中查询hw_timer_ticks 大于delay表示当前定时器任务超时,执行callback。这种在8位单片机系统合适,如果硬件资源有限或者系统时钟太低,可以调整硬件定时中断的精度。这样多个定时器时事件的执行只需要一个硬件定时器。

#include <stdio.h>
#include <string.h>
typedef unsigned int uint32_t;
typedef unsigned char uint8_t;
typedef enum {true=1,false=0}bool;
extern uint32_t hw_timer_ticks ;

typedef void (*timer_callback)(void);
#define SW_TIMER_MAX  10

typedef struct
{
    uint32_t delay;                //延迟时间,实际是当前时间+期望延时的时间后的tick
    uint32_t auto_repeat;    //执行后自动重载时间,为0表示只执行一次
    timer_callback callback;     //回调函数
} timer_struct;

//启动定时器,index可按需求定为枚举类型,必须小于SW_TIMER_MAX
void timer_start(uint8_t index, uint32_t delay, bool loop, timer_callback callback);
void timer_stop(uint8_t index);//停止定时器,delay清零,回调函数置为NULL
bool timer_is_running(uint8_t index);//当前定时器是否在计时运行中,判断delay是否非0
void timer_loop(void);


#include "mytimer.h"

uint32_t hw_timer_ticks = 0;//timer ticks
timer_struct my_timer[SW_TIMER_MAX] = {0};    //定时器参数数组,最大支持10个


void timer_start(uint8_t index, uint32_t delay, bool loop, timer_callback callback)
{
    
    if((index >= SW_TIMER_MAX) || (delay == 0) || (callback == NULL))
    {
        return;
    }

    my_timer[index].delay = hw_timer_ticks + delay;
    if(loop)//自动重载
    {
        my_timer[index].auto_repeat = delay;
    }
    else
    {
        my_timer[index].auto_repeat = 0;
    }

    my_timer[index].callback = callback;
}
void timer_stop(uint8_t index)
{
    my_timer[index].delay=0;
    my_timer[index].callback=NULL;
}

bool timer_is_running(uint8_t index)
{
    if(my_timer[index].delay==0)
    {
        return false ;
    }
    return true;
}

void timer_loop(void)
{
    uint8_t i = 0, n = 0, min = 0;
    for(i = 0 ; i < SW_TIMER_MAX ; i++)
    {
        if(my_timer[i].delay > 0 && my_timer[i].callback != NULL)
        {
            if(hw_timer_ticks >= my_timer[i].delay)
            {
                if(( my_timer[i].auto_repeat) > 0)
                {
                    my_timer[i].delay = hw_timer_ticks + my_timer[i].auto_repeat;
                }
                else
                {
                    my_timer[i].delay = 0; //stop
                }
                (*my_timer[i].callback)();
            }
        }
    }
}

应用Demo:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "mytimer.h"

void func1(void)
{
    printf("task1\r\n");
}
void func2(void)
{
    printf("task2\r\n");
}

int main(void)
{
timer_callback   pFunc;
pFunc=  &func1;
timer_start(0,2,true,pFunc);
pFunc=  &func2;
timer_start(1,6,true,pFunc);
while (1)
{
timer_loop();
usleep(100000);
hw_timer_ticks++;//如果有硬件定时器这个地方放定时器中
}
}


相关文章:

  • Linux 下 Module 工具的介绍与使用
  • 深入解读:2024 可信数据空间建设及应用参考指南【附全文阅读】
  • Go 语言中的局部变量是分配在栈区还是堆区
  • 数据结构-限定性线性表 - 栈与队列
  • 在Mac上离线安装k3s
  • HarmonyOS:页面滚动时标题悬浮、背景渐变
  • 【微服务管理】深入理解 Gateway 网关:原理与实现
  • fbx/obj/glb/gltf/b3dm等通用格式批量转换成osgb
  • STL之priority_queue的用法与实现
  • 第一阶段补充知识
  • 【信息系统项目管理师】高分论文:论信息系统项目的范围管理(投资信息化全流程管理项目)
  • TestHubo安装及入门指南
  • MuJoCo 机械臂关节路径规划+轨迹优化+末端轨迹可视化(附代码)
  • 计算机网络 - 三次握手相关问题
  • 【CUDA】ubuntu环境下安装cuda
  • 为 docker 拉取镜像配置代理
  • 【5G通信】通过RRC重配实现功率调整的可能性
  • 【Python内置函数的深度解析与应用】id
  • Dify - 整合Ollama + Xinference私有化部署Dify平台(01)
  • C++23 新特性静态operator[]、operator()与Lambda
  • 美国参议院投票通过戴维·珀杜出任美国驻华大使
  • 十大券商看后市|A股风险偏好有望边际改善,市场仍处黄金坑
  • 报告:到2030年我国无人机产业将率先实现万亿规模
  • 地下管道密布成难题,道路修整如何破局?
  • 迟来的忍者与武士:从《刺客信条:影》论多元话语的争议
  • 云南省委常委、组织部部长刘非任浙江省委常委、杭州市委书记