Saya mencoba menggunakan pin change interrupt untuk mendeteksi tombol yang ditekan. Sampai sekarang saya belum pernah bekerja dengan interupsi semacam ini dan ada beberapa masalah, jadi saya ingin memastikan apakah ini penggunaan yang benar.
Jika saya mendapatkan datasheet dengan benar, hal-hal berikut harus dilakukan untuk menggunakan interupsi perubahan pin:
- Tetapkan PIN mana yang ingin Anda kendalikan dalam register PCMSK
- Mengaktifkan register PIN untuk kontrol interupsi penggantian pin (PCICR)
- Aktifkan interupsi
- Gunakan vektor interupsi yang sesuai
Proyek: Moodlamp Sederhana, Warna dikontrol melalui 4 Tombol.
Mempersiapkan:
- Atmega168A-PU
- 4 sakelar tombol tekan mini
- MOSFET untuk mengontrol LED RGB 3 Watt saya
Berikut adalah kode yang saya gunakan yang tidak berfungsi seperti yang diharapkan:
#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);
}
}
Catatan: Tombol-tombol harus didebound. Karena saya mencoba langkah ini selangkah demi selangkah dan tidak seharusnya mater untuk menyalakan LED, saya mengabaikannya di sini.
Pertanyaan: Apakah cara saya mencoba menggunakan interupsi itu benar?
Masalah dengan pengaturan saya:
- Buttons1-3 benar-benar diabaikan.
- Button4 memicu reset atmega
Hal-hal yang saya periksa:
- Tombol tidak terhubung dengan PIN reset
- Tombol terhubung dengan benar ke GND jika ditekan
- Tombol tidak terhubung ke GND jika tidak ditekan
Tombol berfungsi dengan baik jika saya menggunakannya tanpa gangguan, misalnya:
if (! (PINC & BUTTON4)) {PORTB ^ = BIRU; }
- Kristal eksternal 16MHz / kristal internal
- Kesalahan dalam perutean
- Saya menggunakan kapasitor 100nF antara PWR dan GND pada atmega
- VCC (7), GND (8), GND (22), AVCC (20) terhubung (karena saya tidak perlu AREF, tidak terhubung)