Gorgon_Meducer 发表于 2006-5-12 10:36:44

[古董贴][测试]用于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



欢迎大家一起测试。

Gorgon_Meducer 发表于 2006-5-12 10:40:11

使用方法:

1、在系统复位初始化的时候调用函数SystemMsDelayInit(),来初始化这一系统;

2、在定时器毫秒中断处理程序里面添加函数refreshSystemMsDelay()来保证系统正常运行;

3、通过addDelayItems(时间)来添加延时,通过该函数返回的Handl(句柄)来用函数IfTimeOut(句柄)查询延时是否完成。

4、该系统非常适合实时系统。

stud1 发表于 2006-5-12 11:00:43

谢谢楼主的一片良苦用心!不知道能否把晶振的不同也带上?

Gorgon_Meducer 发表于 2006-5-12 11:03:28

这个头文件和晶体震荡器的频率没有关系



你把refreshSystemMsDelay()函数放到什么频率的定时器中断处理程序里面,那么延时的单位就是多少。比方说你放到一秒触发一次的定时器中断处理程序里面,那么延时的单位就是秒了。

alisha 发表于 2006-5-17 15:38:37

高手啊

shusheng 发表于 2006-5-17 16:50:05

长见识了

liqu 发表于 2008-3-6 16:00:51

1.IfTimeOut(char ItemID) 输入的是需要查询的延时的句柄,在case SD_COMPLETE: DelayBuffState = SD_FREE; 直接返回True就算检测该延时结束,后面的for()是处理什么?
2.char addDelayItems(unsigned int DelayTime) ,为什么不将该延时的任务号也作为参数,却在程序中用全局变量PointTail有什么用意吗?
3.末尾的#endif 是多余的。

傻孩子:1、后面的for是为了消除环形结构里面的气泡,你可以按照动态堆式内存分配的算法来思考。
2、我用了环形结构……任务号对外部使用者来说是不必要的信息,而且破坏了函数的封装。

avr1008 发表于 2008-3-10 11:42:00

好东西!谢谢!

Gorgon_Meducer 发表于 2008-3-14 19:59:33

【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 ;
      }
    }
}

Gorgon_Meducer 发表于 2008-3-14 20:00:42

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

laodaok 发表于 2010-7-23 17:09:23

非常不错,谢谢
页: [1]
查看完整版本: [古董贴][测试]用于OurRobotV1的实时延时模块(Real Time Delay Module)