⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timer.c

📁 在单片机通过软件建立定时器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*********************************************************************
 *Copyright-(c) 2003,                                                *
 *All rights reserved.                                               *
 *                                                                   *
 * 文件名称: TIMER.C                                                *
 * 摘要    : For 80x86                                              *
 *                                                                   *
 * 当前版本: 2.3                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2006年2月23日                                          *
 * 修改    : 1、把在中断内调用任务函数功能作为可裁减功能,可以通过头 *
 *               文件中的TMR_INTR_FNCT_EN来裁减。                    *
 *                                                                   *
 * 当前版本: 2.2                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2005年4月15日                                          *
 * 修改    : 1、修改了TMR_Delete()函数,增加对ptmrid指针是否为NULL的*
 *               判断。                                              *
 *                                                                   *
 * 取代版本: 2.1                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2005年3月3日                                           *
 * 修改    : 1、加入获取计数值函数TMR_GetCtr(),用于实时获取定时器的*
 *               计数值。                                            *
 *                                                                   *
 * 取代版本: 2.0                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2004年9月29日                                          *
 * 修改    : 1、将系统节拍TMR_TICK_LENGTH的单位由毫秒变为微秒,从而 *
 *               使计时器的定时范围可以小于1毫秒。但在编程时注意,系 *
 *               统节拍不应太短,使系统负载过大;                    *
 *            2、定时长度的单位由原先统一的毫秒,改为可在微秒、毫秒和*
 *               秒之间选择,以免在长时间定时时,数据过大而溢出。    *
 *                                                                   *
 * 取代版本: 1.2                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2004年9月20日                                          *
 * 修改    : 1、对模块内的函数进行重新命名,采用"模块名_函数名"的格 *
 *               式,以期与其他模块统一;                            *
 *            2、将全局变量的定义放到头文件中;                       *
 *            3、修改TMR_Reload()的工作方式,使其在复位计时器计数值后*
 *               让计时器开始运行;                                  *
 *                                                                   *
 * 取代版本: 1.1                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年10月22日                                         *
 * 修改    : 1、将计时器数据结构由结构体改为数组,提高代码效率;    *
 *            2、增加计时器工作模式属性,包含CONT(连续)、ONCE(单次)  *
 *               和DELAY(延时)模式;                                 *
 *            3、增加了LongDelay()函数,用以实现数毫秒到几十秒范围的 *
 *               延时,若使用TMR_LARG_RANG模式,延时长达数天;       *
 *            4、定义了计时器中断使用的寄存器组常数,可以根据中断函  *
 *               数设定TmrIntTask()函数使用的寄存器组。              *
 *            5、修改了TmrDelet()函数,传入计时器id的指针,在删除计  *
 *               时器后,将计时器id赋为TMR_MAX;                     *
 *                                                                   *
 * 取代版本: 1.0                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年9月22日                                          *
 * 修改    : 1、计时器计时范围分为两档,小范围为0~65,535,大范围为 *
 *               0~4,294,967,295,通过宏定义TMR_LARG_RANG进行选择。  *
 *            2、完善了TmrInit()函数,对计时器参数都进行了初始化;   *
 *            3、对计时器函数进行修改的程序段都放入临界区,防止中断进*
 *               入,发生冲突;                                      *
 *            4、修改了TmrDelet()函数,传入计时器指针的指针,在删除计*
 *               时器后,将计时器指针指向空;                        *
 *            5、在大部分函数中添加了计时器指针非空判断,以免发生误操*
 *               作;                                                *
 *            6、将定时计数单位统一为毫秒,取消TmrSetMST()函数。     *
 *                                                                   *
 * 取代版本: 0.4                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年9月5日                                           *
 * 修改    : 1、增加了两个函数(宏定义),分别是TmrCallIntFnct()和  *
 *               TmrCallFnct(),用于直接调用关联函数,并且将计时器重 *
 *               置,重新开始计时。                                  *
 *                                                                   *
 * 取代版本: 0.3                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年8月31日                                          *
 * 修改    : 1、不再使用分配动态内存方式创建新计时器,而是在程序运  *
 *               开始处根据最多计时器数量来定义计时器数组,将计时器  *
 *               分配到静态内存中;                                  *
 *            2、分别由工作计时器链表和空闲计时器链表来管理计时器模  *
 *               块;                                                *
 *            3、新创建的计时器插入到工作链表的首部,而删除的计时器  *
 *               则被插入到空闲计时器链表的尾部。                    *
 *                                                                   *
 * 取代版本: 0.2                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年8月29日                                          *
 * 修改    : 1、取消触发标志结构体,将标志添加到计时器结构体中;    *
 *            2、计时器操作函数不再通过标志结构体来获取计时器地址;  *
 *            3、在计时器结构体中增加的一个函数指针,两个函数指针分  *
 *               别用于指向中断内运行函数和中断外运行函数;          *
 *            4、计时器溢出后,若指向中断内运行函数指针非空,则直接  *
 *               调用函数;反之,将触发标志置位;                    *
 *                                                                   *
 * 取代版本: 0.1                                                    *
 * 作者    : Liy-tj                                                 *
 * 完成日期: 2003年8月28日                                          *
 *********************************************************************/
#define   TMR_GLOBALS
#include  "includes.h"

/*********************************************************************
 *                          初始化计时器模块                         *
 *                                                                   *
 * 功能描述   :    对计时器数组进行初始化,在程序开始时调用。        *
 *                                                                   *
 * 输入参数   : 无                                                   *
 * 返回参数   : 无                                                   *
 * 文件名称   : TIMER.C                                              *
 * 作者       : Liy-tj                                               *
 *********************************************************************/
void TMR_Init(void)
{
    TMR_ID  tmrid = 0;

    OS_ENTER_CRITICAL();
    for(; tmrid<MAX_TMR; tmrid++)
    {
        TmrSta[tmrid]  = 0;
        TmrInit[tmrid] = 0;
        TmrCtr[tmrid]  = 0;
        TmrFnct[tmrid] = NULL;        //指向在中断过程外运行的函数的指针
      #ifdef TMR_INTR_FNCT_EN
        TmrIntFnct[tmrid] = NULL;     //指向在中断过程中运行的函数的指针
      #endif
    }
    OS_EXIT_CRITICAL();
}

/**********************************************************************
 *                          获取一个空计时器                          *
 *                                                                    *
 * 功能描述   :    这个函数计时器数组中获取一个空计时器,并返回计时器 *
 *                 id。                                               *
 *                                                                    *
 * 输入参数   : 无                                                    *
 * 返回参数   : tmrid     计时器的编号                                *
 * 文件名称   : TIMER.C                                               *
 * 作者       : Liy-tj                                                *
 **********************************************************************/
TMR_ID TMR_GetFree(void)
{
    TMR_ID  tmrid = 0;
    while((TmrSta[tmrid]&TMR_EN) && (tmrid < MAX_TMR))
    {
        tmrid++;
    }
    return (tmrid);
}

/**********************************************************************
 *                          创建一个计时器                            *
 *                                                                    *
 * 功能描述   :    这个函数创建一个新计时器。并且根据输入的参数对计时 *
 *                 器进行初始化。                                     *
 *                                                                    *
 * 输入参数   : tmrinit   计时器计时长度                              *
 *              tmrunit   计时器计时长度单位,微秒:UNIT_US           *
 *                                            毫秒:UNIT_MS           *
 *                                            秒  :UNIT_S            *
 *              tmrmod    计时器工作模式                              *
 *              intfnct   指向中断内调用函数的指针                    *
 *              fnct      指向中断外调用函数的指针                    *
 * 返回参数   : tmrid     创建的计时器的id                            *
 * 文件名称   : TIMER.C                                               *
 * 作者       : Liy-tj                                                *
 **********************************************************************/
#ifdef TMR_LARG_RANG
TMR_ID TMR_Create(INT32U  tmrinit, INT8U  tmrunit, INT8U  tmrmod,
                  void  (*intfnct)(void), void  (*fnct)(void))
#else
TMR_ID TMR_Create(INT16U  tmrinit, INT8U  tmrunit, INT8U  tmrmod,
                  void  (*intfnct)(void), void  (*fnct)(void))
#endif
{
    TMR_ID  tmrid = TMR_GetFree();
    
    if(tmrid < MAX_TMR)
    {
        if((tmrmod != TMR_MOD_CONT)&&(tmrmod != TMR_MOD_ONCE)
            &&(tmrmod != TMR_MOD_DELAY))
        {
            tmrid = MAX_TMR;
        }
        else
        {
            OS_ENTER_CRITICAL();
            TmrSta[tmrid]  = 0x01;
            TmrSta[tmrid] |= tmrmod;
            TMR_SetLen(tmrid, tmrinit, tmrunit);
            TmrFnct[tmrid] = fnct;
          #ifdef TMR_INTR_FNCT_EN
            TmrIntFnct[tmrid] = intfnct;
          #endif
            OS_EXIT_CRITICAL();
        }
    }
    return (tmrid);
}

/*********************************************************************
 *                          开始一个计时器                           *
 *                                                                   *
 * 功能描述   :    这个函数使一个计时器开始计数。                    *
 *                                                                   *
 * 输入参数   : tmrid      计时器id                                  *
 * 返回参数   : 无                                                   *
 * 文件名称   : TIMER.C                                              *
 * 作者       : Liy-tj                                               *
 *********************************************************************/
void TMR_Start(TMR_ID tmrid)
{
    if((tmrid < MAX_TMR)&&((TmrSta[tmrid]&TMR_EN)==1)) //计时器已经创建
    {
        OS_ENTER_CRITICAL();
        TmrSta[tmrid] |= TMR_RUN;
        TmrSta[tmrid] &= TMR_FLG_DOWN;
        OS_EXIT_CRITICAL();
    }
}

/*********************************************************************
 *                          停止一个计时器                           *
 *                                                                   *
 * 功能描述   :    这个函数使一个计时器停止计数。                    *
 *                                                                   *
 * 输入参数   : tmrid      计时器id                                  *
 * 返回参数   : 无                                                   *
 * 文件名称   : TIMER.C                                              *
 * 作者       : Liy-tj                                               *
 *********************************************************************/
void TMR_Stop(TMR_ID tmrid)
{
    if(tmrid < MAX_TMR)
    {
        OS_ENTER_CRITICAL();
        TmrSta[tmrid] &= TMR_STOP;
        TmrSta[tmrid] &= TMR_FLG_DOWN;
        OS_EXIT_CRITICAL();
    }
}

/*********************************************************************
 *                            重载计时器                             *
 *                                                                   *
 * 功能描述   :    这个函数使计时器的计数器重新开始计数。            *
 *                                                                   *
 * 输入参数   : tmrid      计时器id                                  *
 * 返回参数   : 无                                                   *
 * 文件名称   : TIMER.C                                              *
 * 作者       : Liy-tj                                               *
 *********************************************************************/
#ifdef TMR_RELOAD_EN
void TMR_Reload(TMR_ID tmrid)
{
    if(tmrid < MAX_TMR)
    {
        OS_ENTER_CRITICAL();
        TmrCtr[tmrid] = TmrInit[tmrid];
        TmrSta[tmrid]|= TMR_RUN;
        TmrSta[tmrid]&= TMR_FLG_DOWN;
        OS_EXIT_CRITICAL();
    }
}
#endif

/**********************************************************************
 *                          修改计时器计时长度                        *
 *                                                                    *
 * 功能描述   :    修改计时器计时长度。                               *
 *                                                                    *
 * 输入参数   : tmrid      计时器id                                   *
 *              tmrinit    计时长度                                   *
 *              tmrunit   计时器计时长度单位,微秒:UNIT_US           *
 *                                            毫秒:UNIT_MS           *
 *                                            秒  :UNIT_S            *
 * 返回参数   : 无                                                    *
 * 文件名称   : TIMER.C                                               *
 * 作者       : Liy-tj                                                *
 **********************************************************************/
#ifdef  TMR_LARG_RANG
void TMR_SetLen(TMR_ID tmrid, INT32U tmrinit, INT8U tmrunit)

#else
void TMR_SetLen(TMR_ID tmrid, INT16U tmrinit, INT8U tmrunit)
#endif
{
    INT32U inittemp;             //计算定时长度的中间变量
    
    if(tmrid < MAX_TMR)
    {
        switch(tmrunit)
        {
            case UNIT_MS:       //定时单位为毫秒
                inittemp = (INT32U)(((FP64)tmrinit/TMR_TICK_LENGTH)*1000+0.5)-1;
                break;
            case UNIT_S:        //定时单位为秒
                inittemp = ((INT32U)((FP64)tmrinit*(1000000.0/TMR_TICK_LENGTH)+0.5))-1;
                break;
            default:            //缺省定时单位为微秒
                inittemp = (INT32U)((FP64)tmrinit/TMR_TICK_LENGTH+0.5)-1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -