2-2/임베디드

폴링(Polling)과 인터럽트(Interrupt)

P1su 2023. 10. 18. 23:15

폴링(Polling)은 loop문 내에서 계속하여 외부의 입력을 제어한다.

반면 인터럽트(Interrupt)는 외부에서 이벤트가 발생시 loop문을 후순위에 두고 사용자가 지정한 프로세스를 실행한다.

매번 상태를 관찰하지 않아도 된다는 장점이 있다.

attachInterrupt( digitalPinToInterrupt(GPIO), function, mode ) 함수를 통해 구현을 할 수 있다. 

 

digitalPinToInterrupt(GPIO) 

-GPIO로 사용할 핀값을 입력하면 된다. 아두이노에서는 2번과 3번 핀만을 사용할 수 있다.

function

-인터럽트가 발생시 사용할 함수를 작성해준다.

mode

-핀의 상태를 입력해준다. 

총 5가지 상태가 있다.

LOW: pin이 LOW 일때

HIGH: pin이 HIGH 일때

RISING: pin이 LOW에서 HIGH로 갈 때

FALLING: pin이 HIGH에서 LOW로 갈 때

CHANGE: pin이 변할때마다

 

 

LED의 밝기값이 0부터 225까지 증가와 감소를 반복하며, 버튼을 누를 시 그 과정을 멈추게 설계한 회로이다.

 

void setup()
{
  pinMode(11, OUTPUT);
  pinMode(2, INPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(2), sw_pressed, RISING);
}

LED가 11번 핀과 연결되어있으므로 OUTPUT을, 버튼이 2번 핀과 연결되어 있으므로 INPUT으로 설정하였다.

버튼을 누를 때마다 인터럽트가 발생하므로, digitalPinToInterrupt값을 2로 설정하고, 버튼이 눌릴 시 수행할 함수를 

sw_pressed로, pin의 상태가 RISING일때로 attachInterrupt 함수를 구성하였다.

 

int pause = 0;
int delta = 1;
volatile byte state = LOW;
int n = 0;
bool flag = 0;

void sw_pressed(){
  state = HIGH;
  Serial.println("Interrupt..");
}

인터럽트 발생 시 수행할 sw_pressed 함수이다.

state가 LOW에서 HIGH로 갈 시 이벤트가 발생하여서 초기 state 값은 LOW로 설정하였다.

 

if(pause == 0){
    analogWrite(11,n);
    
    if(n == 0)flag = 0;
    else if(n == 255)flag = 1;
      
    if(flag == 0){
      n+=delta;
    }else n-= delta;
    
    delay(10);
    Serial.println(n);
  	
}

loop 내부에서 LED 값을 변화시키는 부분이다. flag가 0일 때는 증가를, 1일 때는 감소하게 하였다.

 

if(state == HIGH){
    pause = pause ? 0 : 1;
    Serial.print("pause= ");
    Serial.println(pause);
    
    state = LOW;
}

loop를 돌다가 버튼을 클릭하면  sw_pressed 함수에 의해서 state가 HIGH로 변경된다.

그때 loop에서는 다음과 같은 부분이 수행된다. 증가와 감소가 멈춘 상태라는 것을 pause 값을 통하여 보여준다.

이때 state를 꼭 다시 LOW로 다시 만들어주어야 한다.

 

int pause = 0;
int delta = 1;
volatile byte state = LOW;
int n = 0;
bool flag = 0;

void sw_pressed(){
  
  state = HIGH;
  Serial.println("Interrupt..");
}
void setup()
{
  pinMode(11, OUTPUT);
  pinMode(2, INPUT);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(2), sw_pressed, RISING);
}

void loop()
{
  if(pause == 0){
    analogWrite(11,n);
    
    if(n == 0)flag = 0;
    else if(n == 255)flag = 1;
      
    if(flag == 0){
      n+=delta;
    }else n-= delta;
    
    delay(10);
    Serial.println(n);
  	
  
  }
  
  if(state == HIGH){
    pause = pause ? 0 : 1;
    Serial.print("pause= ");
    Serial.println(pause);
    
    state = LOW;
  }

}

전체 코드이다.

728x90