[古董贴][测试]用于OurRobotV1的实时延时模块(Real Time Delay Module)
#ifndef _USE_SYSTEM_DELAY_H#define _USE_SYSTEM_DELAY_H
/***********************************************************
*函数库说明:系统并行延时函数库 *
*版本: v1.01 *
*作者: 傻孩子 *
*日期: 2005年8月15日 *
* -------------------------------------------------------- *
*[支持库] *
*库名称: RD_MacroAndConst.h *
*需要版本:v0.01 &abv *
*函数库说明:系统常用宏定义库 *
* -------------------------------------------------------- *
*修改: 傻孩子 *
*修改日期:2006月4月11日 *
*版本升级:v1.0 *
* *
*修改: 傻孩子 *
*修改日期:2006年4月16日 *
*版本: v1.01 *
* -------------------------------------------------------- *
*[版本历史] *
* v1.0 从原来的程序代码中提取了该函数库,支持系统*
* 并行延时,支持外部修改缓冲区大小。 *
* v1.01 使用了统一的代码插入接口标准。 *
* -------------------------------------------------------- *
*[说明] *
* 1、在您需要使用该函数之前引用该头文件 *
* 2、在您的毫秒定时器中断处理程序里面调用函数 *
* SD_INSERT_MS_TIMER_OVF_ISR_CODE以确保函数 *
* 库正常使用。 *
* 3、在系统初始化程序里面增加对该系统初始化函数*
* SystemMsDelayInit()的调用 *
* 4、通过调用addDelayItems(n)函数来添加一个延时*
* 该操作成功将会返回一个用于查询的句柄;否则 *
* 返回False(0)。 *
* 5、通过函数IfTimeOut(句柄)来查询句柄代表的那 *
* 个延时是否完成True/False。如果出现错误会 *
* 返回SD_ERROR标志。 *
* 6、通过在引用该头文件之前定义宏: *
* SD_DELAY_BUFF_COUNT来设定缓冲区的大小。 *
***********************************************************/
# include <RD_MacroAndConst.h>
/***********************
* 系 统 宏 定 义 *
***********************/
/*---------------------*
* 常 量 宏 定 义 *
*---------------------*/
#ifndef SD_DELAY_BUFF_COUNT
# define SD_DELAY_BUFF_COUNT 16
#endif
# define SD_ERROR 0xAD
# define SD_IN_USE 0x01
# define SD_FREE 0x00
# define SD_COMPLETE 0xAC
/*---------------------*
* 动 作 宏 定 义 区*
*---------------------*/
# define SD_INSERT_MS_TIMER_OVF_ISR_CODE refreshSystemMsDelay();
/***********************
* 全局变量声明区 *
***********************/
unsigned int DelayBuff;
char DelayBuffState;
char PointHead = 0;
char PointTail = 0;
char DelayItemsCounter = 0;
/***********************
* 函 数 声 明 区 *
***********************/
void SystemMsDelayInit(void);
char addDelayItems(unsigned int DelayTime);
char IfTimeOut(char ItemID);
void refreshSystemMsDelay(void);
/********************************************************
*函数说明:系统延时函数初始化 *
********************************************************/
void SystemMsDelayInit(void)
{
char a = 0;
for (a = 0;a<SD_DELAY_BUFF_COUNT;a++)
{
DelayBuff = 0;
DelayBuffState = SD_FREE;
}
PointHead = 0;
PointTail = 0;
DelayItemsCounter = 0;
}
/********************************************************
*函数说明:添加延时函数 *
*输入: 延时的长度 *
*输出: 成功返回一个延时句柄 否则返回一个False(0)*
********************************************************/
char addDelayItems(unsigned int DelayTime)
{
char a = 0,b = 0;
if (DelayItemsCounter < SD_DELAY_BUFF_COUNT)
{
DelayBuffState = SD_IN_USE;
DelayBuff = DelayTime;
b = PointTail;
PointTail++;
if (PointTail == SD_DELAY_BUFF_COUNT)
{
PointTail = 0;
}
DelayItemsCounter ++;
return b+1;
}
return False;
}
/********************************************************
*函数说明:延时查询函数 *
*输入: 需要查询的延时的句柄 *
*输出: 是否超时 True / False / SD_ERROR *
********************************************************/
char IfTimeOut(char ItemID)
{
char a = 0;
if (ItemID == 0)
{
return SD_ERROR;
}
ItemID--;
switch (DelayBuffState)
{
case SD_IN_USE:
return False;
break;
case SD_FREE:
return False;
break;
case SD_COMPLETE:
DelayBuffState = SD_FREE;
for (a = 0;a<SD_DELAY_BUFF_COUNT;a++)
{
if (DelayBuffState == SD_FREE)
{
DelayItemsCounter--;
PointHead++;
if (PointHead == SD_DELAY_BUFF_COUNT)
{
PointHead = 0;
}
if (PointHead == PointTail)
{
break;
}
}
else
{
break;
}
}
return True;
break;
}
return SD_ERROR;
}
/********************************************************
*函数说明:系统延时处理函数 *
********************************************************/
void refreshSystemMsDelay(void)
{
char a = 0;
for (a = 0;a<SD_DELAY_BUFF_COUNT;a++)
{
if (DelayBuffState == SD_IN_USE)
{
if (DelayBuff > 0)
{
DelayBuff -- ;
}
else
{
DelayBuffState = SD_COMPLETE;
}
}
}
}
#endif
欢迎大家一起测试。 使用方法:
1、在系统复位初始化的时候调用函数SystemMsDelayInit(),来初始化这一系统;
2、在定时器毫秒中断处理程序里面添加函数refreshSystemMsDelay()来保证系统正常运行;
3、通过addDelayItems(时间)来添加延时,通过该函数返回的Handl(句柄)来用函数IfTimeOut(句柄)查询延时是否完成。
4、该系统非常适合实时系统。 谢谢楼主的一片良苦用心!不知道能否把晶振的不同也带上? 这个头文件和晶体震荡器的频率没有关系
你把refreshSystemMsDelay()函数放到什么频率的定时器中断处理程序里面,那么延时的单位就是多少。比方说你放到一秒触发一次的定时器中断处理程序里面,那么延时的单位就是秒了。 高手啊 长见识了 1.IfTimeOut(char ItemID) 输入的是需要查询的延时的句柄,在case SD_COMPLETE: DelayBuffState = SD_FREE; 直接返回True就算检测该延时结束,后面的for()是处理什么?
2.char addDelayItems(unsigned int DelayTime) ,为什么不将该延时的任务号也作为参数,却在程序中用全局变量PointTail有什么用意吗?
3.末尾的#endif 是多余的。
傻孩子:1、后面的for是为了消除环形结构里面的气泡,你可以按照动态堆式内存分配的算法来思考。
2、我用了环形结构……任务号对外部使用者来说是不必要的信息,而且破坏了函数的封装。 好东西!谢谢! 【6楼】 liqu :
这个库文件是一年半以前的,并不符合我现在的编码规范。所以出现了#endif这样多余的东西。
现在更新一个新版本:
RD_UseDelay.c
/***********************************************************
* 函数库说明:系统并行延时函数库 *
* 版本: v3.00 *
* 作者: 傻孩子 *
* 创建日期:2006年9月18日 *
* -------------------------------------------------------- *
*[支持库] *
* 库名称: RD_MacroAndConst.h *
* 需要版本:v0.01 &abv *
* 支持库说明:系统常用宏定义库 *
* *
* 库名称: RD_UseDelay.h *
* 需要版本:----- *
* 支持库说明:系统并行延时声明库 *
* -------------------------------------------------------- *
*[版本更新] *
* 修改: 傻孩子 *
* 修改日期:2006月4月11日 *
* 版本升级:v1.0 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年4月16日 *
* 版本: v1.01 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年6月19日 *
* 版本: v1.10 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年6月25日 *
* 版本: v2.00 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年9月19日 *
* 版本: v3.00 *
* -------------------------------------------------------- *
*[版本历史] *
* v1.0 从原来的程序代码中提取了该函数库,支持系统*
* 并行延时,支持外部修改缓冲区大小。 *
* v1.01 使用了统一的代码插入接口标准。 *
* v1.10 为适应多任务的并行延时特性,增加一个取消延*
* 时预约的函数,增强延时操作的灵活性。 *
* v2.00 修改了系统句柄有效期的问题,使用结构体数组*
* 记录延时状态,将返回的句柄改为unsigned int*
* 型数据。 *
* v3.00 该文件根据从前RD_UseSystemDelay.h修改得来。 *
* 修改了延时的计时方法,减小了系统资源的占用*
* -------------------------------------------------------- *
*[使用说明] *
* 1、在您需要使用该函数之前引用该头文件 *
* 2、在您的毫秒定时器中断处理程序里面调用函数 *
* SD_INSERT_TIMER_OVF_ISR_CODE以确保函数 *
* 库正常使用。 *
* 3、在系统初始化程序里面增加对该系统初始化函数*
* Delay_System_Init()的调用 *
* 4、通过调用addDelayItems(n)函数来添加一个延时*
* 该操作成功将会返回一个用于查询的句柄;否则 *
* 返回FALSE(0)。 *
* 5、通过函数If_Time_Out(句柄)来查询句柄代表的那 *
* 个延时是否完成TRUE/FALSE。如果出现错误会 *
* 返回SD_ERROR标志。 *
* 6、通过在引用该头文件之前定义宏: *
* SD_DELAY_BUFF_COUNT来设定缓冲区的大小。 *
***********************************************************/
/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"
# include "RD_UseDelay.h"
/********************
* 系 统 宏 定 义*
********************/
/*------------------*
* 常 数 宏 定 义*
*------------------*/
#ifndef SD_DELAY_BUFF_SIZE
# error Need For SD_DELAY_BUFF_SIZE
#endif
/********************
* 结构体宏定义 *
********************/
typedef struct DelayItem
{
uint16 ID;
uint32 Timer;
}DELAYITEM;
/********************
* 函 数 声 明 区*
********************/
void Delay_System_INIT(void);
uint16 Add_Delay_Item(uint16 wTime);
uint8 If_Time_Out(uint16 wDHandl);
void Cancel_Delay_Item(uint16 wDHandl);
/********************
* 模块变量声明区*
********************/
static DELAYITEM s_dlDelayBuff;
static uint16s_wDelayIDCounter = 0;
/********************
* 全局变量声明区*
********************/
uint32 g_dDelayTimerCounter = 0;
uint8 g_cDelayItemCounter = 0;
/***********************************************************
*函数说明:延时系统初始化 *
*输入: 无 *
*输出: 无 *
*调用函数:无 *
***********************************************************/
void Delay_System_INIT(void)
{
uint8 n = 0;
for (n = 0;n < SD_DELAY_BUFF_SIZE;n++)
{
s_dlDelayBuff.ID = NULL;
s_dlDelayBuff.Timer = NULL;
}
g_dDelayTimerCounter = 0;
g_cDelayItemCounter = 0;
s_wDelayIDCounter = 0;
}
/***********************************************************
*函数说明:添加一个延时 *
*输入: 需要延时的时间 *
*输出: 查询用的句柄 *
*调用函数:无 *
***********************************************************/
uint16 Add_Delay_Item(uint16 wTime)
{
uint8 n = 0;
if (g_cDelayItemCounter >= SD_DELAY_BUFF_SIZE)
{
return NULL; //返回空表示错误
}
for (n = 0;n < SD_DELAY_BUFF_SIZE;n++)
{
if (!s_dlDelayBuff.ID)
{
if (s_wDelayIDCounter == 0xffff) //回避ID 0x0000的出现
{
s_wDelayIDCounter = 0;
}
s_dlDelayBuff.ID = ++s_wDelayIDCounter;
SAFE_CODE_PERFORMANCE
(
s_dlDelayBuff.Timer = g_dDelayTimerCounter + wTime;
)
g_cDelayItemCounter++;
return s_dlDelayBuff.ID; //返回查询句柄
}
}
return NULL; //异常情况
}
/***********************************************************
*函数说明:判断延时是否超时 *
*输入: 查询用的句柄 *
*输出: 是否超时,如果句柄错误将得到SD_ERROR *
*调用函数:无 *
***********************************************************/
uint8 If_Time_Out(uint16 wDHandl)
{
uint8 n = 0;
uint32 dTempDelayTimerCounter = 0;
if (!wDHandl) //空句柄
{
return SD_ERROR;
}
SAFE_CODE_PERFORMANCE
(
dTempDelayTimerCounter = g_dDelayTimerCounter;
)
for (n = 0;n < SD_DELAY_BUFF_SIZE;n++)
{
if (s_dlDelayBuff.ID == wDHandl)
{
if (s_dlDelayBuff.Timer <= dTempDelayTimerCounter)
{
s_dlDelayBuff.ID = NULL;
s_dlDelayBuff.Timer = NULL;
g_cDelayItemCounter--;
return TRUE;
}
else
{
return FALSE;
}
}
}
return SD_ERROR; //ID已经过期
}
/***********************************************************
*函数说明:取消延时 *
*输入: 查询用的句柄 *
*输出: 无 *
*调用函数:无 *
***********************************************************/
void Cancel_Delay_Item(uint16 wDHandl)
{
uint8 n = 0;
if (!wDHandl) //空句柄
{
return ;
}
for (n = 0;n < SD_DELAY_BUFF_SIZE;n++)
{
if (s_dlDelayBuff.ID == wDHandl)
{
s_dlDelayBuff.ID = NULL;
s_dlDelayBuff.Timer = NULL;
g_cDelayItemCounter--;
return ;
}
}
} RD_UseDelay.h
#ifndef _USE_DELAY_H_
#define _USE_DELAY_H_
/***********************************************************
* 声明库说明:系统并行延时声明库 *
* 版本: v3.00 *
* 作者: 傻孩子 *
* 创建日期:2006年9月18日 *
* -------------------------------------------------------- *
*[支持库] *
* 支持库名称:LIB_Config.h *
* 需要版本:---- *
* 支持库说明:库函数配置声明库 *
* -------------------------------------------------------- *
*[版本更新] *
* 修改: 傻孩子 *
* 修改日期:2006月4月11日 *
* 版本升级:v1.0 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年4月16日 *
* 版本: v1.01 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年6月19日 *
* 版本: v1.10 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年6月25日 *
* 版本: v2.00 *
* *
* 修改: 傻孩子 *
* 修改日期:2006年9月19日 *
* 版本: v3.00 *
* -------------------------------------------------------- *
*[版本历史] *
* v1.0 从原来的程序代码中提取了该函数库,支持系统*
* 并行延时,支持外部修改缓冲区大小。 *
* v1.01 使用了统一的代码插入接口标准。 *
* v1.10 为适应多任务的并行延时特性,增加一个取消延*
* 时预约的函数,增强延时操作的灵活性。 *
* v2.00 修改了系统句柄有效期的问题,使用结构体数组*
* 记录延时状态,将返回的句柄改为unsigned int*
* 型数据。 *
* v3.00 该文件根据从前RD_UseSystemDelay.h修改得来。 *
* 修改了延时的计时方法,减小了系统资源的占用*
* -------------------------------------------------------- *
*[使用说明] *
* 1、在您需要使用该函数之前引用该头文件 *
* 2、在您的毫秒定时器中断处理程序里面调用函数 *
* SD_INSERT_TIMER_OVF_ISR_CODE以确保函数 *
* 库正常使用。 *
* 3、在系统初始化程序里面增加对该系统初始化函数*
* Delay_System_Init()的调用 *
* 4、通过调用addDelayItems(n)函数来添加一个延时*
* 该操作成功将会返回一个用于查询的句柄;否则 *
* 返回FALSE(0)。 *
* 5、通过函数If_Time_Out(句柄)来查询句柄代表的那 *
* 个延时是否完成TRUE/FALSE。如果出现错误会 *
* 返回SD_ERROR标志。 *
* 6、通过在引用该头文件之前定义宏: *
* SD_DELAY_BUFF_COUNT来设定缓冲区的大小。 *
***********************************************************/
/********************
* 头 文 件 配 置 区 *
********************/
# include "RD_MacroAndConst.h"
# include "LIB_Config.h"
/********************
* 系 统 宏 定 义*
********************/
/*------------------*
* 常 数 宏 定 义*
*------------------*/
# define SD_FREE 0x00
# define SD_IN_USE 0x01
# define SD_ERROR 0xff
/*------------------*
* 动 作 宏 定 义*
*------------------*/
# define SD_INSERT_TIMER_OVF_ISR_CODE {\
g_dDelayTimerCounter++;\
if (!g_cDelayItemCounter)\
{\
g_dDelayTimerCounter = 0;\
}\
}
/********************
* 结构体宏定义 *
********************/
/********************
* 函 数 引 用 区*
********************/
extern void Delay_System_INIT(void);
extern unsigned int Add_Delay_Item(unsigned int wTime);
extern unsigned char If_Time_Out(unsigned int wDHandl);
extern void Cancel_Delay_Item(unsigned int wDHandl);
/********************
* 全局变量引用区*
********************/
extern unsigned long g_dDelayTimerCounter;
extern unsigned char g_cDelayItemCounter;
#endif 非常不错,谢谢
页:
[1]