/*
测试中断相关的代码以及volatile变量的使用
*/
#include <util/atomic.h> // demo4
void blink();
void blinkWithDebounce();
void payDay();
#define LEDPIN 6
#define INTERRUPTPIN 2
volatile byte ledStatus = LOW;
volatile int bankBalance = 0; //demo3 demo4
void setup() {
Serial.begin(115200);
pinMode(LEDPIN, OUTPUT);
pinMode(INTERRUPTPIN, INPUT_PULLUP);
digitalWrite(LEDPIN, LOW);
// demo1:基本中断使用
//attachInterrupt(digitalPinToInterrupt(INTERRUPTPIN), blink, FALLING);
// demo2:中断防止按钮抖动
//attachInterrupt(digitalPinToInterrupt(INTERRUPTPIN), blinkWithDebounce, FALLING);
// demo3 demo4: 中断使用的变量长度超过了MCU的总线宽度
// payDay 16bit > ATmega328P 8bit
attachInterrupt(digitalPinToInterrupt(INTERRUPTPIN), payDay, FALLING);
}
void loop() {
//digitalWrite(LEDPIN, ledStatus);
/*
// demo3:使用 noInterrupts 和 interrupts
noInterrupts();
Serial.println(bankBalance);
interrupts();
*/
// demo4:使用atomic block
ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
Serial.println(bankBalance);
}
}
void blink(){
ledStatus = !ledStatus;
}
long debouncing_time = 15;
volatile unsigned long last_micros;
void blinkWithDebounce(){
if((long)(micros() - last_micros) >= debouncing_time * 1000){
ledStatus = !ledStatus;
last_micros = micros();
}
}
void payDay(){
// 中断赋值类型超过1字节
// 超过了ATmega328P的总线8bit
// 在其他程序段的使用中,需要关闭中断,或者使用atomic
bankBalance = bankBalance + 100;
}