stm32h7关串口中断怎么弄_arduino的中断

本文介绍了中断的基本概念,包括CPU如何处理中断以及中断在UNO和STM32H7中的应用。重点讲解了STM32H7如何关闭串口中断以及Arduino的attachInterrupt()、detachInterrupt()、interrupts()和noInterrupts()等中断管理函数的使用,还展示了通过外部中断控制LED闪烁的实验,并给出了按键中断实现的示例代码。
摘要由CSDN通过智能技术生成

什么是中断

  • CPU执行时原本是按程序指令一条一条向下顺序执行的。 但如果此时发生了某一事件B请求CPU迅速去处理(中断发生),CPU暂时中断当前的工作,转去处理事件B(中断响应和中断服务). 待CPU将事件B处理完毕后, 再回到原来被中断的地方继续执行程序(中断返回),这一过程称为中断 。
a6247bc22ee441f0e0edf8e56eeb5d50.png
  • 中断
  • 打个比方:假如你正在读书,这时电话响了。你放下手中的书,去接电话。接完电话后,再继续回来读书,并从原来读的地方继续往下读。

UNO中断

内部中断

  • 内部中断主要为定时中断,定时中断是指主程序在运行一段程序过后自动进行的中断服务程序。

外部中断

  • 一般由外设发出中断请求,如:键盘中断、打印机中断、外部中断需外部中断源发出中断请求才能发中断。

函数列表

  • attachInterrupt()
  • detachInterrupt()
  • interrupts()
  • noInterrupts()

attachInterrupt()函数说明

void attachInterrupt (uint8_t interruptNum, void(*)(void)userFunc, int mode)

设置中断

指定中断函数. 外部中断有0和1两种, 一般对应2号和3号数字引脚.

参数:

interrupt 中断类型, 0或1fun 对应函数mode 触发方式. 有以下几种:  LOW 低电平触发中断  CHANGE 变化时触发中断  RISING 低电平变为高电平触发中断  FALLING 高电平变为低电平触发中断 

注解:

在中断函数中 delay 函数不能使用, millis 始终返回进入中断前的值. 读串口数据的话, 可能会丢失. 中断函数中使用的变量需要定义为 volatile 类型.

下面的例子如果通过外部引脚触发中断函数, 然后控制LED的闪烁.

int pin = 13;volatile int state = LOW;void setup(){ pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE);}void loop(){ digitalWrite(pin, state);}void blink(){ state = !state;}

detachInterrupt()函数说明

void detachInterrupt (uint8_t interruptNum) 

取消中断

取消指定类型的中断.

参数:

interrupt 中断的类型. 

interrupts()函数说明

#define interrupts() sei()

开中断

例子:

void setup() {}void loop(){ noInterrupts(); // critical, time-sensitive code here interrupts(); // other code here}

noInterrupts()函数说明

#define noInterrupts() cli()

关中断

例子:

void setup() {}void loop(){ noInterrupts(); // critical, time-sensitive code here interrupts(); // other code here}

实验——按键实现外部中断

实验器材

  • 按键开关 一个
  • 面包板一块
  • 470Ω 电阻一个
  • 杜邦线若干

实验实现

按键按下,串口显示器显示“KEY DOWM”

按键松开,串口显示器显示“KEY UP”

实验连线图

77982d76d510381137130dccd39497ed.png

代码实现

int pinInterrupt = 2; //接中断信号的脚 void onChange() {  if ( digitalRead(pinInterrupt) == LOW )  Serial.println("Key Down");  else  Serial.println("Key UP"); } void setup() {  Serial.begin(9600); //打开串口  pinMode( pinInterrupt, INPUT); //设置管脚为输入  //Enable中断管脚, 中断服务程序为onChange(), 监视引脚变化  attachInterrupt( digitalPinToInterrupt(pinInterrupt), onChange, CHANGE); } void loop() {  // 模拟长时间运行的进程或复杂的任务。  delay(1000);} 

实验结果

a1b213264353d133eef346444d51c4f1.png
在ESP32上使用串口2接收数据可以通过中断来实现。下面是一个示例代码,演示如何在ESP32上使用串口2进行中断接收数据: ```cpp #include <HardwareSerial.h> // 定义串口中断接收缓冲区 #define SERIAL2_RX_BUF_SIZE 64 char serial2_rx_buf[SERIAL2_RX_BUF_SIZE]; volatile uint8_t serial2_rx_buf_head = 0; volatile uint8_t serial2_rx_buf_tail = 0; // 定义串口对象 HardwareSerial Serial2(2); void setup() { // 初始化串口2 Serial2.begin(115200); // 设置串口2接收中断 Serial2.enableRxInterrupt(); // 注册中断处理函数 Serial2.attachRxInterrupt(serial2_rx_isr); } void loop() { // 处理接收缓冲区中的数据 while (serial2_rx_buf_head != serial2_rx_buf_tail) { char c = serial2_rx_buf[serial2_rx_buf_tail++]; // 处理接收到的字符 // ... // 循环缓冲区 if (serial2_rx_buf_tail >= SERIAL2_RX_BUF_SIZE) { serial2_rx_buf_tail = 0; } } } // 串口2接收中断处理函数 void IRAM_ATTR serial2_rx_isr() { while (Serial2.available()) { char c = Serial2.read(); // 将接收到的字符存入接收缓冲区 uint8_t next_head = serial2_rx_buf_head + 1; if (next_head >= SERIAL2_RX_BUF_SIZE) { next_head = 0; } if (next_head != serial2_rx_buf_tail) { serial2_rx_buf[serial2_rx_buf_head] = c; serial2_rx_buf_head = next_head; } } } ``` 在这个示例代码中,我们定义了一个大小为64的接收缓冲区,并使用volatile键字声明了两个指针serial2_rx_buf_head和serial2_rx_buf_tail,用来指示缓冲区中的数据读写位置。在setup函数中,我们初始化了串口2,并使用enableRxInterrupt函数启用了串口2的接收中断。同时,我们也注册了一个中断处理函数serial2_rx_isr,用来处理串口2接收中断。 在serial2_rx_isr函数中,我们使用while循环读取串口2接收缓冲区中的所有数据,并将它们存入接收缓冲区。如果接收缓冲区已满,则不会再存入新的数据。在loop函数中,我们不断地处理接收缓冲区中的数据,直到缓冲区为空。 在使用串口中断接收数据时,需要注意以下几点: 1. 在中断处理函数中,不要使用阻塞操作,避免影响其他任务的执行。 2. 接收缓冲区的大小应该足够大,以避免数据丢失。 3. 在处理接收缓冲区中的数据时,需要考虑数据的完整性和正确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值