Chinaunix首页 | 论坛 | 博客
  • 博客访问: 105656
  • 博文数量: 32
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 318
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-30 09:58
个人简介

经过长期对C语言的研究,目前只有两个方面不懂:这也不懂,那也不懂。 本人擅长 Ai、Fw、Fl、Br、Ps 等软件的安装卸载,精通 CSS、Java、PHP、C、C++、C#、Java、Ruby、Python、Objective-C等单词的拼写,熟悉 Windows、Linux、Mac、Android、iOS等系统的开关机 https://github.com/ianhom

文章分类

全部博文(32)

我的朋友

分类: C/C++

2015-03-03 15:10:14

与大神David交流了他写的软件定时器模块后,受益匪浅。正值学习链表,决定用链表实现一遍类似的模块

SoftTimer.c

点击(此处)折叠或打开

  1. /******************************************************************************
  2. * 文件名称:SoftTimer.c
  3. * 内容摘要:软件定时器模块
  4. * 其他说明:首先运行TimersInit函数,需向该函数提供"1ms的系统时钟""最大系统ms数"
  5. *         然后在各自的应用模块中调用CreatTimer创建定时器,该函数返回的地址为该定
  6. *         时器的地址,可用与重启或删除定时器结点,请妥善保管。请在主循环中执行
  7. *         ProcessTimer函数以更新定时器时间。
  8. * 当前版本:V1.00
  9. * 作 者:  David Han, Ian
  10. * 完成日期:2015年2月20日
  11. ******************************************************************************/

  12. #include "common.h"
  13. #include "SoftTimer.h"

  14. static TIMER_TABLE* sg_ptTimeTableHead = NULL;             /* 链表表头       */
  15. static TMRSOURCE    sg_pfSysClk        = NULL;             /* 系统1ms时钟函数 */
  16. static long int     sg_dwTimeMaxValue  = MAX_VALUE_16_BIT; /* 最大ms数       */

  17. /*************************************************************************
  18. * 函数名称:int TimersInit(TMRSOURCE pfTimer, uint32 dwMaxTime)
  19. * 功能说明:初始化软件定时器模块
  20. * 输入参数:TMRSOURCE pfTimer  系统1ms时钟函数
  21.            uint32   dwMaxTime 时钟函数最大ms数
  22. * 输出参数:无
  23. * 返 回 值:SW_ERROR: 操作失败
  24.            SW_OK 操作成功
  25. * 其它说明:无
  26. **************************************************************************/
  27. int TimersInit(TMRSOURCE pfTimer, uint32 dwMaxTime)
  28. {
  29.     if (NULL == pfTimer)
  30.     {
  31.         return SW_ERROR; /* 检查注册函数是否为空指针 */
  32.     }
  33.     
  34.     sg_ptTimeTableHead = (TIMER_TABLE*)malloc(sizeof(TIMER_TABLE)); /* 申请头结点 */
  35.     if (NULL == sg_ptTimeTableHead)
  36.     {
  37.         return SW_ERROR; /* 检查是否申请成功 */
  38.     }

  39.     /* 申请成功后进行初始化 */
  40.     sg_ptTimeTableHead->next = NULL;               /* 下个结点地址置空     */
  41.     sg_pfSysClk              = (TMRSOURCE)pfTimer; /* 注册系统1ms时钟函数  */
  42.     sg_dwTimeMaxValue        = dwMaxTime;          /* 确定时钟函数最大ms数 */
  43.     
  44.     return SW_OK;
  45. }

  46. /*************************************************************************
  47. * 函数名称:TIMER_TABLE* CreatTimer(uint32 dwTimeout, uint8 ucPeriodic, TMRCALLBACK pfTimerCallback, void *pArg)
  48. * 功能说明:创建并启动软件定时器
  49. * 输入参数:uint32       dwTimeout  0~0xFFFFFFFF 定时时间
  50.            uint8       ucPeriodic  SINGLE      单次触发
  51.                                    PERIODIC    周期触发
  52.            TMRCALLBACK pfTimerCallback         定时结束时回调函数
  53.            void       *pArg                    回调函数参数
  54.             
  55. * 输出参数:无
  56. * 返 回 值:操作失败 : NULL
  57.            操作成功 : 定时器模块指针
  58. * 其它说明:创建完定时器后返回定时器结点的地址,改地址用于重启或删除该定时器
  59. **************************************************************************/
  60. TIMER_TABLE* CreatTimer(uint32 dwTimeout, uint8 ucPeriodic, TMRCALLBACK pfTimerCallback, void *pArg)
  61. {
  62.     TIMER_TABLE* ptTimerNode;
  63.     TIMER_TABLE* ptFind;
  64.     if (NULL == sg_ptTimeTableHead)
  65.     {
  66.         return NULL; /* 检查链表头节点是否存在 */
  67.     }

  68.     /* 链表头结点已经存在 */
  69.     ptTimerNode = (TIMER_TABLE*)malloc(sizeof(TIMER_TABLE)); /* 申请定时器结点 */
  70.     if (NULL == ptTimerNode)
  71.     {
  72.         return NULL; /* 检查是否申请成功 */
  73.     }

  74.     /* 结点申请成功 */
  75.     ptTimerNode->next                 = NULL;                    /* 下个结点地址置空 */
  76.     ptTimerNode->data.periodic        = ucPeriodic;              /* 单次/周期触发 */
  77.     ptTimerNode->data.start           = sg_pfSysClk();           /* 获取计时起始时间 */
  78.     ptTimerNode->data.now             = ptTimerNode->data.start; /* 获取当前时间 */
  79.     ptTimerNode->data.elapse          = 0;                       /* 已经过的时间 */
  80.     ptTimerNode->data.timeout         = dwTimeout;               /* 定时时间 */
  81.     ptTimerNode->data.pfTimerCallback = pfTimerCallback;         /* 注册定时结束回调函数 */
  82.     ptTimerNode->data.pArg            = pArg;                    /* 回调函数参数 */

  83.     /* 将新申请的定时器结点增加进入链表 */
  84.     ptFind = sg_ptTimeTableHead; /* 先找链表头结点 */
  85.     while(NULL != ptFind->next)  /* 如果当前结点不是末尾结点*/
  86.     {
  87.         ptFind = ptFind->next;   /* 将下一个结点的地址作为当前结点继续查找 */
  88.     }
  89.     /* 找到末尾结点 */
  90.     ptFind->next= ptTimerNode;   /* 将新申请结点链接到末尾结点 */

  91.     return ptTimerNode;          /* 操作成功,返回新申请结点地址(用于删除和重启计时) */
  92. }

  93. /*************************************************************************
  94. * 函数名称:int KillTimer(TIMER_TABLE* ptNode)
  95. * 功能说明:删除定时器结点
  96. * 输入参数:TIMER_TABLE* ptNode 定时器结点地址
  97. * 输出参数:无
  98. * 返 回 值:SW_ERROR: 操作失败
  99.            SW_OK 操作成功
  100. * 其它说明:无
  101. **************************************************************************/
  102. int KillTimer(TIMER_TABLE* ptNode)
  103. {
  104.     TIMER_TABLE* ptFind;

  105.     if (NULL == ptNode)
  106.     {
  107.         return SW_ERROR; /* 检查定时器结点是否为空 */
  108.     }

  109.     /* 定时器结点不为空 */
  110.     ptFind = sg_ptTimeTableHead; /* 先找到头结点 */
  111.     while (ptFind) /* 如果不是末尾结点 */
  112.     {
  113.         if (ptFind->next == ptNode)      /* 检查下一结点是否为需删除结点 */
  114.         {
  115.             ptFind->next = ptNode->next; /* 重新链接上下结点 */
  116.             free(ptNode);                /* 删除结点 */
  117.             return SW_OK;                /* 操作成功,退出程序 */
  118.         }
  119.         ptFind = ptFind->next;           /* 继续查找下一结点 */
  120.     }
  121.     return SW_ERROR;                     /* 未找到,操作失败 */
  122. }


  123. /*************************************************************************
  124. * 函数名称:int ResetTimer(TIMER_TABLE* ptNode)
  125. * 功能说明:重启定时器结点
  126. * 输入参数:TIMER_TABLE* ptNode 定时器结点地址
  127. * 输出参数:无
  128. * 返 回 值:SW_ERROR: 操作失败
  129.            SW_OK 操作成功
  130. * 其它说明:无
  131. **************************************************************************/
  132. int ResetTimer(TIMER_TABLE* ptNode)
  133. {
  134.     if (NULL == ptNode)
  135.     {
  136.         return SW_ERROR;                /* 检查定时器结点是否为空 */
  137.     }

  138.     ptNode->data.start = sg_pfSysClk(); /* 更新定时器起始时间 */
  139.     return SW_OK;                       /* 操作成功 */
  140. }


  141. /*************************************************************************
  142. * 函数名称:int ProcessTimer(void)
  143. * 功能说明:更新定时器结点
  144. * 输入参数:无
  145. * 输出参数:无
  146. * 返 回 值:SW_ERROR: 操作失败
  147.             SW_OK 操作成功
  148. * 其它说明:无
  149. **************************************************************************/
  150. int ProcessTimer(void)
  151. {
  152.     TIMER_TABLE* ptFind;
  153.     TIMER_TABLE* ptNodeFree;
  154.     if (NULL == sg_ptTimeTableHead)
  155.     {
  156.         return SW_ERROR; /* 检查是否申请成功 */
  157.     }
  158.     ptFind = sg_ptTimeTableHead->next;    /* 找到第一个有效结点 */
  159.     while(ptFind)                         /* 如果不是末尾结点 */
  160.     {
  161.         ptFind->data.now = sg_pfSysClk(); /* 更新时间 */

  162.         /* 计算此刻时间与起始时间的时间差 */
  163.         if(ptFind->data.now >= ptFind->data.start)
  164.         {
  165.             ptFind->data.elapse = ptFind->data.now - ptFind->data.start;
  166.         }
  167.         else
  168.         {
  169.             ptFind->data.elapse = sg_dwTimeMaxValue - ptFind->data.start + ptFind->data.now;
  170.         }
  171.         
  172.         if(ptFind->data.elapse >= ptFind->data.timeout)          /* 如果时差大于等于设定的计时时间 */
  173.         {
  174.             if(ptFind->data.pfTimerCallback)                     /* 且已经注册了合法的回调函数 */
  175.             {
  176.                 ptFind->data.pfTimerCallback(ptFind->data.pArg); /* 执行回调函数 */
  177.             }    
  178.             if(ptFind->data.periodic)
  179.             {
  180.                 ResetTimer(ptFind);                              /* 如果是周期性触发,重启定时器 */
  181.             }
  182.             else
  183.             {                                                    /* 如果是单次触发,删除定时器 */
  184.                 ptNodeFree = ptFind;
  185.                 ptFind = ptFind->next;
  186.                 KillTimer(ptNodeFree);
  187.                 continue;
  188.             }            
  189.         }
  190.         ptFind = ptFind->next;                                   /* 继续更新下一个定时器结点 */
  191.     }
  192.     return SW_OK;                                                /* 操作成功 */
  193. }

  194. /* end of file */

SoftTimer.h
  1. /******************************************************************************
  2. * 文件名称:SoftTimer.h
  3. * 内容摘要:软件定时器模块头文件
  4. * 其他说明:首先运行TimersInit函数,需向该函数提供"1ms的系统时钟""最大系统ms数"
  5. *          然后在各自的应用模块中调用CreatTimer创建定时器,该函数返回的地址为该定
  6. *          时器的地址,可用与重启或删除定时器结点,请妥善保管。请在主循环中执行
  7. *          ProcessTimer函数以更新定时器时间。
  8. * 当前版本:V1.00
  9. * 作 者:David Han, Ian
  10. * 完成日期:2015年2月20日
  11. ******************************************************************************/
  12. #ifndef __SOFTTIMER_H_
  13. #define __SOFTTIMER_H_    

  14. #ifdef __cplusplus
  15. extern "C" {
  16. #endif

  17. #define MAX_VALUE_8_BIT  0xFF       /* 16bit最大ms数 */
  18. #define MAX_VALUE_16_BIT 0xFFFF     /* 16bit最大ms数 */
  19. #define MAX_VALUE_24_BIT 0xFFFFFF   /* 16bit最大ms数 */
  20. #define MAX_VALUE_32_BIT 0xFFFFFFFF /* 16bit最大ms数 */

  21. #define SW_ERROR               (-1) /* 操作失败返回值 */
  22. #define SW_OK                   (0) /* 操作成功返回值 */

  23. typedef int (*TMRCALLBACK)(void *pArg);
  24. typedef uint32 (*TMRSOURCE)(void);

  25. /****************************************************
  26. * 结构名:TIMER
  27. * 描述: 软件定时器数据结构
  28. * 参数:
  29.      uint8        periodic;        SINGLE       单次触发
  30.                                    PERIOIC      周期触发
  31.      uint32       start;           0~0xFFFFFFFF 计时器起始时间
  32.      uint32       now;             0~0xFFFFFFFF 计时器当前时间
  33.      uint32       elapse;          0~0xFFFFFFFF 计时器已过时间
  34.      uint32       timeout;         0~0xFFFFFFFF 计时器计时时间
  35.      TMRCALLBACK  pfTimerCallback;              计时结束后执行的回调函数
  36.      void        *pArg;                         回调函数的参数
  37. * 作者: David Han, Ian
  38. * 日期: 2015-2-20
  39. ****************************************************/
  40. typedef struct _TIMER
  41. {
  42.     uint8      periodic;         /* 单次触发/周期触发 */
  43.     uint32      start;           /* 计时器起始时间 */
  44.     uint32      now;             /* 计时器当前时间 */
  45.     uint32      elapse;          /* 计时器已过时间 */
  46.     uint32      timeout;         /* 计时器计时时间 */
  47.     TMRCALLBACK pfTimerCallback; /* 计时结束后执行的回调函数 */
  48.     void       *pArg;            /* 回调函数的参数 */
  49. } TIMER;


  50. /****************************************************
  51. * 结构名:TIMER_TABLE
  52. * 描述: 定时器列表(链表)
  53. * 参数:
  54.           TIMER                data; 本计时器结点数据
  55.           struct _TIMER_TABLE* next; 下一个定时器结点地址
  56. * 作者: David Han, Ian
  57. * 日期: 2015-2-20
  58. ****************************************************/
  59. typedef struct _TIMER_TABLE
  60. {
  61.     TIMER                data; /* 本计时器结点数据 */
  62.     struct _TIMER_TABLE* next; /* 下一个定时器结点地址 */
  63. }TIMER_TABLE;

  64. /*************************************************************************
  65. * 函数名称:int TimersInit(TMRSOURCE pfTimer, uint32 dwMaxTime)
  66. * 功能说明:初始化软件定时器模块
  67. * 输入参数:TMRSOURCE pfTimer    系统1ms时钟函数
  68.            uint32    dwMaxTime  时钟函数最大ms数
  69. * 输出参数:无
  70. * 返 回 值:SW_ERROR: 操作失败
  71.            SW_OK 操作成功
  72. * 其它说明:无
  73. **************************************************************************/
  74. int TimersInit(TMRSOURCE pfTimer, uint32 dwMaxTime);


  75. /*************************************************************************
  76. * 函数名称:TIMER_TABLE* CreatTimer(uint32 dwTimeout, uint8 ucPeriodic, TMRCALLBACK pfTimerCallback, void *pArg)
  77. * 功能说明:创建并启动软件定时器
  78. * 输入参数:uint32         dwTimeout  0~0xFFFFFFFF 定时时间
  79.            uint8          ucPeriodic SINGLE      单次触发
  80.                                      PERIODIC    周期触发
  81.            TMRCALLBACK    pfTimerCallback        定时结束时回调函数
  82.             void         *pArg                   回调函数参数
  83.             
  84. * 输出参数:无
  85. * 返 回 值:操作失败 : NULL
  86.            操作成功 : 定时器模块指针
  87. * 其它说明:创建完定时器后返回定时器结点的地址,改地址用于重启或删除该定时器
  88. **************************************************************************/
  89. TIMER_TABLE* CreatTimer(uint32 dwTimeout, uint8 ucPeriodic, TMRCALLBACK pfTimerCallback, void *pArg);


  90. /*************************************************************************
  91. * 函数名称:int KillTimer(TIMER_TABLE* ptNode)
  92. * 功能说明:删除定时器结点
  93. * 输入参数:TIMER_TABLE* ptNode 定时器结点地址
  94. * 输出参数:无
  95. * 返 回 值:SW_ERROR: 操作失败
  96.            SW_OK 操作成功
  97. * 其它说明:无
  98. **************************************************************************/
  99. int KillTimer(TIMER_TABLE* ptNode);


  100. /*************************************************************************
  101. * 函数名称:int ResetTimer(TIMER_TABLE* ptNode)
  102. * 功能说明:重启定时器结点
  103. * 输入参数:TIMER_TABLE* ptNode 定时器结点地址
  104. * 输出参数:无
  105. * 返 回 值:SW_ERROR: 操作失败
  106.            SW_OK 操作成功
  107. * 其它说明:无
  108. **************************************************************************/
  109. int ResetTimer(TIMER_TABLE* ptNode);


  110. /*************************************************************************
  111. * 函数名称:int ProcessTimer(void)
  112. * 功能说明:更新定时器结点
  113. * 输入参数:无
  114. * 输出参数:无
  115. * 返 回 值:SW_ERROR: 操作失败
  116.            SW_OK 操作成功
  117. * 其它说明:无
  118. **************************************************************************/
  119. int ProcessTimer(void);


  120. #ifdef __cplusplus
  121. }
  122. #endif

  123. #endif

  124. /* end of file */

阅读(3504) | 评论(0) | 转发(1) |
1

上一篇:循环单向链表

下一篇:一种开方函数

给主人留下些什么吧!~~