你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

时驱函数的进阶:定时器链表

[复制链接]
GKoSon 发布时间:2018-7-23 15:53
接上篇:时驱函数了解一下

前一篇帖子我写了时驱函数的设计本质是一种前后台程序,本文依旧如故。后台程序放到定时器里面,周期性的调用。这个程序程序是扫描一个链表,链表中每一个成员 噢 应该说没一个节点都设计好数据的结构体,到达设定的时间就执行回调函数。
功能:完成约定时间调用回调函数。
头文件:
  1. #ifndef _TIMELIST_H_
  2. #define _TIMELIST_H_

  3. #include "sys.h"
  4. typedef struct  _time
  5. {
  6.         void        *next;//指向后一个
  7.         uint8_t     handle;//自己的ID号
  8.         uint8_t     start;//开关1开0关
  9.         uint32_t    cnt;//累计次数的变量
  10.         uint32_t    time_out;//设定次数的常量
  11.         void        (*fun)(void);//计数达到以后做啥的函数
  12. }time_type;



  13. typedef void    (*time_call_back)(void);
  14. typedef struct
  15. {
  16.     uint8_t (*creat) (  uint32_t time_out ,uint8_t start, time_call_back call_back);
  17.     uint8_t (*stop)  (  uint8_t handle);
  18.     uint8_t (*start) (  uint8_t handle);
  19. }time_ops_type;

  20. extern time_ops_type   timer;


  21. void timer_isr( void );

  22. #endif

复制代码
看这个头文件基本就能懂一大半了。每个节点的6个成员我都批注了,handle这个词语意思很宽 ID更准确。
  1. #include "timelist.h"
  2. #include "malloc.h"        
  3. #define NULL 0
  4. enum
  5. {
  6.         false,
  7.         true
  8. };
  9. uint8_t                         timerTaskId = 0;//全局变量 每个节点的ID号从0开始
  10. time_type           *time = NULL; //链表的头 第一个节点


  11. void timer_isr( void )
  12. {
  13.         time_type          *priv = time;

  14.         while( priv != NULL )
  15.     {
  16.         if( priv->start)//这个节点是开的 就进去 否则pass
  17.         {
  18.             if( ++priv->cnt >= priv->time_out)//进来累计一次 直达到达约定设定值
  19.             {
  20.                 priv->cnt = 0;
  21.                 if(priv->fun != NULL)        
  22.                                                                         priv->fun();
  23.             }
  24.         }
  25.         priv = priv->next;      
  26.         }
  27. }

  28. //只有malloc没有free 我没有释放
  29. //返回void*

  30. void *timer_malloc(int size)
  31. {
  32.         return mymalloc(SRAMIN,sizeof(time_type));
  33. }

  34. uint8_t timer_stop_time(uint8_t handle)
  35. {
  36.         time_type *priv = time;
  37.         
  38.         while( priv != NULL )
  39.     {
  40.         if( priv->handle == handle)
  41.         {
  42.             priv->start = false;
  43.                                                 priv->cnt = 0;
  44.             return true;
  45.         }
  46.         priv = priv->next;     
  47.         }  
  48.    
  49.     return false;
  50. }

  51. uint8_t timer_start_time(uint8_t handle)
  52. {
  53.         time_type *priv = time;
  54.         
  55.         while( priv != NULL )
  56.     {
  57.         if( priv->handle == handle)
  58.         {
  59.             priv->start = true;
  60.             return true;
  61.         }
  62.         priv = priv->next;     
  63.         }  
  64.    
  65.     return false;
  66. }

  67. uint8_t timer_register_isr(  uint32_t time_out ,uint8_t start, time_call_back call_back)
  68. {
  69.         time_type *priv;
  70.         time_type        *this;

  71.         this = (time_type *)timer_malloc(sizeof(time_type));
  72.         if( this != NULL)
  73.         {

  74.                 this->cnt = 0;
  75.                 this->start = start;
  76.                 this->handle = timerTaskId++;
  77.                 this->time_out = time_out;
  78.                 this->fun = call_back;
  79.                 this->next = NULL;
  80.         if( time == NULL)
  81.                 {
  82.                          time = this;
  83.                 }
  84.                 else
  85.                 {
  86.                         priv = time;
  87.                         while( priv->next != NULL )        priv = priv->next;
  88.                         priv->next = this;
  89.                 }   
  90.         }
  91.         else
  92.         {
  93.                 return 0xFF;
  94.         }


  95.     return (this->handle);

  96. }

  97. //KEIL不支持该写法??
  98. //time_ops_type  timer =
  99. //{
  100. //    .creat = timer_register_isr,
  101. //    .stop  = timer_stop_time ,
  102. //    .start = timer_start_time,
  103. //};


  104. time_ops_type  timer =
  105. {
  106.     timer_register_isr,
  107.     timer_stop_time ,
  108.     timer_start_time,
  109. };
复制代码
实现如上 因为用了链表需要malloc函数 我没有用C库 而是自己写的内存分配模块

举一个例子吧
int IDID=0;
int wang=0;
void saywang(void)
{
    wang++;
    if(wang==4)
        timer.stop(IDID);
}
void Business_Init(void)
{
        IDID=timer.creat(100,1,saywang);

。。。。。
}

初始化的时候创建了一个定时器节点,时间是100个节拍,1是直接打开,到达设定时间就会调用saywang函数。
可以在找一个条件比较按键来                                timer.start(IDID); 再次打开这个节点功能。

而后天程序放到it.c即可
void TIM3_IRQHandler(void)
{
        static char count=0;        
        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
       timer_isr(  );
}

收藏 3 评论6 发布时间:2018-7-23 15:53

举报

6个回答
zero99 回答时间:2018-7-23 17:33:07
好像很厉害的样子
勿忘心安110 回答时间:2018-7-24 08:41:36
学习了 涨姿势了
冷眼1121 回答时间:2018-7-24 08:52:31
这个可以好好学习一下,毕竟底层更重要
MrJiu 回答时间:2018-7-24 09:51:13
基本认同,就一个点不认同,不认可把函数放在中断里面执行。。。。如果需要,可以放在大循环里面,虽然没法保证立即执行,但是,比放在中断里面好很多!!!
小耳朵1500922649 回答时间:2018-7-24 09:53:56
楼主,你的mymalloc(SRAMIN,sizeof(time_type)); 没有啊
xiaolingoei 回答时间:2018-7-24 10:22:26
好贴,收藏了

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版