Witam.
Zbudowałem sobie klawiaturę matrycową 4x4 do mikrokontrolera Atmega 128. Klawiatura jest podłączona do 8 wyjść portu D. Obsługę klawiatury chce realizować poprzez przerwania wykorzystując przerwania zewnętrzne INT0...INT3
Poniżej przedstawiam kody:
DEFINICJE:
KONFIGURACJA ORAZ ODBLOKOWANIE PRZERWAN NA INT0...INT3
ODNOSNIKI PRZERWAN
FUNKCJA skan_klaw();
FUNKCJA MAIN
PROBLEM!!!
Zasada działania takiego układu jest następująca:
1) Odpowiednia konfiguracja pinów PORTU D
(PIND0-3 jako wejścia reagujące na GND)
(PIND4-7 jako wyjścia w stanie niskim)
2)w związku z powyższym zwarcie styku powoduje powstanie zbocza opadającego na wejściu i wyzwolenie przerwania zewnętrznego.
I teraz mój problem.
Działają mi wszystkie przyciski oprócz jednej kolumny. Kolumny podporządkowanej Przerwaniu INT0
I teraz gdy na krótko wejście INT0 podpinam pod GND przerwanie zostaje wywołane. Natomiast gdy próbuję je wyzwolić za pomocą przycisku lub na krótko podpinając do pinu wyjścia przerwanie nie zostaje wywołane.
Dodam jeszcze iż sprawdziłem klawiaturę zamieniając przewody w skutek czego doszedłem do wniosku że sama klawiatura jest wykonana poprawnie.
PYTANIE:
Czy wykorzystywanie przerwania INT0 w atmedze128 wymaga poza standardowymi jakiegoś dodatkowego konfigurowania go w rejestrach atmegi?? a może popełniam jakieś błędy w kodzie choć w przypadku kiedy na tym samym kodzie działają inne przyciski wydaje mi się wątpliwa.
Proszę o pomoc.
Pozdrawiam
Zbudowałem sobie klawiaturę matrycową 4x4 do mikrokontrolera Atmega 128. Klawiatura jest podłączona do 8 wyjść portu D. Obsługę klawiatury chce realizować poprzez przerwania wykorzystując przerwania zewnętrzne INT0...INT3
Poniżej przedstawiam kody:
DEFINICJE:
#define KLAD DDRD // PORT LINII STERUJACYCH
#define KLAP PORTD
//#define WE1 0 // LINIA WEJSCIE
//#define WE2 1 // LINIA WEJSCIE
//#define WE3 2 // LINIA WEJSCIE
//#define WE4 3 // LINIA WEJSCIE
#define WY1 4 // LINIA WYJSCIE
#define WY2 5 // LINIA WYJSCIE
#define WY3 6 // LINIA WYJSCIE
#define WY4 7 // LINIA WYJSCIE
//
#define SET_WY1 KLAP |= _BV(WY1)
#define CLR_WY1 KLAP &= ~_BV(WY1)
//
#define SET_WY2 KLAP |= _BV(WY2)
#define CLR_WY2 KLAP &= ~_BV(WY2)
//
#define SET_WY3 KLAP |= _BV(WY3)
#define CLR_WY3 KLAP &= ~_BV(WY3)
//
#define SET_WY4 KLAP |= _BV(WY4)
#define CLR_WY4 KLAP &= ~_BV(WY4)
KONFIGURACJA ORAZ ODBLOKOWANIE PRZERWAN NA INT0...INT3
void on_int0_3()
{
EICRA = 0xAA; // wejscie reaguje na opadajace zbocze
EIMSK = 0x0F; // odblokowuje przerwania na wejsciach INT0...INT3
SREG |= _BV(7); // globalne odblokowanie przerwan
}
ODNOSNIKI PRZERWAN
SIGNAL(SIG_INTERRUPT0)
{
skan_klaw();
}
SIGNAL(SIG_INTERRUPT1)
{
skan_klaw();
}
SIGNAL(SIG_INTERRUPT2)
{
skan_klaw();
}
SIGNAL(SIG_INTERRUPT3)
{
skan_klaw();
}
FUNKCJA skan_klaw();
void skan_klaw(void) // procedura odczytu całej klawiatury
{
//KLAD = 0xF0; // przygotowanie portów WY=> jako wyjścia; WE=> jako wejscia
KLAP = 0xFF; // przygotowanie pinów WY=> stan wysoki; WE=> reaguje na GND
dlms(2);
CLR_WY1;
if(bit_is_clear(PIND,PD0)) // WE1 => S1
{
dlms(20);
if(bit_is_clear(PIND,PD0))
{
lcd_goto(1,2);
lcd_write_string("S1 ");
}
}
if(bit_is_clear(PIND,PD1)) // WE2 => S2
{
dlms(20);
if(bit_is_clear(PIND,PD1))
{
lcd_goto(1,1);
lcd_write_string("S2 ");
}
}
if(bit_is_clear(PIND,PD2)) // WE3 => S3
{
dlms(20);
if(bit_is_clear(PIND,PD2))
{
lcd_goto(1,1);
lcd_write_string("S3 ");
}
}
if(bit_is_clear(PIND,PD3)) // WE4 => S4
{
dlms(20);
if(bit_is_clear(PIND,PD3))
{
lcd_goto(1,1);
lcd_write_string("S4 ");
}
}
SET_WY1;
CLR_WY2;
if(bit_is_clear(PIND,PD0)) // WE1 => S5
{
dlms(20);
if(bit_is_clear(PIND,PD0))
{
lcd_goto(1,1);
lcd_write_string("S5 ");
}
}
if(bit_is_clear(PIND,PD1)) // WE2 => S6
{
dlms(20);
if(bit_is_clear(PIND,PD1))
{
lcd_goto(1,1);
lcd_write_string("S6 ");
}
}
if(bit_is_clear(PIND,PD2)) // WE3 => S7
{
dlms(20);
if(bit_is_clear(PIND,PD2))
{
lcd_goto(1,1);
lcd_write_string("S7 ");
}
}
if(bit_is_clear(PIND,PD3)) // WE4 => S8
{
dlms(20);
if(bit_is_clear(PIND,PD3))
{
lcd_goto(1,1);
lcd_write_string("S8 ");
}
}
SET_WY2;
CLR_WY3;
if(bit_is_clear(PIND,PD0)) // WE1 => S12
{
dlms(20);
if(bit_is_clear(PIND,PD0))
{
lcd_goto(1,1);
lcd_write_string("S12");
}
}
if(bit_is_clear(PIND,PD1)) // WE2 => S11
{
dlms(20);
if(bit_is_clear(PIND,PD1))
{
lcd_goto(1,1);
lcd_write_string("S11");
}
}
if(bit_is_clear(PIND,PD2)) // WE3 => S10
{
dlms(20);
if(bit_is_clear(PIND,PD2))
{
lcd_goto(1,1);
lcd_write_string("S10");
}
}
if(bit_is_clear(PIND,PD3)) // WE4 => S9
{
dlms(20);
if(bit_is_clear(PIND,PD3))
{
lcd_goto(1,1);
lcd_write_string("S9");
}
}
SET_WY3;
CLR_WY4;
if(bit_is_clear(PIND,PD0)) // WE1 => S13
{
dlms(20);
if(bit_is_clear(PIND,PD0))
{
lcd_goto(1,1);
lcd_write_string("S13");
}
}
if(bit_is_clear(PIND,PD1)) // WE2 => S14
{
dlms(20);
if(bit_is_clear(PIND,PD1))
{
lcd_goto(1,1);
lcd_write_string("S14");
}
}
if(bit_is_clear(PIND,PD2)) // WE3 => S15
{
dlms(20);
if(bit_is_clear(PIND,PD2))
{
lcd_goto(1,1);
lcd_write_string("S15");
}
}
if(bit_is_clear(PIND,PD3)) // WE4 => S16
{
dlms(20);
if(bit_is_clear(PIND,PD3))
{
lcd_goto(1,1);
lcd_write_string("S16");
}
}
SET_WY4;
KLAP = 0x0F;
}
FUNKCJA MAIN
int main (void)
{
KLAD = 0xF0; // przygotowanie portów WY=> jako wyjscia; WE=> jako wejscia
KLAP = 0x0F;
on_int0_3();
lcdg_init1();
lcd_wyswietlaj();
while(1)
{
}
}
PROBLEM!!!
Zasada działania takiego układu jest następująca:
1) Odpowiednia konfiguracja pinów PORTU D
(PIND0-3 jako wejścia reagujące na GND)
(PIND4-7 jako wyjścia w stanie niskim)
2)w związku z powyższym zwarcie styku powoduje powstanie zbocza opadającego na wejściu i wyzwolenie przerwania zewnętrznego.
I teraz mój problem.
Działają mi wszystkie przyciski oprócz jednej kolumny. Kolumny podporządkowanej Przerwaniu INT0
I teraz gdy na krótko wejście INT0 podpinam pod GND przerwanie zostaje wywołane. Natomiast gdy próbuję je wyzwolić za pomocą przycisku lub na krótko podpinając do pinu wyjścia przerwanie nie zostaje wywołane.
Dodam jeszcze iż sprawdziłem klawiaturę zamieniając przewody w skutek czego doszedłem do wniosku że sama klawiatura jest wykonana poprawnie.
PYTANIE:
Czy wykorzystywanie przerwania INT0 w atmedze128 wymaga poza standardowymi jakiegoś dodatkowego konfigurowania go w rejestrach atmegi?? a może popełniam jakieś błędy w kodzie choć w przypadku kiedy na tym samym kodzie działają inne przyciski wydaje mi się wątpliwa.
Proszę o pomoc.
Pozdrawiam

![[Atmega128][C] Klawiatura matrycowa 4x4 [Atmega128][C] Klawiatura matrycowa 4x4](https://docs.blackfin.uclinux.org/lib/exe/fetch.php?cache=cache&media=bf54x_keypad.png)