【源码分享】MCU裸机下,非阻塞式定时器组实现方案



.c/*自定义定时器结构体*/typedef struct timer{uint8_t TimerId; //计时器id,索引定时器uint32_t TimerBaseValue; //计时基准,更新定时基准uint32_t TimerValue; //定时值,存储定时值uint8_t Timer_Enable; //开启uint8_t Timer_Disable; //关闭} Timer;#define TimeNum 16 //定时器数量Timer userTimer[TimeNum]; //自定义定时器实体
/* .c*说明:计算定时器时间间隔*参数:TimerID timerid 定时器ID,根据ID查询对应的定时器是否超时*返回:1/计时到达 0/计时未达到*/TimerFlags TimerInterval(TimerID timerid){uint8_t Timer_ID = timerid;//判断当前定时器是否启用?if(userTimer[Timer_ID].Timer_Enable){//检查当前定时器是否溢出?if(userTimer[Timer_ID].TimerBaseValue <= u32SystickTimer){//如果没有溢出,则直接计算并判断是否超时?if((u32SystickTimer - userTimer[Timer_ID].TimerBaseValue) >= userTimer[Timer_ID].TimerValue)return Timer_Success;elsereturn Timer_Failure;}else{//如果溢出,先计算出实际时间间隔,最后判断是否超时?if((0xffffffff - userTimer[Timer_ID].TimerBaseValue + u32SystickTimer) >= userTimer[Timer_ID].TimerValue)return Timer_Success;elsereturn Timer_Failure;}}else //若当前定时器未启用,则直接返回Failure{return Timer_Failure;}}
/* .cthis function handles SysTick exception*/voidSysTick_Handler(void){/*定时时间间隔计数值递加*/TimerValueAdd();/*自定义Systick延时函数递减*/userDelay_decrement();}
/*定时器ID枚举*/typedef enum {MONITOR_USART0_RS485_DEN = 0, //monitor USART0 RS-485 DEN-PIN status timerTIMER_NUM} TimerID;/*……其它逻辑*//**说明:初始化systick定时器*参数:none*返回:none*/voidSystickTimer_Init(void){u32SystickTimer = 0x00;/*初始化所有定时器*/memset(userTimer, 0x00, sizeof(userTimer));//set monitor usart1 RS-485 status timer,1sSetSystickTimer(MONITOR_USART0_RS485_DEN, SYSTICK_TIMER_1s);}
/* .c */int main(void){/*...其它初始化逻辑...*//*初始化systick定时器*/SystickTimer_Init();while (1){/*...其它逻辑...*/if(TimerInterval(MONITOR_USART0_RS485_DEN)){/*...需要定时处理的业务逻辑...*///如果不需要轮询,可以调用接口关闭定时器Disable_SysTimer(MONITOR_USART0_RS485_DEN);}/*...其它逻辑...*/}}
/************************************************************************************说明:userSystick.h文件用于系统嘀嗒定时器计时调用接口*创建:MaJinWen*时间:2021.12.13*版本:V_1.0.0************************************************************************************/#ifndef __USERSYSTICK_H__#define __USERSYSTICK_H__#include<stdint.h>#include<stdio.h>/*Systick定时器模块参数封装*/#define SYSTICK_TIMER_100us 1#define SYSTICK_TIMER_10ms (100*SYSTICK_TIMER_100us)#define SYSTICK_TIMER_100ms (10*SYSTICK_TIMER_10ms)#define SYSTICK_TIMER_1s (10*SYSTICK_TIMER_100ms)#define SYSTICK_TIMER_1min (60*SYSTICK_TIMER_1s)#define SYSTICK_TIMER_1h (60*SYSTICK_TIMER_1min)/*函数返回值状态标志*/typedef enum status_flags{Timer_Failure = 0,Timer_Success = 1}TimerFlags;/*定时器ID枚举*/typedef enum {MONITOR_USART0_RS485_DEN = 0, //monitor USART0 RS-485 DEN-PIN status timerTIMER_NUM} TimerID;/*自定义定时器结构体*/typedef struct timer{uint8_t TimerId; //计时器id,索引定时器uint32_t TimerBaseValue; //计时基准,更新定时基准uint32_t TimerValue; //定时值,存储定时值uint8_t Timer_Enable; //开启uint8_t Timer_Disable; //关闭} Timer;/*自定义Systick延时函数*/voiduserSystick_Delay(uint32_t count);/*自定义Systick延时函数递减*/voiduserDelay_decrement(void);/*初始化systick定时器*/voidSystickTimer_Init(void);/*设置systick自定义定时器*/TimerFlags SetSystickTimer(TimerID timerid, uint32_t TimerValue);/*读取systick定时器的计数值*/uint32_tGet_SystickTimerValue(void);/*计算定时时间间隔*/TimerFlags TimerInterval(TimerID timerid);/*定时时间间隔计数值递加*/voidTimerValueAdd(void);/*Systick定时器关闭*/voidDisable_SysTimer(TimerID timerid);/*Systick定时器开启*/voidEnable_SysTimer(TimerID timerid);/*Systick定时器重置*/voidReset_SysTimer(TimerID timerid);#endif/*#ifndef __USERSYSTICK_H__*/
/************************************************************************************说明:userSystick.c源文件用于系统嘀嗒定时器计时调用*创建:MaJinWen*时间:2021.12.13*版本:V_1.0.0************************************************************************************/#include"userSystick.h"#include<string.h>volatile uint32_t u32SystickTimer = 0; //定义一个计时变量volatile uint32_t u32SystickDelay = 0; //定义一个延时变量#define TimeNum 16 //定时器数量Timer userTimer[TimeNum]; //自定义定时器实体/**说明:自定义延时函数,可以在Systick中断中调用*参数:count是延时计数值(计时时长 = count * systick定时)*返回:none*/voiduserSystick_Delay(uint32_t count){u32SystickDelay = count;do{//等待延时计数值递减到0}while(0U != u32SystickDelay);}/**说明:自定义Systick延时函数递减*参数:none*返回:none*/voiduserDelay_decrement(void){if(0U != u32SystickDelay){u32SystickDelay--; //延时计数值做递减}}/**说明:初始化systick定时器*参数:none*返回:none*/voidSystickTimer_Init(void){u32SystickTimer = 0x00;/*初始化所有定时器*/memset(userTimer, 0x00, sizeof(userTimer));/*在这里添加定时间隔设置*/}/**说明:设置systick自定义定时器*参数:TimerID 定时器ID* TimerValue 定时值*返回:设置成功返回true,设置失败返回flaes*/TimerFlags SetSystickTimer(TimerID timerid, uint32_t TimerValue){uint8_t Timer_ID = timerid;uint32_t Timer_Value = TimerValue;/*设置定时器ID*/userTimer[Timer_ID].TimerId = Timer_ID;/*获取定时器计数的初始基准*/userTimer[Timer_ID].TimerBaseValue = Get_SystickTimerValue();/*设置定时器计时值*/userTimer[Timer_ID].TimerValue = Timer_Value;/*设置定时器默认开启*/Enable_SysTimer(timerid);if(userTimer[Timer_ID].TimerValue == 0)return Timer_Failure;elsereturn Timer_Success;}/**说明:读取systick定时器当前计数值*参数:none*返回:返回定时器计数值*/uint32_tGet_SystickTimerValue(void){return u32SystickTimer;}/**说明:计算定时器时间间隔*参数:u32oldTick 定时器启动时获取到的初始计数值*返回:1/计时到达 0/计时未达到*/TimerFlags TimerInterval(TimerID timerid){uint8_t Timer_ID = timerid;if(userTimer[Timer_ID].Timer_Enable){if(userTimer[Timer_ID].TimerBaseValue <= u32SystickTimer){if((u32SystickTimer - userTimer[Timer_ID].TimerBaseValue) >= userTimer[Timer_ID].TimerValue)return Timer_Success;elsereturn Timer_Failure;}else{if((0xffffffff - userTimer[Timer_ID].TimerBaseValue + u32SystickTimer) >= userTimer[Timer_ID].TimerValue)return Timer_Success;elsereturn Timer_Failure;}}else{return Timer_Failure;}}/**说明:定时时间间隔计数值递加*参数:none*返回:none*/voidTimerValueAdd(void){u32SystickTimer++;}/**说明:Systick定时器关闭*参数:TimerID timerid 定时器索引*返回:none*/voidDisable_SysTimer(TimerID timerid){uint8_t Timer_Idx = timerid;userTimer[Timer_Idx].Timer_Enable = 0x00;}/**说明:Systick定时器开启*参数:TimerID timerid 定时器索引*返回:none*/voidEnable_SysTimer(TimerID timerid){uint8_t Timer_Idx = timerid;userTimer[Timer_Idx].Timer_Enable = 0x01;}/**说明:Systick定时器重置*参数:TimerID timerid 定时器索引*返回:none*/voidReset_SysTimer(TimerID timerid){/*重新获取定时器计数基准*/userTimer[timerid].TimerBaseValue = Get_SystickTimerValue();}
夜雨聆风
