임베디드 시스템
5장 인터럽트와 millis
보름달빵
2024. 6. 16. 11:37
실습과제
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_F4 349
#define NOTE_G4 392
#define NOTE_A4 440
#define NOTE_B4 494
#define NOTE_C5 523
#define PIN_PIEZO 10
#define PIN_SWITCH 2 // Button connected to pin 2, 인터럽트 핀 번호 0번 (Int0)
#define PIN_LED 13 // LED connected to pin 13
#define T 200 // 16th note length
#define DB_WAIT 20 // Debouncing wait time
volatile int sw_pressed = 0; // Interrupt flag
void setup() {
pinMode(PIN_PIEZO, OUTPUT);
pinMode(PIN_SWITCH, INPUT_PULLUP);
pinMode(PIN_LED, OUTPUT);
attachInterrupt(0, sw_isr, FALLING); // 버튼이 눌린 순간 인터럽트 함수 실행
Serial.begin(9600);
printMsg("Welcome to John's JukeBox");
}
// Interrupt service routine
void sw_isr() {
sw_pressed = 1;
}
int Notes[] = { NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5 };
String NoteStr[] = { "Do", "Re", "Mi", "Fa", "Sol", "La", "Si", "Do5" };
void play_note(int n, int d) {
if (sw_pressed) return; // 버튼이 눌리면 노래 종료
Serial.print(NoteStr[n] + " ");
int duration = T * d; // 노트 지속 시간
tone(PIN_PIEZO, Notes[n], duration - T * 0.1);
delay(duration);
}
int airplane_note[] = {2, 1, 0, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 0, 1, 2, 2, 2, 1, 1, 2, 1, 0};
int airplane_duration[] = {3, 1, 2, 2, 2, 2, 4, 2, 2, 4, 2, 2, 4, 3, 1, 2, 2, 2, 2, 4, 2, 2, 2, 2, 4};
int airplane_N = 25;
// 비행기 노래 출력
void play_airplane() {
for (int i = 0; i < airplane_N; i++) {
if (sw_pressed) { // 노래 실행 도중 버튼이 눌리면
sw_pressed = 0; // 리셋
break; // 노래 종료
}
play_note(airplane_note[i], airplane_duration[i]);
}
noTone(PIN_PIEZO); // 재생 중지
}
// 메세지 출력
void printMsg(const char *str) {
Serial.print("\r ");
Serial.print(str);
}
// led 함수
void blink() {
for (int i = 0; i < 10; i++) {
if (sw_pressed) {
sw_pressed = 0; // 리셋
break;
}
digitalWrite(PIN_LED, HIGH);
delay(1000);
digitalWrite(PIN_LED, LOW);
delay(1000);
}
}
int state = 0; // State variable
void loop() {
switch (state) {
case 0: // Guide for function 1
printMsg("Play music?");
state = 1;
break;
case 1: // Execute function 1
if(sw_pressed){ // 첫번째 버튼 눌렀을때
printMsg("Playing Music....");
sw_pressed = 0; // 첫번째 버튼에 대한 인터럽트 변수 리셋!!
play_airplane(); // 노래 재생
Serial.print(String("sw_pressed= ")+sw_pressed);
state = 2;
}
break;
case 2: // Guide for function 2
printMsg("Blink the Light?");
state = 3;
break;
case 3: // Execute function 2
if(sw_pressed){
printMsg("Blinking LED....");
sw_pressed = 0; // 리셋
Serial.print(String("sw_pressed= ")+sw_pressed);
blink();
state = 0;
}
break;
default:
break;
}
}
Q 이미 각각의 paly_airplane 과 blink 안에 sw_pressed를 처리하는 부분이 있음에도 불구하고 case문 안에서 sw_pressed를 다시 리셋해주는 이유가 무엇인가 ?
Q case문 안에 있는 sw_pressed가 있을때와 없을때의 차이를 생각해보시오