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

Posted pocean2012

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP-Arduino玩转外设中断基本概念及Timer中断相关的知识,希望对你有一定的参考价值。

1. 嵌入式开发要深刻理解“资源受限”

嵌入式系统设计开发的主要技术矛盾:芯片和板级资源的限制VS. 任务和事件处理的实时性要求

内存,Flash空间,GPIO数量, ADC/DAC通道数等等,甚至体积,功耗, 嵌入式系统面临的约束条件是比较多的,而需求角度对系统又要求处理及时,响应快还要功耗越低越好......等等,这一对矛盾催生了各种嵌入式系统的核心技术,低功耗节电、实时操作系统、高速串口......都是为了解决上面的技术矛盾。

2. 为神马要有中断机制?

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

 

3. 中断的基本概念和处理流程

中断的文字定义:指当出现需要时, CPU 暂时停止当前程序的执行转而执行处理新情况的程序和执行过程。
          即在程序运行过程中,系统出现了一个必须由 CPU 立即处理的情况,此时, CPU 暂时中止程序的执行转而处理这个新的情况的过程就叫做中断。 基本处理流程看下图是比较清楚的

4. 中断处理的三要素

         •触发条件(类型/通道配置等, 过程即初始化)

中断矢量(中断 入口 / 句柄---挂接到对应的执行位置)中断 操作(中断处理函数)

5. 以Timer中断为例,是最容易理解的,设了闹钟,时间到了就“干活”

看以ESP32-Arduino平台的应用来看各种类型的中断 ,其他外部中断,异常中断等另文展开,案例包括以下几种应用:

*Alarm式的定时中断

*设立后台运行的时钟“滴答”,按节拍处理不同任务(ticker)

*RTC实时时钟,提供和真实世界对齐同步的时钟(年月日,时分秒)

*WDT看门狗

6. 实例代码

案例1-----Timer-sample1 定时中断


#define LED_ON LOW;
#define LED_OFF HIGH;

hw_timer_t *timer=NULL;
uint32_t flag=0;
static void IRAM_ATTR Timer0_CallBack(void);
const int led=22;
int ledState=LED_OFF;

void setup() 
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(led, OUTPUT);
  timer=timerBegin(0,80,true);
  timerAttachInterrupt(timer,Timer0_CallBack,true);
  timerAlarmWrite(timer,1000000,true); // 单位us,定时模式
  timerAlarmEnable(timer); // 启动定时器



void loop() 
  // put your main code here, to run repeatedly:
  if(flag)
    flag=0;
    Serial.println("time out. ");  // 串口打印只需要监测,非时间敏感
    
    
    



static void IRAM_ATTR Timer0_CallBack(void)
  flag=1;
  ledState=!ledState;  // 控制闪灯是时间敏感任务
  digitalWrite(led,ledState);
  

案例2-----利用时钟滴答处理多任务

#include <Arduino.h>
#include <Ticker.h>

// attach a LED to pPIO 21
#define LED_PIN 21

Ticker blinker;
Ticker toggler;
Ticker changer;
float blinkerPace = 0.1;  //seconds
const float togglePeriod = 5; //seconds

void change() 
  blinkerPace = 0.5;


void blink() 
  digitalWrite(LED_PIN, !digitalRead(LED_PIN));


void toggle() 
  static bool isBlinking = false;
  if (isBlinking) 
    blinker.detach();
    isBlinking = false;
  
  else 
    blinker.attach(blinkerPace, blink);
    isBlinking = true;
  
  digitalWrite(LED_PIN, LOW);  //make sure LED on on after toggling (pin LOW = led ON)


void setup() 
  pinMode(LED_PIN, OUTPUT);
  toggler.attach(togglePeriod, toggle);
  changer.once(30, change);


void loop() 
  

案例3--RTC实时时钟

学习下怎样在arduino里获取库支持

工具->管理库->搜索“ESP32TIME”->安装

然后在“示例”里打开对应的例子就OK了. 我们这里用例子说明最简单的调用

/*
esp32time sample
*/

#include <ESP32Time.h>

ESP32Time rtc;

void setup() 
  Serial.begin(115200);
  rtc.setTime(30, 24, 15, 17, 1, 2022);  // 17th Jan 2022 15:24:30


void loop() 
//  Serial.println(rtc.getTime());          //  (String) 15:24:38
//  Serial.println(rtc.getDate());          //  (String) Sun, Jan 17 2021
//  Serial.println(rtc.getDate(true));      //  (String) Sunday, January 17 2021
//  Serial.println(rtc.getDateTime());      //  (String) Sun, Jan 17 2021 15:24:38
//  Serial.println(rtc.getDateTime(true));  //  (String) Sunday, January 17 2021 15:24:38
//  Serial.println(rtc.getTimeDate());      //  (String) 15:24:38 Sun, Jan 17 2021
//  Serial.println(rtc.getTimeDate(true));  //  (String) 15:24:38 Sunday, January 17 2021
//
//  Serial.println(rtc.getMicros());        //  (long)    723546
//  Serial.println(rtc.getMillis());        //  (long)    723
//  Serial.println(rtc.getEpoch());         //  (long)    1609459200
//  Serial.println(rtc.getSecond());        //  (int)     38    (0-59)
//  Serial.println(rtc.getMinute());        //  (int)     24    (0-59)
//  Serial.println(rtc.getHour());          //  (int)     3     (0-12)
//  Serial.println(rtc.getHour(true));      //  (int)     15    (0-23)
//  Serial.println(rtc.getAmPm());          //  (String)  pm
//  Serial.println(rtc.getAmPm(true));      //  (String)  PM
//  Serial.println(rtc.getDay());           //  (int)     17    (1-31)
//  Serial.println(rtc.getDayofWeek());     //  (int)     0     (0-6)
//  Serial.println(rtc.getDayofYear());     //  (int)     16    (0-365)
//  Serial.println(rtc.getMonth());         //  (int)     0     (0-11)
//  Serial.println(rtc.getYear());          //  (int)     2021

  Serial.println(rtc.getTime("%A, %B %d %Y %H:%M:%S"));   // (String) returns time with specified format 
  // formating options  http://www.cplusplus.com/reference/ctime/strftime/


  struct tm timeinfo = rtc.getTimeStruct();
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");   //  (tm struct) Sunday, January 17 2021 07:24:38
  
  delay(1000);

以上是关于ESP-Arduino玩转外设中断基本概念及Timer中断的主要内容,如果未能解决你的问题,请参考以下文章

java中异常概念及分类捕获异常声明异常

Docker 概念及基本用法

Linux基本概念及操作

数据结构复习笔记——树的基本概念及结构

ElasticSearch_基本概念及索引过程

linux信号基本概念及如何产生信号