ESP32-S3 控制 定时器中断

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 后熄灭 → 循环往复,形成闪烁效果。

五、完整源代码

下面给出本实验的完整工程代码,分为 maintimeled 三部分。


1. 主程序

#include "public.h"
#include "led.h"
#include "time.h"

//定义全局变量

void setup() {
  led_init();             // 初始化LED
  time0_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);//设置引脚为输出模式
}

六、程序分析

  1. 主程序 setup()

    • 初始化 LED
    • 初始化定时器,并设置定时 0.5s 进入一次中断
  2. 定时器初始化

    • timerBegin(0, 80, true):定时器 0,分频 80,计数周期 1us
    • timerAlarmWrite(timer0, 500000, true):500000us = 0.5s 周期中断
    • timerAttachInterrupt(timer0, &time0_isr, true):绑定中断函数
  3. 中断服务函数 time0_isr()

    • 使用 static 变量保存 LED 状态,每次中断翻转一次
    • 通过 digitalWrite() 控制 LED 灯亮灭

七、注意事项

  1. 中断函数要简洁
    ISR 中不要放复杂逻辑或耗时操作,这里只做了 LED 翻转。

  2. 定时器单位是 us
    通过分频设置为 1MHz 后,传入的参数就是微秒,例如 500000 = 0.5s。

  3. ESP32-S3 有 4 个硬件定时器
    如果需要多任务定时,可以同时使用多个定时器(0,1,2,3)。

  4. 区别于 delay()
    delay() 会阻塞主程序,而定时器中断不会影响主循环执行,更适合实时性要求高的应用。


八、实验总结

通过本实验,我们学习了 ESP32-S3 定时器中断的配置与应用

  • 使用 timerBegin() 初始化定时器
  • timerAlarmWrite() 设置定时时间
  • 通过 timerAttachInterrupt() 绑定中断函数
  • 在中断中实现 LED 的周期翻转

最终,LED 实现了 每隔 0.5 秒闪烁,这是一个最经典的定时器中断应用。

posted @ 2025-08-16 14:02  jeikerxiao  阅读(139)  评论(0)    收藏  举报