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

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

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

softwaretimer.h

#ifndef _SOFTWARETIMER_H_
#define _SOFTWARETIMER_H_

typedef enum{z_false = 0, z_true = !z_false}         z_bool;
typedef unsigned char                                z_uchar;
typedef unsigned char                                z_u8;
typedef char                                         z_char;
typedef char                                         z_s8;
typedef unsigned short int                           z_u16;
typedef short int                                    z_s16;
typedef unsigned int                                 z_u32;
typedef int                                          z_s32;
typedef unsigned long long                           z_u64;
typedef long long                                    z_s64;
typedef float                                        z_float;
typedef double                                       z_double;

/*
* 此软件定时器是对硬件定时器的扩展,这些软件定时器,通过查询方式工作,即开启定时器后,
* 需要手动查看定时器时间是否到,自动填充计数初值的实现是在查询的时候完成的
*/
//软件定时器相关参数
enum
{
    S_TIMER_INIT_VAL         = 0x01ff,        //定时器初值,设置系统定时器为1Ms中断一次
    S_TIMER_COUNT_MAX_VAL    = 0x10000000,    //定时器计数最大值
    S_TIMER_ERROR_VAL        = 0x7FFFFFFF,    //定时器取值错误值
    
    S_TIMER_PUBLIC_NUM       = 5,             //公用定时器个数
    S_TIMER_PRIVATE_NUM      = 1,             //专用定时器个数
};

//软件定时器项列表
typedef enum
{
    /*公用定时器*/
    S_TIMER_PUBLIC_1,    //公用定时器1
    S_TIMER_PUBLIC_2,    //公用定时器2
    S_TIMER_PUBLIC_3,    //公用定时器3
    S_TIMER_PUBLIC_4,    //公用定时器4
    S_TIMER_PUBLIC_5,    //公用定时器5
    
    /*专用定时器*/
    S_TIMER_PRIVATE_1,   //专用定时器1(专用定时器可直接用名字表示,如S_TIMER_MEDIA_WAIT)
    
    /*公用定时器获取失败返回值*/
    S_TIMER_NO_FREE_TIMER    = 0xFFFF,        //没有空闲的定时器了
}S_TIMER_ITEM;

//软件定时器状态定义
typedef enum
{
    S_TIMER_IS_CLOSE,
    S_TIMER_IS_OPEN,
}S_TIMER_STATE;

//软件定时器定时单位
typedef enum
{
    S_TIMER_1000MS,
    S_TIMER_100MS,
    S_TIMER_10MS,
}S_TIMER_UNIT;

//软件定时器工作类型
typedef enum
{
    S_TIMER_MANUAL_INIT,   //定时器需手动填充计数值,一次计数完成,自动关闭,如再次使用需重新手动启动定时器
    S_TIMER_AUTO_INIT,     //定时器开启后,自动填充计数值,保存中断次数,需手动关闭
}S_TIMER_WORK_TYPE;

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

//获取公用定时器编号
S_TIMER_ITEM S_TimerGetPublicFreeTimer(void);
//软件定时器操作-打开定时器
z_bool S_TimerOpen(S_TIMER_ITEM, S_TIMER_UNIT, S_TIMER_WORK_TYPE, z_s32);
//软件定时器操作-关闭定时器
z_bool S_TimerClose(S_TIMER_ITEM);
//软件定时器查询-获取定时器定时值
//说明:获取到的值小于0表示定时时间未到
//      获取到的值等于0表示定时时间刚到
//      获取到的值大于0表示定时时间已超
//      获取到的值等于S_TIMER_ERROR_VAL表示无该定时器或定时器已关闭
z_s32  S_TimerGetTimerVal(S_TIMER_ITEM);

#endif

softwaretimer.c

#include "softwaretimer.h"

//软件定时器结构定义
typedef struct
{
    S_TIMER_STATE           eState;        //定时器状态
    S_TIMER_UNIT            eUnit;         //定时器单位
    S_TIMER_WORK_TYPE       eWorkType;     //定时器工作类型
    z_s32                   s32Timer;      //定时时间
    z_s32                   s32InitVal;    //定时器初值记录
}S_Timer_TypeDef;

static z_s32 s_S_TimerCount = 0;
static S_Timer_TypeDef s_S_Timer[S_TIMER_PUBLIC_NUM + S_TIMER_PRIVATE_NUM];

//将系统定时器初始化
z_bool S_TimerInit(void)
{
    //配置硬件定时器为1ms中断一次
    //启动定时器
    return z_true;
}

//系统定时器中断函数,记录中断次数,即软件定时器运行时长,单位ms
void SystemTimer_Handler(void)
{
    s_S_TimerCount = (s_S_TimerCount + 1) % S_TIMER_COUNT_MAX_VAL;
}

//获取公用定时器编号
S_TIMER_ITEM S_TimerGetPublicFreeTimer(void)
{
    S_TIMER_ITEM eTimerItem = S_TIMER_NO_FREE_TIMER;
    static z_s16 s16Loop = 0;
    
    for(s16Loop = 0; s16Loop < S_TIMER_PUBLIC_NUM; s16Loop++)
    {
        if(S_TIMER_IS_CLOSE == s_S_Timer[s16Loop].eState)
        {
            eTimerItem = (S_TIMER_ITEM)s16Loop;
            break;
        }
    }
    
    return eTimerItem;
}

//软件定时器操作-打开定时器
//打开软件定时器eTimer,设置为eTimerType类型的eTimerWorkType工作类型,定时时间值为s32TimerVal
z_bool S_TimerOpen(S_TIMER_ITEM eTimer, S_TIMER_UNIT eTimerUnit, S_TIMER_WORK_TYPE eTimerWorkType, z_s32 s32TimerVal)
{
    z_bool zbRetVal = z_false;
    
    if(S_TIMER_IS_CLOSE == s_S_Timer[eTimer].eState)
    {
        s_S_Timer[eTimer].s32InitVal = s_S_TimerCount;
        s_S_Timer[eTimer].eWorkType = eTimerWorkType;
        s_S_Timer[eTimer].s32Timer = s32TimerVal;
        s_S_Timer[eTimer].eUnit = eTimerUnit;
        s_S_Timer[eTimer].eState = S_TIMER_IS_OPEN;
        zbRetVal = z_true;
    }
    
    return zbRetVal;
}

//软件定时器操作-关闭定时器
//关闭软件定时器eTimer
z_bool S_TimerClose(S_TIMER_ITEM eTimer)
{
    z_bool zbRetVal = z_false;
    
    if(S_TIMER_IS_OPEN == s_S_Timer[eTimer].eState)
    {
        s_S_Timer[eTimer].eState = S_TIMER_IS_CLOSE;
        zbRetVal = z_true;
    }
    
    return zbRetVal;
}

//软件定时器查询-获取定时器定时值
//说明:获取到的值小于0表示定时时间未到
//      获取到的值等于0表示定时时间刚到
//      获取到的值大于0表示定时时间已超
//      获取到的值等于S_TIMER_ERROR_VAL表示无该定时器或定时器已关闭
z_s32  S_TimerGetTimerVal(S_TIMER_ITEM eTimer)
{
    z_s32 s32TimerVal = S_TIMER_ERROR_VAL;
    z_s32 s32TimerCount = 0;
    z_s32 s32TimerAddCount = 0;
    
    if((eTimer < S_TIMER_PRIVATE_NUM + S_TIMER_PUBLIC_NUM) && (S_TIMER_IS_OPEN == s_S_Timer[eTimer].eState))
    {
        s32TimerCount = (s_S_TimerCount + S_TIMER_COUNT_MAX_VAL - s_S_Timer[eTimer].s32InitVal) % S_TIMER_COUNT_MAX_VAL;
        
        switch(s_S_Timer[eTimer].eUnit)
        {
        case S_TIMER_1000MS:
            s32TimerVal = (s32TimerCount / 1000) - s_S_Timer[eTimer].s32Timer;
            s32TimerAddCount = s_S_Timer[eTimer].s32Timer * 1000;
            break;
        case S_TIMER_100MS:
            s32TimerVal = (s32TimerCount / 100) - s_S_Timer[eTimer].s32Timer;
            s32TimerAddCount = s_S_Timer[eTimer].s32Timer * 100;
            break;
        case S_TIMER_10MS:
            s32TimerVal = (s32TimerCount / 10) - s_S_Timer[eTimer].s32Timer;
            s32TimerAddCount = s_S_Timer[eTimer].s32Timer * 10;
            break;
        default:
            break;
        }
        
        if((S_TIMER_ERROR_VAL != s32TimerVal) && (s32TimerVal >= 0))
        {
            switch(s_S_Timer[eTimer].eWorkType)
            {
            case S_TIMER_MANUAL_INIT:
                s_S_Timer[eTimer].eState = S_TIMER_IS_CLOSE;
                break;
            case S_TIMER_AUTO_INIT:
                s_S_Timer[eTimer].s32InitVal = (s_S_Timer[eTimer].s32InitVal + s32TimerAddCount) % S_TIMER_COUNT_MAX_VAL;
                break;
            default:
                break;
            }
        }
    }
    
    return s32TimerVal;
}

#if 0 //测试函数
void SoftwareTimerTest(void)
{
    static z_u8 u8TestStep = 0;
    static S_TIMER_ITEM eTimerA = S_TIMER_NO_FREE_TIMER;
    z_s32 s32TimerVal = 0;
    
    switch(u8TestStep)
    {
        case 1:
            if((eTimerA = S_TimerGetPublicFreeTimer()) != S_TIMER_NO_FREE_TIMER)
            {
                u8TestStep = 2;
            }
            break;
        case 2:
            if(S_TimerOpen(eTimerA, S_TIMER_100MS, S_TIMER_AUTO_INIT, 3))
            {
                u8TestStep = 3;
            }
            break;
        case 3:
            s32TimerVal = S_TimerGetTimerVal(eTimerA);
            if((S_TIMER_ERROR_VAL != s32TimerVal) && (s32TimerVal >= 0))
            {
                printf("\r\n eTimerA OverTime \r\n");
            }
            break;
        case 4:
            S_TimerClose(eTimerA);
            u8TestStep = 0;
            break;
        default:
            break;
    }
}

#endif