ledi
30.08.2010, 11:45
Da ich kein Pollingverfahren verwende, möchte ich über eine 3x4
Tastenmatrix die einzelnen Tasten über Interrupts abfragen. (Siehe
Datei)
Die 3 Spalten sind mit den Interruptpins Int0, Int1 und Int2 des
Controllers verbunden. Die 4 Zeilen mit den Pins PC4...PC7.
Spaltenpins = als Eingänge geschaltet
Zeilenpins = als Ausgänge geschaltet
Die 3 Spalten ergeben sich über die einzelnen Interrupts, das ist mir klar. Wie mache ich das aber am einfachsten mit den Zeilen und wie werte ich die Tasten aus?
Hier mein vorläufiger Code.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
int main (void)
{
DDRC = (1<<PC4)|(1<<PC5)|(1<<PC6)|(1<<PC7); // Datenrichtung der Zeilen = Ausgang
DDRD = (0<<PIND6); // Datenrichtung Eingang (für Int 0)
DDRB = (0<<PINB2)|(0<<PINB5); // Datenrichtung Eingang (für Int 1, Int 2)
DDRB = (1<<DDB4)|(1<<DDB3)|(1<<DDB0)|(1<<DDB1); // LEDs = Ausgang
PORTD |= (1<<PD6); // Pull-up
PORTB |= (1<<PB2)|(1<<PB5); // Pull-up
EIMSK |= (1<<INT0)|(1<<INT1)|(1<<INT2); // Set Int0 - 2 enable
EICRA |= (1<<ISC01)|(1<<ISC11)|(1<<ISC21); // Set Int0 - 2 on falling edge
sei(); // enable all Interrupts
while (1)
{
PORTB ^= (1<<PB3); // Led on/off
_delay_ms(500); // Warten
}
}
ISR(INT0_vect) // Aufruf Interrupt Service Routine INT0
{
PORTB ^= (1<<PB4); // Led0 on
_delay_ms(100);
}
ISR(INT1_vect) // Aufruf Interrupt Service Routine INT1
{
PORTB ^= (1<<PB0); // Led1 on
_delay_ms(100);
}
ISR(INT2_vect) // Aufruf Interrupt Service Routine INT2
{
PORTB ^= (1<<PB1); // Led2 on
_delay_ms(100);
}
Tastenmatrix die einzelnen Tasten über Interrupts abfragen. (Siehe
Datei)
Die 3 Spalten sind mit den Interruptpins Int0, Int1 und Int2 des
Controllers verbunden. Die 4 Zeilen mit den Pins PC4...PC7.
Spaltenpins = als Eingänge geschaltet
Zeilenpins = als Ausgänge geschaltet
Die 3 Spalten ergeben sich über die einzelnen Interrupts, das ist mir klar. Wie mache ich das aber am einfachsten mit den Zeilen und wie werte ich die Tasten aus?
Hier mein vorläufiger Code.
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
int main (void)
{
DDRC = (1<<PC4)|(1<<PC5)|(1<<PC6)|(1<<PC7); // Datenrichtung der Zeilen = Ausgang
DDRD = (0<<PIND6); // Datenrichtung Eingang (für Int 0)
DDRB = (0<<PINB2)|(0<<PINB5); // Datenrichtung Eingang (für Int 1, Int 2)
DDRB = (1<<DDB4)|(1<<DDB3)|(1<<DDB0)|(1<<DDB1); // LEDs = Ausgang
PORTD |= (1<<PD6); // Pull-up
PORTB |= (1<<PB2)|(1<<PB5); // Pull-up
EIMSK |= (1<<INT0)|(1<<INT1)|(1<<INT2); // Set Int0 - 2 enable
EICRA |= (1<<ISC01)|(1<<ISC11)|(1<<ISC21); // Set Int0 - 2 on falling edge
sei(); // enable all Interrupts
while (1)
{
PORTB ^= (1<<PB3); // Led on/off
_delay_ms(500); // Warten
}
}
ISR(INT0_vect) // Aufruf Interrupt Service Routine INT0
{
PORTB ^= (1<<PB4); // Led0 on
_delay_ms(100);
}
ISR(INT1_vect) // Aufruf Interrupt Service Routine INT1
{
PORTB ^= (1<<PB0); // Led1 on
_delay_ms(100);
}
ISR(INT2_vect) // Aufruf Interrupt Service Routine INT2
{
PORTB ^= (1<<PB1); // Led2 on
_delay_ms(100);
}