Arduino ESP8266利用定时器中断控制LED闪烁示例程序

Posted perseverance52

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Arduino ESP8266利用定时器中断控制LED闪烁示例程序相关的知识,希望对你有一定的参考价值。

Arduino ESP8266利用定时器中断控制LED闪烁示例程序

  • 使用库:TimerInterrupt_Generic
  • 库下载地:GitHub地址:https://github.com/khoih-prog/TimerInterrupt_Generic

也可以 Arduino IDE 库管理搜索TimerInterrupt_Generic安装。

  • 串口打印
    >

1秒钟定时还是十分准确的
在这里插入图片描述

  • 示例代码

实现板载LED灯一秒钟循环闪烁

/****************************************************************************************************************************
  TimerInterruptTest.ino
  For ESP8266 boards
  Written by Khoi Hoang
  
  The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
  The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
  The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short.
  Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
  
  Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
  unsigned long miliseconds), you just consume only one Hardware timer and avoid conflicting with other cores' tasks.
  The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
  Therefore, their executions are not blocked by bad-behaving functions / tasks.
  This important feature is absolutely necessary for mission-critical tasks.
  
  Based on SimpleTimer - A timer library for Arduino.
  Author: mromani@ottotecnica.com
  Copyright (c) 2010 OTTOTECNICA Italy
  
  Based on BlynkTimer.h
  Author: Volodymyr Shymanskyy
  
  Built by Khoi Hoang https://github.com/khoih-prog/TimerInterrupt_Generic
  Licensed under MIT license
*****************************************************************************************************************************/
/* Notes:
   Special design is necessary to share data between interrupt code and the rest of your program.
   Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
   variable can not spontaneously change. Because your function may change variables while your program is using them,
   the compiler needs this hint. But volatile alone is often not enough.

   When accessing shared variables, usually interrupts must be disabled. Even with volatile,
   if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
   If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
   or the entire sequence of your code which accesses the data.
*/

#if !defined(ESP8266)
  #error This code is designed to run on ESP8266 and ESP8266-based boards! Please check your Tools->Board setting.
#endif

// These define's must be placed at the beginning before #include "TimerInterrupt_Generic.h"
//这些 define's必须放在#include "TimerInterrupt_Generic.h"前面
// _TIMERINTERRUPT_LOGLEVEL_ from 0 to 4
//中断优先级 从0到4
// Don't define _TIMERINTERRUPT_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
//不能将_TIMERINTERRUPT_LOGLEVEL_中断优先级设置为0级,仅用于特殊的ISR调试。可以挂起系统。
#define TIMER_INTERRUPT_DEBUG         0
#define _TIMERINTERRUPT_LOGLEVEL_     0

#include "TimerInterrupt_Generic.h"

#define BUILTIN_LED     2       // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED

volatile bool statusLed = false;
volatile uint32_t lastMillis = 0;

#define TIMER_INTERVAL_MS       1000

// Init ESP8266 timer 0
ESP8266Timer ITimer;

//=======================================================================
void IRAM_ATTR TimerHandler()
{//中断服务函数
  static bool started = false;

  if (!started)
  {
    started = true;
    pinMode(BUILTIN_LED, OUTPUT);
  }

  digitalWrite(BUILTIN_LED, statusLed);  //Toggle LED Pin
  statusLed = !statusLed;
 Serial.println(millis());
#if (TIMER_INTERRUPT_DEBUG > 0)
  Serial.println("Delta ms = " + String(millis() - lastMillis));
  lastMillis = millis();
#endif
}
//=======================================================================
//                               Setup
//=======================================================================
void setup()
{
  Serial.begin(115200);
  while (!Serial);

  delay(200);

  Serial.print(F("\\nStarting TimerInterruptTest on ")); Serial.println(ARDUINO_BOARD);
  Serial.println(ESP8266_TIMER_INTERRUPT_VERSION);
  Serial.println(TIMER_INTERRUPT_GENERIC_VERSION);
  Serial.print(F("CPU Frequency = ")); Serial.print(F_CPU / 1000000); Serial.println(F(" MHz"));

  // Interval in microsecs
  if (ITimer.attachInterruptInterval(TIMER_INTERVAL_MS * 1000, TimerHandler))
  {
    lastMillis = millis();
    Serial.print(F("Starting ITimer OK, millis() = ")); Serial.println(lastMillis);
  }
  else
    Serial.println(F("Can't set ITimer correctly. Select another freq. or interval"));

}
//=======================================================================
//                MAIN LOOP
//=======================================================================
void loop()
{
}

以上是关于Arduino ESP8266利用定时器中断控制LED闪烁示例程序的主要内容,如果未能解决你的问题,请参考以下文章

Arduino ESP8266定时器中断

Arduino ESP8266基于异步http网页定时器

Arduino ESP8266外部中断触发示例

Arduino ESP8266通过定时器输出PWM示例

Arduino ESP8266/ESP32基于异步http网页定时器

Arduino ESP8266利用SDServer文件管理系统在线调取DHT历史数据