/*
 * Copyright (c) 2016 https://blog.csdn.net/Wekic
 * All rights reserved
 */
 
#ifndef _MULTI_TIMER_H_
#define _MULTI_TIMER_H_

#include "stdint.h"
#include "stddef.h"

typedef struct Timer {
    uint32_t timeout;         //超时时间
    uint32_t repeat;          //重置时间
    void (*timeout_cb)(void); //回调任务函数
    struct Timer* next;       //下一个任务
}Timer;

#ifdef __cplusplus  
extern "C" {  
#endif  

void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
int  timer_start(struct Timer* handle);
void timer_stop(struct Timer* handle);
void timer_ticks(void);
void timer_loop(void);

// void timer_again(struct Timer* handle);
// void timer_set_repeat(struct Timer* handle, uint32_t repeat);

#ifdef __cplusplus
} 
#endif

#endif
/*
 * Copyright (c) 2020 https://blog.csdn.net/Wekic
 * All rights reserved
 */

#include "multi_timer.h"

//timer handle list head.
static struct Timer* head_handle = NULL;

//Timer ticks
static uint32_t _timer_ticks = 0;

/**
  * @brief  Initializes the timer struct handle.
  * @param  handle: the timer handle strcut.
  * @param  timeout_cb: timeout callback.
  * @param  repeat: repeat interval time.
  * @retval None
  */
 //定时器回调任务初始化
void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat)
{
	// memset(handle, sizeof(struct Timer), 0);
	handle->timeout_cb = timeout_cb;           //回调块
	handle->timeout = _timer_ticks + timeout;  //设置超时时间
	handle->repeat  = repeat;                  //设置回调时间
}

/**
  * @brief  Start the timer work, add the handle into work list.
  * @param  btn: target handle strcut.
  * @retval 0: succeed. -1: already exist.
  */
 //注册任务块
int timer_start(struct Timer* handle)
{
	struct Timer* target = head_handle;  //获取头
	//寻找链表尾
	while(target) {                      //
		if(target == handle) return -1;	//already exist.(重复任务,注册失败)
		target = target->next;
	}
    //链接新的任务(头部插入任务块)
	handle->next = head_handle;
	head_handle = handle;
	return 0;
}

/**
  * @brief  Stop the timer work, remove the handle off work list.
  * @param  handle: target handle strcut.
  * @retval None
  */
 //删除任务块
void timer_stop(struct Timer* handle)
{
	struct Timer** curr;
	//得到链表头地址
	for(curr = &head_handle; *curr; ) {
		//获取现在的地址
		struct Timer* entry = *curr;
		//判断是否与传入的定时任务回调块地址相同
		if (entry == handle) {
			*curr = entry->next;
//			free(entry);
		} 
		//偏移下一个回调块
		else{
			curr = &entry->next;
		}

	}
}

/**
  * @brief  main loop.
  * @param  None.
  * @retval None
  */
 //任务链表检查
void timer_loop()
{
	struct Timer* target;
	//循环 (1.得到链表头 2.判断下一个是否为空 3.继续下一个)
	for(target=head_handle; target; target=target->next) {
		//超出时间
		if(_timer_ticks >= target->timeout) {
			//重载为0,去掉这个定时任务
			if(target->repeat == 0) {
				timer_stop(target);
			} 
			//设置下一次超时时间
			else {
				target->timeout = _timer_ticks + target->repeat;
			}
			//运行回调函数
			target->timeout_cb();
		}
	}
}

/**
  * @brief  background ticks, timer repeat invoking interval 1ms.
  * @param  None.
  * @retval None.
  */
 //提供时间基准
void timer_ticks()
{
	_timer_ticks++;
}

README.md
# MultiTimer

## 简介
MultiTimer 是一个软件定时器扩展模块,可无限扩展你所需的定时器任务,取代传统的标志位判断方式, 更优雅更便捷地管理程序的时间触发时序。

## 使用方法
1.先申请一个定时器管理handle

```
struct Timer timer1;
```
2.初始化定时器对象,注册定时器回调处理函数,设置定时时间(ms),循环定时触发时间

```
timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
```

3.启动定时器

```
timer_start(&timer1);
```
4.设置1ms的硬件定时器循环调用 *timer_ticks()* 以提供时间基准

```
void HAL_SYSTICK_Callback(void)
{
    timer_ticks();
}
```


5.在主循环调用定时器后台处理函数

```
int main() 
{
    ...
    while(1) {
        ...
        timer_loop();
    }
}
```

## Examples

```
#include "multi_timer.h"

struct Timer timer1;
struct Timer timer2;

void timer1_callback()
{
    printf("timer1 timeout!\r\n");
}

void timer2_callback()
{
    printf("timer2 timeout!\r\n");
}

int main()
{
    timer_init(&timer1, timer1_callback, 1000, 1000); //1s loop
    timer_start(&timer1);
    
    timer_init(&timer2, timer2_callback, 50, 0); //50ms delay
    timer_start(&timer2);
    
    while(1) {
        
        timer_loop();
    }
}

void HAL_SYSTICK_Callback(void)
{
    timer_ticks(); //1ms ticks
}
```

## Examples

```
#include "multi_timer.h"

struct Timer timer1;
struct Timer timer2;

void timer1_callback()
{
    printf("timer1 timeout!\r\n");
}

void timer2_callback()
{
    printf("timer2 timeout!\r\n");
}

int main()
{
    timer_init(&timer1, timer1_callback, 1000, 1000); //1s loop       (1S定时任务)
    timer_start(&timer1);
    
    timer_init(&timer2, timer2_callback, 50, 0);          //50ms delay (50ms调用)
    timer_start(&timer2);
    
    while(1) {
        
        timer_loop();
    }
}

void HAL_SYSTICK_Callback(void)
{
    timer_ticks(); //1ms ticks
}
```

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐