首页 > 代码库 > 软件定时器-闹钟提醒我们该吃饭吃饭,该睡觉睡觉

软件定时器-闹钟提醒我们该吃饭吃饭,该睡觉睡觉

闹钟提醒我们该吃饭吃饭,该睡觉睡觉

softwaretimer.h

#ifndef _SOFTTIMER_H_
#define _SOFTTIMER_H_

#include "stdreader.h"

/*
* 此软件定时器是对硬件定时器的扩展,这些软件定时器,通过查询方式工作,即开启定时器后,
* 须要手动查看定时器时间是否到,自己主动填充计数初值的实现是在查询的时候完毕的
*/
//软件定时器相关參数
enum
{
    ST_INIT_VAL         = 0x01ff,        //定时器初值,设置系统定时器为1Ms中断一次
    ST_COUNT_MAX_VAL    = 0x10000000,    //定时器计数最大值
    ST_ERROR_VAL        = 0x7FFFFFFF,    //定时器取值错误值
    
    ST_PUBLIC_NUM       = 0,             //公用定时器个数
    ST_PRIVATE_NUM      = 5,             //专用定时器个数
    ST_NUMBER           = ST_PUBLIC_NUM + ST_PRIVATE_NUM, //软件定时器总个数
};

//软件定时器项列表
typedef enum
{
    /*公用定时器,不用写定时器名字。定义公用定时器个数就能够*/
    
    /*专用定时器*/
    ST_TERMINAL_OPERATION    = ST_PUBLIC_NUM,   //专用定时器1(专用定时器可直接用名字表示,如SOFTTIMER_MEDIA_WAIT)
    
    ST_JT808_HEARTBEAT,
    ST_JT808_CHECKAREAALARM,
    ST_JT808_CHECKSIGNALSTATE,
    ST_JT808_CHECKALARMSTATE,
    ST_JT808_CAMERAWORK,
    
    /*公用定时器获取失败返回值*/
    ST_NO_FREE_TIMER    = 0xFFFF,        //没有空暇的定时器了
}SOFTTIMER_ITEM;

//软件定时器状态定义
typedef enum
{
    ST_IS_CLOSE,
    ST_IS_OPEN,
}SOFTTIMER_OPEN_STATE;

//软件定时器定时单位
typedef enum
{
    ST_10MS    = 10,
    ST_100MS   = 100,
    ST_1000MS  = 1000,
}SOFTTIMER_UNIT;

//软件定时器工作类型
typedef enum
{
    ST_INIT_MANUAL,   //定时器需手动填充计数值。一次计数完毕,自己主动关闭。如再次使用需又一次手动启动定时器
    ST_INIT_AUTO,     //定时器开启后。自己主动填充计数值,保存中断次数,需手动关闭
}SOFTTIMER_WORK_TYPE;

typedef enum
{
    ST_RUN_MANUAL,
    ST_RUN_AUTO,
}SOFTTIMER_RUN_TYPE;

typedef enum
{
    ST_IS_ERROR,
    ST_IS_SLEEPING,
    ST_IS_RUNNING,
}SOFTTIMER_CLOCK_STATE;

//软件定时器定时基础-系统硬件定时器初始化函数
z_bool SoftTimerInit(void);
//软件定时器定时基础-系统硬件定时器中断函数
void SystemTimer_Handler(void);

//软件定时器自己主动执行调度接口
void SoftTimerAutoRuning(void);

//获取公用定时器编号
SOFTTIMER_ITEM SoftTimerGetPublicFreeTimer(void);
//软件定时器操作-打开定时器
z_bool SoftTimerOpen(SOFTTIMER_ITEM eTimer, SOFTTIMER_RUN_TYPE eTimeRunType, SOFTTIMER_WORK_TYPE eTimerWorkType, SOFTTIMER_UNIT eTimerUnit, z_s32 s32TimerVal, void (*)(void));
//软件定时器操作-又一次打开定时器
z_bool SoftTimerReOpen(SOFTTIMER_ITEM eTimer, SOFTTIMER_RUN_TYPE eTimeRunType, SOFTTIMER_WORK_TYPE eTimerWorkType, SOFTTIMER_UNIT eTimerUnit, z_s32 s32TimerVal, void (*)(void));
//软件定时器操作-关闭定时器
z_bool SoftTimerClose(SOFTTIMER_ITEM);
//软件定时器操作-获取定时器闹钟状态
SOFTTIMER_CLOCK_STATE SoftTimerGetTimerClockState(SOFTTIMER_ITEM eTimer);
//软件定时器操作-获取定时器开启状态
SOFTTIMER_OPEN_STATE SoftTimerGetTimerOpenState(SOFTTIMER_ITEM eTimer);

#endif

softwaretimer.c

#include "softtimer.h"

//软件定时器结构定义
typedef struct
{
    SOFTTIMER_OPEN_STATE    eOpenState;    //定时器状态
    SOFTTIMER_RUN_TYPE      eRunType;      //定时器执行类型
    SOFTTIMER_WORK_TYPE     eWorkType;     //定时器工作类型
    SOFTTIMER_UNIT          eUnit;         //定时器单位
    z_s32                   s32Timer;      //定时时间
    z_s32                   s32InitVal;    //定时器初值记录
    void (*pFun)(void);                    //定时时间到执行函数
}SOFTTIMER_TypeDef;

static z_s32 s_SoftTimerCount = 0;
static SOFTTIMER_TypeDef s_SoftTimer[ST_NUMBER];

//系统定时器中断函数。记录中断次数,即软件定时器执行时长。单位ms
void SystemTimer_Handler(void)
{
    s_SoftTimerCount = (s_SoftTimerCount + 10) % ST_COUNT_MAX_VAL;
}

//将系统定时器初始化
z_bool SoftTimerInit(void)
{
    z_u16 u16Loop = 0;
    
    //配置硬件定时器为10ms中断一次
    
    for(u16Loop = 0; u16Loop < ST_NUMBER; u16Loop++)
    {
        s_SoftTimer[u16Loop].eOpenState = ST_IS_CLOSE;
    }
    //启动定时器
    return z_true;
}

//软件定时器主调度函数
void SoftTimerAutoRuning(void)
{
    z_u16 u16Loop = 0;
    
    for(u16Loop = 0; u16Loop < ST_NUMBER; u16Loop++)
    {
        if(ST_IS_OPEN == s_SoftTimer[u16Loop].eOpenState)
        {
            if(ST_RUN_AUTO == s_SoftTimer[u16Loop].eRunType)
            {
                if(ST_IS_RUNNING == SoftTimerGetTimerClockState((SOFTTIMER_ITEM)u16Loop))
                {
                    s_SoftTimer[u16Loop].pFun();
                }
            }
        }
    }
}

//申请公用定时器。返回申请到的编号或无空暇软件定时器
SOFTTIMER_ITEM SoftTimerGetPublicFreeTimer(void)
{
    SOFTTIMER_ITEM eTimerItem = ST_NO_FREE_TIMER;
    z_s16 s16Loop = 0;
    
    for(s16Loop = 0; s16Loop < ST_PUBLIC_NUM; s16Loop++)
    {
        if(ST_IS_CLOSE == s_SoftTimer[s16Loop].eOpenState)
        {
            eTimerItem = (SOFTTIMER_ITEM)s16Loop;
            break;
        }
    }
    
    return eTimerItem;
}

//软件定时器操作-打开定时器
//打开软件定时器eTimer。设置为eTimerType类型的eTimerWorkType工作类型。定时时间值为s32TimerVal
z_bool SoftTimerOpen(SOFTTIMER_ITEM eTimer, SOFTTIMER_RUN_TYPE eTimeRunType, SOFTTIMER_WORK_TYPE eTimerWorkType, SOFTTIMER_UNIT eTimerUnit, z_s32 s32TimerVal, void (*pFunc)(void))
{
    z_bool zbRetVal = z_false;
    
    if(ST_IS_CLOSE == s_SoftTimer[eTimer].eOpenState)
    {
        s_SoftTimer[eTimer].s32InitVal = s_SoftTimerCount;
        s_SoftTimer[eTimer].eOpenState = ST_IS_OPEN;
        s_SoftTimer[eTimer].eRunType = eTimeRunType;
        s_SoftTimer[eTimer].eWorkType = eTimerWorkType;
        s_SoftTimer[eTimer].eUnit = eTimerUnit;
        s_SoftTimer[eTimer].s32Timer = s32TimerVal;
        s_SoftTimer[eTimer].pFun = pFunc;
        zbRetVal = z_true;
    }
    
    return zbRetVal;
}
//软件定时器操作-又一次打开定时器
//打开软件定时器eTimer,设置为eTimerType类型的eTimerWorkType工作类型,定时时间值为s32TimerVal
z_bool SoftTimerReOpen(SOFTTIMER_ITEM eTimer, SOFTTIMER_RUN_TYPE eTimeRunType, SOFTTIMER_WORK_TYPE eTimerWorkType, SOFTTIMER_UNIT eTimerUnit, z_s32 s32TimerVal, void (*pFunc)(void))
{
    z_bool zbRetVal = z_false;
    
    if(SoftTimerClose(eTimer))
    {
        zbRetVal = SoftTimerOpen(eTimer, eTimeRunType, eTimerWorkType, eTimerUnit, s32TimerVal, pFunc);
    }
    
    return zbRetVal;
}

//软件定时器操作-关闭定时器
//关闭软件定时器eTimer
z_bool SoftTimerClose(SOFTTIMER_ITEM eTimer)
{
    z_bool zbRetVal = z_false;
    
    if(ST_IS_OPEN == s_SoftTimer[eTimer].eOpenState)
    {
        s_SoftTimer[eTimer].eOpenState = ST_IS_CLOSE;
        zbRetVal = z_true;
    }
    
    return zbRetVal;
}
//软件定时器操作-获取定时器计数值
z_s32 SoftTimerGetTimerCount(SOFTTIMER_ITEM eTimer)
{
    z_s32 s32TimerCount = ST_ERROR_VAL;
    
    if((eTimer < ST_NUMBER) && (ST_IS_OPEN == s_SoftTimer[eTimer].eOpenState))
    {
        s32TimerCount = (s_SoftTimerCount + ST_COUNT_MAX_VAL - s_SoftTimer[eTimer].s32InitVal) % ST_COUNT_MAX_VAL;
        
        switch(s_SoftTimer[eTimer].eUnit)
        {
        case ST_10MS:
        case ST_100MS:
        case ST_1000MS:
            s32TimerCount = (s32TimerCount / s_SoftTimer[eTimer].eUnit) - s_SoftTimer[eTimer].s32Timer;
            break;
        default:
            break;
        }
    }
    
    return s32TimerCount;
}
//更新软件定时器
z_bool SoftTimerUpdateAutoInitVal(SOFTTIMER_ITEM eTimer)
{
    z_bool zbRetVal = z_false;
    
    if((eTimer < ST_NUMBER) && (ST_IS_OPEN == s_SoftTimer[eTimer].eOpenState))
    {
        s_SoftTimer[eTimer].s32InitVal = (s_SoftTimer[eTimer].s32InitVal + s_SoftTimer[eTimer].s32Timer* s_SoftTimer[eTimer].eUnit) % ST_COUNT_MAX_VAL;
        zbRetVal = z_true;
    }
    
    return zbRetVal;
}

//软件定时器查询-获取定时器定时状态
SOFTTIMER_CLOCK_STATE SoftTimerGetTimerClockState(SOFTTIMER_ITEM eTimer)
{
    SOFTTIMER_CLOCK_STATE eClockState = ST_IS_ERROR;
    z_s32 s32TimerCount = 0;
    
    s32TimerCount = SoftTimerGetTimerCount(eTimer);
    
    if(ST_ERROR_VAL != s32TimerCount)
    {
        eClockState = (s32TimerCount < 0) ? ST_IS_SLEEPING : ST_IS_RUNNING;
        
        if(ST_IS_RUNNING == eClockState)
        {
            switch(s_SoftTimer[eTimer].eWorkType)
            {
            case ST_INIT_MANUAL:
                SoftTimerClose(eTimer);
                break;
            case ST_INIT_AUTO:
                SoftTimerUpdateAutoInitVal(eTimer);
                break;
            default:
                eClockState = ST_IS_ERROR;
                break;
            }
        }
    }
    
    return eClockState;
}
//软件定时器操作-获取定时器开启状态
SOFTTIMER_OPEN_STATE SoftTimerGetTimerOpenState(SOFTTIMER_ITEM eTimer)
{
    return s_SoftTimer[eTimer].eOpenState;
}



软件定时器-闹钟提醒我们该吃饭吃饭,该睡觉睡觉