ESP32-S3 定时器中断
在嵌入式系统中,定时器中断是一个非常常见的功能。它可以让程序在特定的时间间隔自动执行某些操作,而无需依赖 delay() 或手动轮询。
本实验将基于 ESP32-S3 的硬件定时器,实现 LED 每隔 0.5s 自动闪烁。
一、实验目的
- 学习 ESP32-S3 硬件定时器 的初始化与使用
- 掌握 定时器中断函数(ISR) 的编写方法
- 实现 LED 每隔 0.5s 自动翻转
二、硬件准备
- ESP32-S3 开发板
- LED 模块 × 1
- 杜邦线若干
三、接线说明
| 模块 | 引脚 | ESP32-S3 IO |
|---|---|---|
| LED 模块 | D1 | 3 |
接线非常简单,只需要将 LED 模块的 D1 引脚接到 ESP32-S3 的 IO3 即可。
四、实验现象
程序下载成功后:
- LED 每隔 0.5 秒自动翻转一次状态;
- LED 原来灭 → 0.5s 后点亮 → 0.5s 后熄灭 → 循环往复,形成闪烁效果。
五、完整源代码
下面给出本实验的完整工程代码,分为 main、time 和 led 三部分。
1. 主程序
#include "public.h"
#include "led.h"
#include "time.h"//定义全局变量void setup() {led_init(); // 初始化LEDtime0_init(500000); // 定时器中断初始化,500000us = 0.5s
}void loop() {// 主循环中不需要写任何代码
}
2. 定时器头文件 time.h
#ifndef _time_H
#define _time_H#include "public.h"//变量声明
extern hw_timer_t *timer0;//函数声明
void time0_init(u32 per);
void time0_isr(void);#endif
3. 定时器实现 time.cpp
#include "time.h"
#include "led.h"hw_timer_t *timer0 = NULL;//定时器初始化
//per:定时时间,单位us
void time0_init(u32 per)
{/* timerBegin:初始化定时器指针第一个参数:设置定时器0(一共有四个定时器0、1、2、3)第二个参数:80分频(设置APB时钟,ESP32主频80MHz),80则时间单位为1Mhz即1us,1000000us即1s。第三个参数:计数方式,true向上计数 false向下计数*/timer0 = timerBegin(0, 80, true);/* timerAlarmWrite:配置报警计数器保护值(就是设置时间)第一个参数:指向已初始化定时器的指针第二个参数:定时时间,这里为500000us 意思为0.5s进入一次中断第三个参数:是否重载,false定时器中断触发一次 true:死循环*/timerAlarmWrite(timer0, per, true);/* timerAttachInterrupt:绑定定时器第一个参数:指向已初始化定时器的指针第二个参数:中断服务器函数第三个参数:true边沿触发,false电平触发*/timerAttachInterrupt(timer0, &time0_isr, true); timerAlarmEnable(timer0);//启用定时器//timerDetachInterrupt(timer0);//关闭定时器
}//定时器中断函数
void IRAM_ATTR time0_isr(void)
{static u8 led_sta=0; led_sta=!led_sta;digitalWrite(led1_pin,led_sta);
}
4. LED 头文件 led.h
#ifndef _led_H
#define _led_H#include "public.h"//LED管脚定义
#define led1_pin 3//函数声明
void led_init(void);#endif
5. LED 实现 led.cpp
#include "led.h"//led初始化
void led_init(void)
{pinMode(led1_pin, OUTPUT);//设置引脚为输出模式
}
六、程序分析
-
主程序 setup()
- 初始化 LED
- 初始化定时器,并设置定时 0.5s 进入一次中断
-
定时器初始化
timerBegin(0, 80, true):定时器 0,分频 80,计数周期 1ustimerAlarmWrite(timer0, 500000, true):500000us = 0.5s 周期中断timerAttachInterrupt(timer0, &time0_isr, true):绑定中断函数
-
中断服务函数 time0_isr()
- 使用
static变量保存 LED 状态,每次中断翻转一次 - 通过
digitalWrite()控制 LED 灯亮灭
- 使用
七、注意事项
-
中断函数要简洁
ISR 中不要放复杂逻辑或耗时操作,这里只做了 LED 翻转。 -
定时器单位是 us
通过分频设置为 1MHz 后,传入的参数就是微秒,例如500000= 0.5s。 -
ESP32-S3 有 4 个硬件定时器
如果需要多任务定时,可以同时使用多个定时器(0,1,2,3)。 -
区别于 delay()
delay()会阻塞主程序,而定时器中断不会影响主循环执行,更适合实时性要求高的应用。
八、实验总结
通过本实验,我们学习了 ESP32-S3 定时器中断的配置与应用:
- 使用
timerBegin()初始化定时器 - 用
timerAlarmWrite()设置定时时间 - 通过
timerAttachInterrupt()绑定中断函数 - 在中断中实现 LED 的周期翻转
最终,LED 实现了 每隔 0.5 秒闪烁,这是一个最经典的定时器中断应用。
