ESP8266-Arduino编程实例-定时器与中断

定时器与中断

ESP8266 Timer0和Timer1有两个计时器,其WiFi功能使用一个定时器。我们只能使用一定计时器。为避免崩溃问题,在Arduino框架中建议使用Ticker而不是TimerTicker执行与计时器相同的功能。

本实例将演示如何使用定时器及中断实现LED闪烁。

定时器的速度计算公式如下:

定时器速度(Hz) = 定时器时钟速度(Mhz) / 预分频器

预分频器/分频器是将上述频率除以形成定时器的“滴答(tick)”(增加其计数器)。 然后将 ISR 配置为在特定数量的滴答数后触发。

使用了预分频器,因为定时器最多只能在其计数器中存储 8/16 位,这意味着对于 8 位计数器,它们将每 256/16000000 秒(16us)溢出,对于 16 位计数器,它们将每 65536 / 16000000 秒(4us)溢出 ,这通常远远超过需要。 预分频器允许对其进行缩放以允许更长的间隔。

1、硬件准备

  • ESP8266 NodeMCU开发板一块
  • LED一个
  • 470欧姆电阻一个
  • 杜邦线若干
  • 数据线一条

2、软件准备

  • Arduino IDE或VSCode + PlatformIO

在前面的文章中,对如何搭建ESP8266开发环境做了详细的介绍,请参考:

ESP8266 NodeMCU的引脚介绍在前面的文章中做了详细的介绍,请参考:

3、硬件电路接线图

在这里插入图片描述

4、代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <ESP8266WiFi.h>
#include <Ticker.h>

Ticker timer;
int led = 2;
volatile int interrupts;
volatile bool ledstate = true;


// 定时器触发时中断服务
void IRAM_ATTR onTime() {
interrupts++;
Serial.print("Total Ticks:");
Serial.println(interrupts);
digitalWrite(led,ledstate);
ledstate = !ledstate;
// 使用TIM\_SINGLE重新启动计时器
timer1\_write(2500000);//12us
}

void setup()
{
Serial.begin(115200);
pinMode(led,OUTPUT);
// 绑定中断服务
timer1\_attachInterrupt(onTime);
// 启动定时器
timer1\_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
/\*分频器:
TIM\_DIV1 = 0, // 80MHz (80 ticks/us - 104857.588 us max)
TIM\_DIV16 = 1, // 5MHz (5 ticks/us - 1677721.4 us max)
TIM\_DIV256 = 3 // 312.5Khz (1 tick = 3.2us - 26843542.4 us max)
重装:
TIM\_SINGLE 0 // 在中断例程中,需要写入一个新值以再次启动计时器
TIM\_LOOP 1 // 在中断时,计数器将再次以相同的值开始
\*/

// 设置每0.5s触发一次
timer1\_write(2500000); // 2500000 / 5 ticks per us from TIM\_DIV16 == 500,000 us interval
}

void loop()
{

}

5、代码解析

首先,创建Timer对象

1
2
Ticker timer;

接下来,定义LED引脚

1
2
int led = 4;

接下来,定义定时器计数变量和LED状态变量

1
2
3
volatile int interrupts;
volatile bool ledstate = true;

接下来,定义定时器中断服务

1
2
3
4
5
6
7
8
9
10
void IRAM_ATTR onTime() {
interrupts++;
Serial.print("Total Ticks:");
Serial.println(interrupts);
digitalWrite(led,ledstate);
ledstate = !ledstate;
// 使用TIM\_SINGLE重新启动计时器
timer1\_write(2500000);//12us
}

代码中,向串口输出当前计数值,和切换LED状态。逻辑功能执行完成后,需要重新启动计数器

1
2
timer1\_write(2500000);//12us

setup函数中,初始化串口、LED引脚、定时器,绑定定时器中断服务

1
2
3
4
5
Serial.begin(115200);
pinMode(led,OUTPUT);
timer1\_attachInterrupt(onTime);
timer1\_write(2500000);

文章来源: https://iotsmart.blog.csdn.net/article/details/126026810