/* * 201105_interrupt.c * * Created: 2020-11-05 오전 9:37:16 * Author : User */ #include <avr/io.h> #include <avr/interrupt.h> #define F_CPU 16000000UL // #define _BV(x) (1 << x) // _BV(PIND2) --> 1<< PIND2 int main(void) { // Configure PD2 as an input using the Data // Direction Register D (DDRD) DDRD &= ~_BV(DDD2); //Enable the pull-up resistor on PD2 using the Port D //Data Register (PORTD) PORTD |= _BV(PORTD2); // Configure external interrupt 0 to generate // an interrupt request on any // logical change using External Interrupt control // Register A (EICRA) EICRA |= _BV(ISC00); //Enable external interrupt 0 using the External Interrupt Mask Register // (EIMSK) EIMSK |= _BV(INT0); // Configure PB5 as an output using the PortB Data Direction Register // (DDRB) DDRB |= _BV(DDB5); // Enable interrupts .SREG sei(); //Loop forever while (1) { // Nothing to do here // All work is done in the ISR } } ISR(INT0_vect){ // read PD2 using the Port D Pin Input Register (PIND) if (PIND & _BV(PIND2)){ // PD2 is high , so button is released // set PB5 low using the Port B DAta Register (PORTB) PORTB &= ~_BV(PORTB5); } else{ // PD2 is low, so button is pressed // Set PB5 high using the Port B data Register (PORTB) PORTB |= _BV(PORTB5); } }
위의 코드는
1. logical change 만 쓸 수 있다 .. rising falling 은 안됨. 왜냐면 if else 부분을 보면 그렇게 짜여져 있음
디바운스 처리가 없기 때문에 채터링으로 계속 rising falling을 빠르게 반복함 그래서 rising falling 을 쓰면 제대로 작동하지 않는다.
2. 내부 풀업저항을 사용하는 코드
그래서 회로를 풀업저항으로 연결해도 되고 또는 그렇게 안해도 된다. 다만 풀다운 저항으로 연결하게 되면 꼬이게 됨 ..
LED 2개, interrupt 2개 사용 코드
https://sj0020.tistory.com/256
ISR = Interrrupt Service Routine
_BV(x) 는 매크로
_BV(x) 의미는 (1 << x)
x에는 어떤 타입이 들어가든 상관없음 .
모두 다 같은 의미 . 어떤것을 써도 상관없다 EICRA = (_BV(ISC00)) | (_BV(ISC00)); EICRA |= 5; EICRA |= 0b00000101; EICRA |= 0x05;
버튼 누르면 falling 되었다 떼는 순간 rising
EIMSK
'임베디드 > Atmega328p' 카테고리의 다른 글
16x2 LCD (LC1621-SMLYH6) (0) | 2020.11.06 |
---|---|
interrupt 2개 사용 LED 2개 제어 (0) | 2020.11.06 |
atmega 328p port ddrx (0) | 2020.11.04 |
button (0) | 2020.11.04 |
arduino uno atmega pin map (0) | 2020.11.03 |