闹钟提醒我们该吃饭吃饭,该睡觉睡觉
原文地址:http://blog.csdn.net/u011833609/article/details/28862125
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
#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
软件定时器-闹钟提醒我们该吃饭吃饭,该睡觉睡觉,布布扣,bubuko.com
原文:http://blog.csdn.net/u011833609/article/details/28862125