Arduino学习笔记:串口中断

实习任务需要实现一个优先级变换,因此在此要自学一下串口中断。

1 为何要中断
计算机读取信息有两种方法:查询和中断。查询即为不断读取,直到得到数据。而中断为只有接到数据后才会响应。在Arduino中,把要执行的查询放在loop下面反复执行就属于一种查询。但是查询具有一定缺点。在查询中计算机无法进行其他任务,只能等待数据,而中断使得计算机可以腾出内存进行其他任务,只有接受到数据在打断其他任务开始处理此事件。

例1:按钮中断
这是一个传统的查询实现按钮点灯


const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState = digitalRead(buttonPin);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:
  if (buttonState == HIGH) {
    // turn LED on:
    digitalWrite(ledPin, HIGH);
  }
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW);
  }
}

可以看到在loop里面,程序反复探测按钮输入,这样使得Arduino无法执行其他任务

这是interrupt版本的点灯程序

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
volatile int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT);
  // Attach an interrupt to the ISR vector
  attachInterrupt(0, pin_ISR, CHANGE);
}

void loop() {
  // Nothing here!
}

void pin_ISR() {
  buttonState = digitalRead(buttonPin);
  digitalWrite(ledPin, buttonState);
}

可以看出,这里loop循环没有程序,因为我们现在不需要反复查询。接收按钮的程序放在了interrupt里面

程序解读:
pin_ISR()函数代替了之前loop循环里if else语句。这种函数叫做中断服务程序(interrupt service routine),函数内部即为要处理的中断程序。

编写中断服务程序要注意两点:
1 ISR要尽量简短,执行时间短,毕竟我们一般不想中断太久
2 中断程序没有输入参数和返回值,因此它只能操作全局变量

attachInterrupt()用于设置中断,包含三个参数:
1 中断矢量(interrupt vector)确定哪个引脚会发生中断,这里不是指具体引脚编号,而是Arduino要查找的存储位置,每一个矢量对应一个具体的外部引脚,并且不是所有引脚都可以中断。如Arduino Uno 2和3引脚可以中断,对应矢量0和1
2 中断服务程序,即要执行的函数
3 中断模式(interrupt mode)判断引脚状态
RISING 引脚电压升高
FALLING 引脚电压降低
CHANGE 引脚电压改变
LOW 引脚低电压

注意:volatile
buttonState数据类型不是常规的int,而是volatile int。
volatile指变量值不完全受程序控制,意味着buttonState可能受用户输入而变化,而输入不是程序可以预测的
volatile关键字可以防止编译器错误操作。编译器会把源代码所有没有使用的变量删除,变量buttonState在setup和loop里都没有直接使用,有可能会被编译器直接删除,
volatile关键字可以防止编译器错误优化

你可能感兴趣的:(实习记录,单片机,嵌入式硬件,stm32,arduino)