ESP32-arduino,超好玩的定时器!

前言

嵌入式系统的主程序基本上是个大循环,如果在循环里要处理各个任务的请求的话,最粗暴的方式就是轮流查询,简称轮询, 轮询可以解决简单系统的问题,但当请求数量和处理复杂度提升的时候,难免捉襟见肘,中断就是为了解决“按需分配”的资源配置问题。

当然,中断有很几种,外部中断、定时中断等,今天我们要介绍的就是中断里的定时中断!

定时中断——定时执行的中断

直奔主题,编写一个定时中断的程序需要几步呢?我们来编写一个简单的定时器程序,每秒打印一次,如下:

  1. 首先声明一个定时器
/* timerBegin:初始化定时器指针
		第一个参数:设置定时器0(一共有四个定时器0、1、2、3)
		第二个参数:80分频(设置APB时钟,ESP32主频80MHz),80则时间单位为1Mhz即1us,1000000us即1s。
		第三个参数:计数方式,true向上计数 false向下计数
 */
timer = timerBegin(0, 80, true);
  1. 编写中断函数并绑定定时器
/*
	中断服务函数,为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性
*/
void IRAM_ATTR onTimer() {            
  Serial.println('1');
}

/* timerAttachInterrupt:绑定定时器
		 第一个参数:指向已初始化定时器的指针
		 第二个参数:中断服务器函数
		 第三个参数:true边沿触发,false电平触发
*/
timerAttachInterrupt(timer, &onTimer, true);
  1. 初始化定时器,指定定时器、分频、计数方式
/* timerAlarmWrite:配置报警计数器保护值(就是设置时间)
		 第一个参数:指向已初始化定时器的指针
		 第二个参数:定时时间,这里为1000000us  意思为1s进入一次中断
		 第三个参数:是否重载,false定时器中断触发一次  true:死循环
*/
timerAlarmWrite(timer, 1000000, true); 
  1. 启用定时器
	/* timerAlarmEnable:启用定时器
			 第一个参数:指向已初始化定时器的指针
	*/         
  timerAlarmEnable(timer);   
  1. 关闭定时器
/*timerDetachInterrupt:关闭定时器
	 	 第一个参数:指向已初始化定时器的指针
*/
timerDetachInterrupt(timer);
hw_timer_t * timer = NULL;                        // 声明一个定时器

void IRAM_ATTR onTimer() {                        // 中断函数
  Serial.println('1');
}

void setup() {
  Serial.begin(115200);       
	timer = timerBegin(0, 80, true);                // 初始化定时器指针        
  timerAttachInterrupt(timer, &onTimer, true);    // 绑定定时器
  timerAlarmWrite(timer, 1000000, true);          // 配置报警计数器保护值(就是设置时间)
	timerAlarmEnable(timer);                        // 启用定时器
                  
// timerDetachInterrupt(timer);                   // 关闭定时器         
}
 
void loop() {
 
}

需要注意的是:

  • 中断服务程序必须是一个返回void(空)且没有输入参数的函数。

相关参考

[ESP32系列教程]ESP32 Arduino教程:定时器中断

ESP-Arduino玩转外设(五)中断基本概念及Timer中断

ESP32 Timer实现

你可能感兴趣的:(笔记,单片机,嵌入式硬件,ESP32,Arduino,中断)