Próbuję użyć przerwań zmiany pinów do wykrycia naciśniętych przycisków. Do tej pory nigdy nie pracowałem z tego rodzaju przerwaniami i są pewne problemy, więc chcę się upewnić, czy jest to prawidłowe użycie.
Jeśli poprawnie dostałem arkusz danych, należy wykonać następujące czynności, aby użyć przerwania zmiany PIN:
- Ustaw, które kody PIN chcesz kontrolować w rejestrze PCMSK
- Włącz rejestr PIN-ów do kontroli przerwań zmiany PIN (PCICR)
- Włącz przerwania
- Użyj odpowiedniego wektora przerwań
Projekt: Simple Moodlamp, kolory kontrolowane za pomocą 4 przycisków.
Ustawiać:
- Atmega168A-PU
- 4 mini przełączniki przyciskowe
- MOSFETY do sterowania moją 3-watową diodą LED RGB
Oto kod, którego używam, który nie działa zgodnie z oczekiwaniami:
#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);
}
}
Uwaga: Przyciski należy usunąć. Ponieważ próbuję wykonać ten krok po kroku i nie powinno to mieć znaczenia dla włączenia diody LED, zignorowałem to tutaj.
Pytanie: Czy sposób, w jaki próbuję użyć przerwań, jest prawidłowy?
Problemy z moją konfiguracją:
- Przyciski 1-3 są całkowicie ignorowane.
- Button4 uruchamia reset atmega
Rzeczy, które sprawdziłem:
- Przyciski nie są w żaden sposób połączone z resetowanym kodem PIN
- Przyciski są prawidłowo podłączone do GND, jeśli zostaną naciśnięte
- Przyciski nie są podłączone do GND, jeśli nie zostaną naciśnięte
Przyciski działają ładnie, jeśli korzystam z nich bez przerwy, np .:
if (! (PINC & BUTTON4)) {PORTB ^ = NIEBIESKI; }
- Zewnętrzny kryształ 16MHZ / wewnętrzny kryształ
- Wszelkie błędy w routingu
- Używam kondensatora 100nF między PWR i GND na atmega
- VCC (7), GND (8), GND (22), AVCC (20) są połączone (ponieważ nie potrzebuję AREF, nie jest podłączony)