[stm32]stm32硬件定时器复用——一个定时器承载多组定时任务

之前写过一篇使用stm32的滴答定时器构建多组软件定时器的博客,有感兴趣的可以看一下:
stm32滴答定时器构建多组软件定时器

  • 使用滴答定时器构建软件定时器,其中定时器的超时是靠轮询来实现的,所以精度不高。但是实现方法及其简单,甚至都不用配置什么外设,对于一般的定时任务来说够用了。
  • 如果是对定时精度较高的任务来说,我们最好用硬件定时器来实现了。但是MCU的硬件定时器资源有限,而且定时器开多了可能会混乱,不好管理。能不能用一两组硬件定时器来实现更多的定时任务呢?我们今天就来一起研究一下这个问题。

我们使用定时器的溢出中断来实现这个构想(暂且称之为构想)吧,这里主要说下实现的思想,具体代码暂时没有时间调试哈:

  1. 定义定时任务相关的结构体
typedef void (*pfunc)(uint8_t);

typedef struct TMR_t{
	pfunc cb_tmr;	//定时器超时任务
	uint8_t parameter;	//任务函数参数
	bool  cycle;		//是否循环定时
	uint32_t tick;	//时基
}HTMR_TypeDef;

typedef struct list_t{
	struct list_t *next;		//单向链表->next node
	struct TMR_t *htmr;	//指向定时器任务块
}LIST_TypeDef ;

2.初始化定时器,打开更新(溢出)中断

TIMx_Init();
void TIMx_IRQHandler(void){
  HAL_TIM_IRQHandler(&htimx);
}

3.假设有如下定时任务

//task 1
任务:LED_toggle		超时时间:5s		是否循环:是

//task 2
任务:beep		超时时间:18s		是否循环:否

//task3
任务:print		超时时间:8s			是否循环:否

//task 4
任务:lcd_off		超时时间10s		是否循环:否

4.把定时任务加入到链表中

  • –> LED_toggle / 5s / true --> print / 8s / false --> lcd_off / 10s / false --> beep / 18s / false

  • 5秒定时中断
  • –> LED_toggle() --> print / 3s / false --> LED_toggle / 5s / true --> lcd_off / 5s / fase --> beep / 13s / false

  • 3秒定时中断
  • –> print() --> LED_toggle / 2s / true --> lcd_off / 2s / fase --> beep / 10s / false

  • 2秒定时中断
  • –> LED_toggle() lcd_off() --> LED_toggle / 5s / true --> beep / 8s / false

  • 5秒定时中断
  • –> LED_toggle() --> beep / 3s / false --> LED_toggle / 5s / true

  • 3秒定时器中断
  • –> beep() --> LED_toggle / 2s / true

  • 2秒定时器中断
  • –> beep() --> LED_toggle / 5s / true

以上就是大致的思路,每次进入定时器溢出中断,触发超时任务、更新链表中的数据,更新定时器的溢出周期。
暂时没有时间调试具体代码,有感兴趣的童鞋也可以顺着这个思路实现一下咯

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值