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);
}

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海里的鱼2022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值