现在的搞法
typedef struct //毫秒延时结构体
{
uint8_t En;
uint32_t Cnt;
}DelayMs_TypeDef;
DelayMs_TypeDef msTimer1;
//初始化定时器
msTimer1.En = 1;
msTimer1.Cnt = 2000; //2000ms
//计时
if(msTimer1.En==1)
{
if(--msTimer1.Cnt==0)
{
msTimer1.En = 0;
}
//这里定时器时间到执行一系列动作
}
这样如果定时器一多,好像就比较繁杂了,初始化和计时又不在同一个地方,求一简单的写法
如:将上诉过程全部封装起来,用一个函数 func1 实现初始化和计时,同时函数参数里面给另外一个函数 func2 的指针 ,func2 函数用来执行定时器时间到之后的动作,并且func2需要传参进去
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
下面是C文件 MCU是STM32F103x
- #include "SysTick.h"
- #include <stdlib.h>
- #include "SEGGER_RTT.h"
- //===================================================================
- #ifndef true
- #define true 1
- #define false 0
- #endif
- //===================================================================
- //------------超时标记变量定义区---------------
- #define TM_OUT_CNT 32 /* 最多超时变量个数,建议不要超过32个*/
- vu32 *gTimOut[TM_OUT_CNT] = {0}; // 超时计数变量指针数组
- // 可以配置多个超时变量
- // 超时变量不可复用,不然会出问题
- // 但是只是变量指针,具体的变量值需要调用TimeOutSet来配置
- static u8 tm_Out_Cnt = 0; // 实际超时变量个数
- //------------定时回调变量定义区----------------
- #define TM_CB_CNT 64
- struct TimCBDef {
- u32 tim;
- void (*hook)(void);
- struct TimCBDef *next;
- };
- struct TimCBDef *_gTimCBPtr = 0;
- u16 _gTimCBSize = 0;
- volatile union SysTickTimerFlag SysTick_T; // 系统时间标志位
- volatile u32 SysTick_MsDelay_T; // SysTick毫秒延时计数
- static u32 SysTick_Timer = 0;
- /**
- * 函数功能: 配置定时回调
- * 输入参数: tset=定时时间(毫秒) hook=回调函数
- * 输出参数: 0=配置成功, -1配置失败
- * 功能说明:
- */
- s8 TimeCallBackSet(u32 tmset, void (*hook)(void))
- {
- if(_gTimCBSize >= TM_CB_CNT)
- return -1;
- struct TimCBDef *tsnewDef = (struct TimCBDef*)malloc(sizeof(struct TimCBDef)); // 新申请一块内存
- if(tsnewDef == NULL)
- return -1;
- tsnewDef->tim = tmset + SysTick_Timer;
- tsnewDef->hook = hook;
- tsnewDef->next = NULL;
- //Jprintf(0,"
=%x %d",hook,_gTimCBSize);
- _gTimCBSize += 1;
- if(_gTimCBSize == 1) {
- _gTimCBPtr = tsnewDef;
- } else {
- if(tsnewDef->tim < _gTimCBPtr->tim) {
- tsnewDef->next = _gTimCBPtr;
- _gTimCBPtr = tsnewDef;
- return 0;
- }
- struct TimCBDef *tstmpDef = _gTimCBPtr; // 当前节点指针
- struct TimCBDef *tslstDef = _gTimCBPtr; // 上一节点
- while(tstmpDef->next != NULL) {
- if(tsnewDef->tim < tstmpDef->tim) {
- tsnewDef->next = tstmpDef;
- tslstDef->next = tsnewDef;
- break;
- }
- tslstDef = tstmpDef;
- tstmpDef = tstmpDef->next;
- }
- if(tsnewDef->next == NULL) {
- if(tsnewDef->tim < tstmpDef->tim) {
- tsnewDef->next = tstmpDef;
- tslstDef->next = tsnewDef;
- } else {
- tstmpDef->next = tsnewDef;
- }
- }
- }
- return 0;
- }
- /**
- * 函数功能: 查看回调链表是否有任务就绪
- */
- static void CheckTimCallback(void)
- {
- if(_gTimCBSize == 0)
- return;
- if(_gTimCBPtr->tim <= SysTick_Timer) {
- struct TimCBDef *tstmpDef = _gTimCBPtr;
- _gTimCBPtr = _gTimCBPtr->next;
- _gTimCBSize -= 1;
- if(tstmpDef->hook != NULL) {
- void (*tshook)(void);
- //Jprintf(0,"
>%x",tstmpDef->hook);
- tshook = tstmpDef->hook;
- free(tstmpDef);
- tshook();
- //Jputs(0,">");
- }
- }
- }
- /**
- * 函数功能: 配置超时指针
- * 输入参数: *ptout 需要传入的超时变量指针
- * 输出参数: 配置结果 0:成功 -1:索引溢出 1:超时指针重复(不影响正常结果)
- * 功能说明: 修改原来实现方式的bug,不再使用idx变量
- 当超过最大允许的超时变量个数时返回-1
- */
- s8 TimeOutSet(vu32 *ptout)
- {
- if(tm_Out_Cnt >= TM_OUT_CNT)
- return -1;
- for(int i=0;i<tm_Out_Cnt;i++) {
- if(ptout == gTimOut[i])
- return 1;
- }
- gTimOut[tm_Out_Cnt] = ptout;
- tm_Out_Cnt++;
- return 0;
- }
- /**
- *函数功能:SysTick初始化
- *函数名称:SysTick_Init
- *输入参数:无
- *输出参数:无
- */
- void SysTick_Init(void)
- {
- if(SysTick_Config(SystemCoreClock / 1000)) { //1ms
- while(1);
- }
- SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择时钟源
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
- NVIC_SetPriority(SysTick_IRQn,4); //中断
- }
- /**
- *SysTick中断服务函数
- *输入参数无
- *输出参数无
- */
- void SysTick_Handler_Service(void)
- {
-
- SysTick_Timer++; // 每个毫秒进行一次累加
- SysTick_MsDelay_T ? SysTick_MsDelay_T-- : 0; // 全局毫秒计数如果不等于0则减一
-
- int i=0;
- while(i<tm_Out_Cnt) { // 扫描超时变量,并且把不为0的变量进行自减一
- *gTimOut[i] ? (*gTimOut[i])-- : 0;
- i++;
- }
- CheckTimCallback(); // 查看定时回调任务就绪情况
-
- /* if嵌套原则: 一定是有约数关系才能嵌套,而且选择最大的约数嵌套,
- 如500可以和20嵌套也可以和50嵌套,则选50,
- 目的为减少判断次数
- */
- if(SysTick_Timer%10!=0) // 10ms判断一次,用于减少判断次数
- return;
- if(SysTick_Timer%20==0) SysTick_T.bits._20ms = true; // 20ms 标志置位
- if(SysTick_Timer%50==0) { SysTick_T.bits._50ms = true; // 50ms 标志置位
- if(SysTick_Timer%100==0) { SysTick_T.bits._100ms = true; // 250ms 标志置位
- if(SysTick_Timer%500==0) { SysTick_T.bits._500ms = true; // 500ms 标志置位
- if(SysTick_Timer%1000 == 0) { SysTick_T.bits._1000ms = true; // 1000ms 标志置位
- if(SysTick_Timer%2000 == 0) { SysTick_T.bits._2000ms = true; // 2000ms 标志置位
- if(SysTick_Timer%60000 == 0) { SysTick_T.bits._60s = true; // 60秒 标志置位
- }
- }
- }
- }
- }
- }
- }
复制代码- #ifndef __SYSTICK_H
- #define __SYSTICK_H
- #include "stm32f10x.h"
- //--------------------定义区----------------------
- union SysTickTimerFlag //系统时间标志位
- {
- uint16_t Flag;
- struct {
- // uint8_t _10ms :1; // 10ms 标志
- uint8_t _20ms :1; // 20ms 标志
- uint8_t _50ms :1; // 50ms 标志
- uint8_t _100ms :1; // 100ms 标志
- // uint8_t _250ms :1; // 250ms 标志
- uint8_t _500ms :1; // 500ms 标志
- uint8_t _1000ms :1; // 1000ms 标志
- uint8_t _2000ms :1; // 2000ms 标志
- // uint8_t _30s :1; // 30秒 标志
- uint8_t _60s :1; // 60秒 标志
- }bits;
- };
- //===================对外变量声明===========================
- extern volatile union SysTickTimerFlag SysTick_T; // 系统时间标志位,(用于查看各个定时时间段的标志位,不允许对变量赋值)
- //===================对外函数接口===========================
- void SysTick_Init(void); // SysTick初始化
- s8 TimeCallBackSet(u32 tmset, void (*hook)(void)); // 定时回调,tmset=回调时间(毫秒), hook= 定时时间到的回调函数
- s8 TimeOutSet(vu32 *ptout); // 超时变量配置(在用到超时变量时,需要提前调用此函数进行初始化)
- #endif
复制代码谢谢,好好研究研究
一周热门 更多>