누른 버튼을 감지하기 위해 핀 변경 인터럽트를 사용하려고합니다. 지금까지 나는 이런 종류의 인터럽트로 작업 한 적이 없으며 몇 가지 문제가 있으므로 이것이 올바른 사용법인지 확인하고 싶습니다.
데이터 시트를 올바르게 얻은 경우 핀 변경 인터럽트를 사용하려면 다음을 수행해야합니다.
- PCMSK 레지스터에서 제어하려는 PIN 설정
- 핀 변경 인터럽트 제어 (PCICR)를 위해 PIN 레지스터 활성화
- 인터럽트 활성화
- 해당 인터럽트 벡터를 사용하십시오
프로젝트 : Simple Moodlamp, 4 개의 버튼으로 제어되는 색상.
설정:
- Atmega168A-PU
- 미니 푸시 버튼 스위치 4 개
- 3W RGB LED를 제어하는 MOSFET
다음은 예상대로 작동하지 않는 사용중인 코드입니다.
#include <avr/io.h>
#include <stdint.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BUTTON1 (1<<PC5)
#define BUTTON2 (1<<PC4)
#define BUTTON3 (1<<PC3)
#define BUTTON4 (1<<PC2)
#define GREEN (1<<PB1)
#define BLUE (1<<PB2)
#define RED (1<<PB3)
void init() {
// enable LED
DDRB |= GREEN;
DDRB |= BLUE;
DDRB |= RED;
// button pullups
PORTC |= BUTTON1;
PORTC |= BUTTON2;
PORTC |= BUTTON3;
PORTC |= BUTTON4;
// pin change interrupts for buttons
PCMSK1 |= PCINT13;
PCMSK1 |= PCINT12;
PCMSK1 |= PCINT11;
PCMSK1 |= PCINT10;
// enable pin change for buttons
PCICR |= PCIE2;
sei();
}
ISR(PCINT2_vect) {
PORTB = BLUE;
}
void ledTest() {
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
_delay_ms(250);
PORTB ^= RED;
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
_delay_ms(250);
PORTB ^= BLUE;
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
_delay_ms(250);
PORTB ^= GREEN;
}
int main() {
init();
ledTest();
_delay_ms(500);
PORTB |= GREEN;
while(1) {
_delay_ms(100);
}
}
참고 : 버튼을 디 바운스해야합니다. 이 단계별로 시도하고 있으며 LED를 켜는 데 문제가되지 않기 때문에 여기서 무시했습니다.
질문 : 인터럽트를 사용하려는 방식이 올바른가요?
내 설정 문제 :
- 버튼 1 ~ 3은 완전히 무시됩니다.
- Button4가 atmega의 재설정을 트리거합니다
내가 확인한 것들 :
- 버튼이 재설정 PIN에 연결되지 않습니다
- 누르면 버튼이 GND에 올바르게 연결됩니다
- 누르지 않으면 버튼이 GND에 연결되지 않습니다
인터럽트없이 버튼을 사용하면 버튼이 잘 작동합니다.
if (! (PINC & BUTTON4)) {PORTB ^ = 파랑; }
- 16MHZ 외부 결정 / 내부 결정
- 라우팅 오류
- atmega에서 PWR과 GND 사이에 100nF 커패시터를 사용하고 있습니다.
- VCC (7), GND (8), GND (22), AVCC (20)가 연결됨 (AREF가 필요하지 않기 때문에 연결되지 않음)