본문 바로가기
임베디드/Atmega128

ATmega128 인터럽트방식 p247 (pdf246)

by sj0020 2021. 1. 22.

키입력 - 폴링방식 p205 (pdf203), 인터럽트방식 p247 (pdf246)

 

 

sei

cli : global interrupt enable 

 

volatile 쓰는 이유 : volatile 은 변수 값을 참고할 때 캐시메모리에 있는게 아닌(캐시메모리의 값을 참조하는것 =간소화)  실제 메모리주소로 바로 가서 참조한다. 그래서 다른값을 참조하는 일을 없게 한다. 온전히 변수값 그대로를 참조한다

https://ko.wikipedia.org/wiki/Volatile_%EB%B3%80%EC%88%98

 

volatile 변수 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. C/C++ 프로그래밍 언어에서 이 키워드는 최적화 등 컴파일러의 재량을 제한하는 역할을 한다. 개발자가 설정한 개념을 구현하기 위해 코딩된 프로그램을 온전히

ko.wikipedia.org

 

/*
 * 210122 ISR.c
 *
 * Created: 2021-01-22 오전 9:39:37
 * Author : User
 */ 

#include <avr/io.h>
#include <avr/interrupt.h>

#define NUM_EVENT		5
#define REQUEST			1
#define NOT_REQUEST		-1
#define REPLY			0

volatile int req_INT0 = REQUEST, req_INT1 = NOT_REQUEST;

ISR (INT0_vect){
	cli();
	static long event = 0;
	
	if (req_INT0 == REQUEST){
		event++;
		if(event>=NUM_EVENT){
			event = 0;
			req_INT0 = REPLY;	
		}	
	}
	sei();
}

ISR (INT1_vect){
	cli();
	static long event = 0;
	
	if (req_INT1 == REQUEST){
		event++;
		if(event>=NUM_EVENT){
			event = 0;
			req_INT1 = REPLY;
		}
	}
	sei();
}


int main(void)
{
    EIMSK |= (1 << INT0) | (1 << INT1); // 인터럽트 쓰기위해 핀 활성화
	PORTD |= (1 << INT0) | (1 << INT1); // (1 << DDD0). //버튼 인터럽트 초기화
	EICRA = (2 << ISC00) | (3 << ISC10) ; // INT0 : falling edge, INT1 : rising edge
	DDRA |= 1<< DDA0; //LED 출력 설정
	
	sei(); //모든 인터럽트 활성화
    while (1) 
    {
		if(req_INT0 == REPLY){
			PORTA ^= 1<< PA0;
			req_INT0 = NOT_REQUEST;
			req_INT1 = REQUEST;
		}
		else if (req_INT1 == REPLY){
			PORTA ^= 1<<PA0;
			req_INT0 = REQUEST;
			req_INT1 = NOT_REQUEST;
		}		
    }
}

동작은 잘 되나  버튼의 채터링현상을 잡아주는 디바운스 코드가 없기 때문에 
버튼을 원래는 5번 눌러야 동작하는게 맞으나  3번이 될 수도 있고 4번이 될 수도 있고 .. 랜덤임