logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Atmega8 klawiatura matrycowa + przerwania wewnętrzne

Mateusz.K 31 Sie 2009 09:57 4551 5
REKLAMA
  • #1 6963338
    Mateusz.K
    Poziom 10  
    Witam.

    Niedawno napisałem prosta funkcję obsługi klawiatury matrycowej 4x4. Chciałbym teraz poprawić troche tą funkcję i zrobić ją trochę bardziej profesjonalnie. Czy ma ktoś jakiś pomysł jak przerobić funkcję, żeby nie używać opóźnienia? oraz jak zastąpić while z oczekiwaniem na zwolnienie przycisku? Proszę o wyrozumiałość i pomoc w problemie. Poniżej zamieszczam cześć kodu:

    
    if(i==1) //Sprawdzanie kolumny
    {
    	if((PINB>>4)==14) // Sprawdzanie wiersza
    	{
    		_delay_ms(10); // Przeczekuje drgania
    		if((PINB>>4)==14) // Ponowne sprawdzenie stanu przycisku
    		{
    			...// Kod programu 
    			while((PINB>>4)==14); // czeka, aż klawisz nie zostanie zwolniony
    		}
    	}
    ............. //pozostałe przyciski
    }
  • REKLAMA
  • #2 6963429
    kuuczoo
    Poziom 26  
    Witam
    Do wyjść klawiatury wpinasz równolegle bramkę NAND 4-wejściową (zakładam klawiatura 4x4), a wyjście bramki do wejścia z przerwaniem zewnętrznym (INT0, INT1). W momencie naciśnięcia przycisku z klawiry na wyjściu bramki będzie "1" które wykrywasz (lub zbocze) na INTx. W obsłudze przerwania sprawdzasz klawisz jak normalnie.
  • REKLAMA
  • REKLAMA
  • #4 6963484
    Mateusz.K
    Poziom 10  
    A jest możliwość jakiegoś programowego usprawnienia ?? Bo na tym by mi bardziej zależało. Klawiarure mam podpietą do PORTD.

    hmmm...

    Bardzo ciezki kod do ogarnięcia, zwłaszcza że jestem początkującym programistą. Gdzie sie tutaj definiuje porty ?? i co to jest #include "../Port/Port.h" mógłbym zobaczyć przykładowe użycie tej biblioteki ?
  • REKLAMA
  • #5 6963559
    szelus
    Poziom 34  
    Druga możliwość, to wykorzystanie przerwania od timera. Ustawiasz sobie przerwanie co np. 10ms i w przerwaniu badasz stan klawiatury i zapamiętujesz. Jeżeli ten nowy stan jest inny, niż zapamiętany poprzednio, to np. wpisujesz sobie wartość opóźnienia (do eliminacji drgań styków) do zmiennej. Jeżeli stan się nie zmienił, to zmniejszasz zmienną i jeżeli osiągnie ona zero, to masz nowy, ważny stan z wyeliminowanymi drganiami styków.
    Ten nowy stan możesz przekazać np. przez zmienną globalną do programu głównego.
    Jeżeli chodzi o czekanie na zwolnienie klawisza, to zależy od wymaganej funkcjonalności Twojego programu. Możesz albo np. przekazywać stan "klawisz puszczony" do programu głównego, albo pomijać.

    Poniżej fragment mojego programu (ja mam klawiaturę 4x2).
    
    
    static uint8_t  low_keys;
    static uint8_t old_keys = 0xff; // valid keys from previous keypress 
    static uint8_t scan_keys = 0xff; // last keyboard scan state
    static uint8_t debounce_cnt = 0;
    
    /* .... */
    
    /* fragment procedury obsługi przerwania */
    
        register uint8_t keys;
    
            //read keys
            keys = KBD_INP_PORT & KBD_INP_MASK;
            
            // add second half of keyboard bits from previous scan
            if (low_keys)
            {
                keys |= scan_keys & ~KBD_INP_MASK;
                KBD_SET_ROW_1();
                low_keys = 0;
            }
            else
            {
                keys = (keys << 4) | (scan_keys & KBD_INP_MASK);
                KBD_SET_ROW_0();
                low_keys = 1;
            }
    
            if (keys ^ scan_keys)
            {
                // key state change from previous scan
                // start debounce delay
                scan_keys = keys;
                debounce_cnt = DEBOUNCE_DELAY_CNT;
            }
            else if (keys ^ old_keys)
            {
                // key state same as in previous scan and diffrent
                // than last keypress - check if debouncing has finished
                if (debounce_cnt++ > DEBOUNCE_DELAY_CNT)
                {
                    // valid keypress now detected
                    KeyDecoder(keys, old_keys);
                    old_keys = keys;
                }
            }
    


    EDIT: To w zasadzie taka sama metoda, jak ta zaproponowana przez kol. pburczyna. Sorki, miałem "przerwanie" w trakcie pisania odpowiedzi i odpowiedź kolegi wyżej przeoczyłem.
  • #6 10176181
    marspox
    Poziom 10  
    pburczyn mógł byś wrzucić na forum jeszcze jednego hedera z portami bo widzę że twój kod do matrycówki jest super i chciałbym go zastosować w swoim projekcie jeśli nie masz nic przeciwko
REKLAMA