【单片机】高复用Systick定时器

前言:该定时器设计方法使用Systick中断机制实现。

1.定义定时器结构

包含:软件定时器数量、工作模式、结构体成员

#define TMR_NUM 15//软件定时器数量

typedef enum
{
    TMR_ONCE_MODE = 0; //一次性工作模式
    TMR_AUTO_MDOE = 1; //自动定时工作模式  
}TMR_MDDE_E;

//定时器结构体,成员必须volatile,否则C编译器优化可能有问题
typedef struct
{
    volatile uint8_t Mode;     //计数器模式
    volatile uint8_t Flag;     //定时器到达标志
    volatile uint32_t Count;   //计数器
    volatile uint32_t PreLoad; //计数器预装载值
}SOFT_TMR;

函数应用层面

//定义软件定时器结构体变量
static SOFT_TMR s_tTmr[TMR_NUM];

//基于systick的中断的定时初始化清空
void bsp_InitTimer(void)
{
    uint8_t i;
    //清空软件定时器
    for(i=0;i<TMR_NUM;i++)
    {
        s_tTmr[i].Count = 0;
        s_tTmr[i].PreLoad = 0;
        s_tTmr[i].Flag = 0;
        s_tTmr[i].Mode = TMR_ONCE_MODE;
    }
    SysTick_Config(FREQ_SYS / 1000);//设定滴答定时器
}
//每隔1ms对所有定时器变量-1.必须被SysTick_ISR周期调用
stattic void bsp_SoftTimeDec(SOFT_TMR *_tmr)
{
    if(_tmr->Count > 0)//启用了定时器
    {
        //如果定时器变量减到1则设置定时器到达标志
        if(--_tmr-> == 0)
        {
            _tmr->Flag = 1;
            //如果是自动模式,则自动重装计数器
            if(_tmr->Mode == TMR_AUTO_MODE)
            {
                _tmr->Count = _tmr->PreLoad;
            }
        }
    }
}
__IO int32_t g_iRunTime = 0;

void SysTick_ISR(void)
{
    uint8_t i;
    //每隔1ms进去一次(Delay_ms)
    if(s_uiDelayCount > 0)
    {
        if(--s_uiDelayCount == 0)
        {
            s_ucTimeOutFlag = 1;
        }
    }
    //定时器:每隔1ms对软件定时器进行减1操作
    for(i=0;i < TMR_NUM; i++)
    {
        bsp_softTimerDec(&s_tTmr[i]);
    }
    //全局运行时间
    g_iRunTime++;
    if(g_iRrunTime == 0x7FFFFFFFF)//int32_t类型
    {
        g_iRunTime = 0;//避免溢出
    }
}
/*
功能:启动一个定时器,并设定周期。
形参: _id     : 定时器ID,值域[0,TMR_NUM-1]。用户自行维护定时器ID,避免定时器ID冲突。
    _Period :   定时周期,单位1ms
*/
void bsp_StartTimer(uint8_t _id, uint32_t _period)
{
    if(_id >= TMR_NUM)
    {
        //参数异常
        //执行复位
           while(1);
    }
    s_tTmr[id].Count = _period;   //实时定时器初值
    s_tTmr[id].PreLoad = _period; //自动重装载值,仅自动模式生效
    s_tTmr[id].Flag = 0;          //定时时间到达标志
    s_tTmr[id].Mode = TMR_ONCE_MODE;//一次性工作模式
}


/*
功能:启动一个自动定时器,并设定周期。
形参: _id     : 定时器ID,值域[0,TMR_NUM-1]。用户自行维护定时器ID,避免定时器ID冲突。
    _Period :   定时周期,单位1ms
*/
void bsp_StartAutoTimer(uint8_t _id, uint32_t _period)
{
    if(_id >= TMR_NUM)
    {
        //参数异常
        //执行复位
           while(1);
    }
    s_tTmr[id].Count = _period;   //实时定时器初值
    s_tTmr[id].PreLoad = _period; //自动重装载值,仅自动模式生效
    s_tTmr[id].Flag = 0;          //定时时间到达标志
    s_tTmr[id].Mode = TMR_AUTO_MODE;//一次性工作模式
}
/* 停止定时器 _id 停止的ID */
void bsp_StopTimer(unt8_t _id)
{
    if(id >= TMR_NUM){while(1);}
    s_tTmr[_id].Count = 0;
    s_tTmr[_id].Flag = 0;
    s_tTmr[_id].Mode = TMR_ONCE_MODE;
}
/* 检查定时器是否超时 */
uint8_t bsp_CheckTimer(uint8_t _id)
{
    if(_id >= TMR_NUM){return 0;}
    if(s_tTmr[id].Flag == 1)
    {
        s_tTmr[_id].Flag = 0;
        return 1;//时间已到达
    }
    else
    {
        return 0;//时间未到达
    }
}

void SysTick_Handler()
{
    Systick_ISR();
    SysTick->SR=0;//清中断标志
}

总体的.c接口文件

//该代码为软件定时器创建代码
//定义软件定时器结构体变量
#include "DE_FIFO.h"

static xdata SOFT_TMR s_tTmr[TMR_NUM];

static volatile unsigned int xdata s_uiDelayCount = 0;
static volatile unsigned char xdata s_ucTimeOutFlag = 0;
volatile unsigned short xdata u16_SysTickCnt = 0;
//基于systick的中断的定时初始化清空
void bsp_InitTimer(void)
{
    unsigned int i;
    //清空软件定时器
    for(i=0;i<TMR_NUM;i++)
    {
        s_tTmr[i].Count = 0;
        s_tTmr[i].PreLoad = 0;
        s_tTmr[i].Flag = 0;
        s_tTmr[i].Mode = TMR_ONCE_MODE;
    }
//    SysTick_Config(FREQ_SYS / 1000);//设定滴答定时器
}
//每隔1ms对所有定时器变量-1.必须被SysTick_ISR周期调用
static void bsp_SoftTimeDec(SOFT_TMR *_tmr)
{
    if(_tmr->Count > 0)//启用了定时器
    {
        //如果定时器变量减到1则设置定时器到达标志
        if(--_tmr->Count == 0)
        {
            _tmr->Flag = 1;
            //如果是自动模式,则自动重装计数器
            if(_tmr->Mode == 1)
            {
                _tmr->Count = _tmr->PreLoad;
            }
        }
    }
}
void SysTick_ISR(void)
{
    unsigned short i;
    //每隔1ms进去一次(Delay_ms)
    if(s_uiDelayCount > 0)
    {
        if(--s_uiDelayCount == 0)
        {
            s_ucTimeOutFlag = 1;
        }
    }
    //定时器:每隔1ms对软件定时器进行减1操作
    for(i=0;i < TMR_NUM; i++)
    {
        bsp_SoftTimeDec(&s_tTmr[i]);
    }
    /*
    //全局运行时间
    g_iRunTime++;
    if(g_iRrunTime == 0x7FFFFFFFF)//int32_t类型
    {
        g_iRunTime = 0;//避免溢出
    }
    */
}

/*
功能:启动一个定时器,并设定周期。
形参: _id     : 定时器ID,值域[0,TMR_NUM-1]。用户自行维护定时器ID,避免定时器ID冲突。
    _Period :   定时周期,单位1ms
*/
void bsp_StartTimer(unsigned char _id, unsigned int _period)
{
    if(_id >= TMR_NUM)
    {
        //参数异常
        //执行复位
         while(1);
    }
    s_tTmr[_id].Count = _period;   //实时定时器初值
    s_tTmr[_id].PreLoad = _period; //自动重装载值,仅自动模式生效
    s_tTmr[_id].Flag = 0;          //定时时间到达标志
    s_tTmr[_id].Mode = TMR_ONCE_MODE;//一次性工作模式
}


/*
功能:启动一个自动定时器,并设定周期。
形参: _id     : 定时器ID,值域[0,TMR_NUM-1]。用户自行维护定时器ID,避免定时器ID冲突。
    _Period :   定时周期,单位1ms
*/
/*
void bsp_StartAutoTimer(unsigned char _id, unsigned int _period)
{
    if(_id >= TMR_NUM)
    {
        //参数异常
        //执行复位
           while(1);
    }
    s_tTmr[_id].Count = _period;   //实时定时器初值
    s_tTmr[_id].PreLoad = _period; //自动重装载值,仅自动模式生效
    s_tTmr[_id].Flag = 0;          //定时时间到达标志
    s_tTmr[_id].Mode = TMR_AUTO_MDOE;//一次性工作模式
}
*/
/* 停止定时器 _id 停止的ID */
void bsp_StopTimer(unsigned char _id)
{
    if(_id >= TMR_NUM){while(1);}
    s_tTmr[_id].Count = 0;
    s_tTmr[_id].Flag = 0;
    s_tTmr[_id].Mode = TMR_ONCE_MODE;
}

/* 检查定时器是否超时 */
unsigned char bsp_CheckTimer(unsigned char _id)
{
    if(_id >= TMR_NUM){return 0;}
    if(s_tTmr[_id].Flag == 1)
    {
        s_tTmr[_id].Flag = 0;
        return 1;//时间已到达
    }
    else
    {
        return 0;//时间未到达
    }
}
/*中断处理
void SysTick_Handler()
{
    Systick_ISR();
    SysTick->SR=0;//清中断标志
}
*/

总体的.h接口文件

#define TMR_NUM 15 //software timmer
#define uint8_t unsigned char xdata
#define uint16_t unsigned int xdata
#define uint32_t unsigned int xdata 
typedef enum
{
    TMR_ONCE_MODE = 0,
    TMR_AUTO_MDOE = 1
}TMR_MDDE_E;


typedef struct
{
    unsigned char Mode;
    unsigned char Flag;
    unsigned int Count;
    unsigned int PreLoad;
}SOFT_TMR;

void bsp_InitTimer(void);
void SysTick_ISR(void);
void bsp_StartTimer(unsigned char _id, unsigned int _period);
void bsp_StartAutoTimer(unsigned char _id, unsigned int _period);
void bsp_StopTimer(unsigned char _id);
unsigned char bsp_CheckTimer(unsigned char _id);
void bsp_SoftTimeDec(SOFT_TMR *_tmr);
//调用放在timer中断或者systick中断

void timmer_iSR()//自动重装载模式
{
    SysTick_ISR();//软件定时器
}	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值