Basılan düğmeleri algılamak için pim değiştirme kesintilerini kullanmaya çalışıyorum. Şimdiye kadar bu tür kesintilerle hiç çalışmadım ve bazı problemler var, bu yüzden bunun doğru kullanım olup olmadığından emin olmak istiyorum.
Veri sayfasını doğru bir şekilde anladıysam, bir pin değiştirme kesintisi kullanmak için aşağıdakiler yapılmalıdır:
- PCMSK kaydında hangi PIN'leri kontrol etmek istediğinizi ayarlayın
- Pin değiştirme kesinti kontrolü (PCICR) için PIN kaydını etkinleştirin
- Kesmeleri etkinleştir
- İlgili kesinti vektörünü kullanın
Proje: Basit Moodlamp, 4 Düğme ile kontrol edilen renkler.
Kurmak:
- Atmega168A-PU
- 4 mini basma düğmesi anahtarı
- 3 Watt RGB LED'imi kontrol etmek için MOSFETS
İşte ben beklendiği gibi çalışmıyor kod kullanıyorum:
#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);
}
}
Not: Düğmeler kaldırılmalıdır. Bu adımı adım adım denediğim için ve LED'i açmak için gerekli olmamalı, burada görmezden geldim.
Soru: Kesmeleri kullanmaya çalıştığım yol doğru mu?
Kurulumumla ilgili sorunlar:
- 1-3 arasındaki düğmeler tamamen yok sayılır.
- Button4, atmega sıfırlamasını tetikliyor
Kontrol ettiğim şeyler:
- Düğmeler hiçbir şekilde sıfırlama PIN'ine bağlı değildir
- Düğmeler basılırsa GND'ye düzgün şekilde bağlanır
- Düğmeler basılmazsa GND'ye bağlı değildir
Kesintisiz olarak kullanırsanız düğmeler güzel çalışır, örneğin:
eğer (! (PINC & BUTTON4)) {PORTB ^ = MAVİ; }
- 16MHZ harici kristal / dahili kristal
- Yönlendirmedeki hatalar
- Atmega'da PWR ve GND arasında 100nF kapasitör kullanıyorum
- VCC (7), GND (8), GND (22), AVCC (20) bağlı (AREF'e ihtiyacım olmadığı için bağlı değil)