Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Klawiatura matrycowa obsługująca wiele przycisków

03 Paź 2011 20:49 2254 11
  • Poziom 17  
    Witam, mam taki o to problem, poszukuję przykładu klawiatury matrycowej obsługującej 2 wciśnięte przyciski.
    lub przykład jak osobno odczytywać klawiaturę 3x3 ale w taki sposób ze najpierw odczytujemy 3x2 oraz następnie 3x1.
  • Poziom 17  
    Już opisuję.
    Otóż, stworzyłem na własne potrzeby przejściówkę pilota sterowania z pod kierownicy Renault na pilota sony, okazało się że projekt ma wzięcie gdyż we własnym zakresie przejściówkę można zrobić za około 40 zł, i nie kupować przejściówki za 250.
    Jednak inna faza pilota działa na podobnej lecz nie identycznej zasadzie.

    Otóż problem stanowi fakt, iż rolka przełączająca utwory, stacje radiowe, w pilocie ktory obecnie chciałbym przystosować zwiera ciągle, tzn nie w momencie przełączania lecz ciągle co powoduje ciągłe wciśnięcie jednego z przycisków.
    W poprzednim pilocie zastosowałem klawiaturę matrycową 3x3 i dzięki niej odczytywałem przycisk który wywoływał zadaną funkcję.
    Teraz, przycisków mamy 6 + 3 dla rolki przełączającej (rolka ma 3 pozycje tak aby łatwo można było określić jej stan poprzedni i następny) (tzn. jeżeli poprzedni = 2 a obecny =1 to cofnij, jeżeli obecny = 1 i następny = 3 to cofnij, jeżeli obecny =2 następny =3 to daj do przodu, itd... itd...)
    W poprzedniej wersji nie było problemu działało to jak zwykłe switche i nie stanowiły jednak problemu
    teraz mamy taki myk, że cały czas wciskamy jakiś przycisk przez ciągłe zwieranie rolki, tzn.
    Code:
    |=======|=======|=======|======| 
    
    |Wyj\Wej| 1(1)  | 2(4)  | 3(6) |
    |=======|=======|=======|======|
    |  1(2) |[b]Source [/b]|Off    |   x  |
    |=======|=======|=======|======|
    |  2(3) |Vol-   |  x    |Vol+  |
    |=======|=======|=======|======|
    |  3(5) |Rolka1 |[b]Rolka2[/b] |Rolka3|
    |=======|=======|=======|======|


    Powyższa tabelka przedstawia na pogrubiono sytuację której kod nie potrafi obsłużyć, to znaczy nie da rady wcisnąć 2 przycisków

    Za pomocą ponyższego kodu uda się jedynie wcisnąć jeden przycisk, kolejny wciśnięty już nie zadziała.


    Code:
    [syntax=c]#include <avr/io.h> 
    
    #include <util/delay.h>
    #define time 500
    #define czas 2
    int pozycja;
    /**** DEFINICJE WŁASNYCH FUNKCJI ****/
    /* Konfiguracja sprzętu */
    void init(void)
    {
       /* Konfiguruj portu A jako wyjścia */
       /* Wyjście na ULN2003A */
       DDRA  = 0xFF;
       PORTA = 0x00;
       /* Pilot Renault Clio 3 wejścia 3 wyjścia 
       jak klawiatura 3x3 bez wykorzystania wszystkich przycisków
         
        */
       DDRB  = 0x0f;
       PORTB = 0x7f;
    /*
    OPIS I KONFIGURACJA PRZYCISKÓW PILOTA CLIO
    |=======|=======|=======|======|
    |Wyj\Wej| 1(1)  | 2(4)  | 3(6) |
    |=======|=======|=======|======|
    |  1(2) |Source |Off    |   x  |
    |=======|=======|=======|======|
    |  2(3) |Vol-   |  x    |Vol+  |
    |=======|=======|=======|======|
    |  3(5) |Rolka1 |Rolka2|Rolka3|
    |=======|=======|=======|======|
    */
    }
    /*
    Funkcja sprawdza kolejno wszystkie przyciski klawiatury
    i zwraca numer pierwszego wciśniętego przycisku, albo zero,
    gdy żaden przycisk nie został wciśnięty.
     */
    unsigned char czytaj_przycisk(void)
    {
       unsigned char wejscie,wyjscie,przycisk;
       
       for(wejscie=0x7e,przycisk=1; wejscie>=0x77; wejscie=(wejscie<<1|0x1)&0x7f)
       {
            PORTB = wejscie; 
      _delay_us(czas);
     
          for(wyjscie=0x10; wyjscie< 0x80; wyjscie<<=1, przycisk++){
       
                       if(!(PINB & wyjscie)) return przycisk;
           
           }
       }
       return 0;
    }
    /**** POCZĄTEK PROGRAMU ****/
    /* Definicja funkcji main */
    int main(void)
    {
       unsigned char przycisk;

    /* Konfiguracja portów we/wy */
       init();
    /* Nieskończona pętla */
       pozycja = 0;
       for(;;)
         
       
          if((przycisk = czytaj_przycisk()))
       {
       if (pozycja == 0 && przycisk == 7){
    pozycja = 1;
       }
       if (pozycja == 0 && przycisk == 8){
    pozycja = 2;
       }
       if (pozycja == 0 && przycisk == 9){
    pozycja = 3;
       } 
       
    // na przód   
       if (pozycja == 1 && przycisk == 8){
    pozycja = 2;
    PORTA|= _BV(7);
    _delay_ms(time);
    PORTA&=~_BV(7);
       }
          if (pozycja == 2 && przycisk == 9){
    pozycja = 3;
    PORTA|= _BV(7);
    _delay_ms(time);
    PORTA&=~_BV(7);
       }
          if (pozycja == 3 && przycisk == 7){
    pozycja = 1;
    PORTA|= _BV(7);
    _delay_ms(time);
    PORTA&=~_BV(7);
       }       
    //cofanie
           if (pozycja == 1 && przycisk == 9){
    pozycja = 3;
    PORTA|= _BV(6);
    _delay_ms(time);
    PORTA&=~_BV(6);
       }
           if (pozycja == 3 && przycisk == 8){
    pozycja = 2;
    PORTA|= _BV(6);
    _delay_ms(time);
    PORTA&=~_BV(6);
       }
           if (pozycja == 2 && przycisk == 7){
    pozycja = 1;
    PORTA|= _BV(6);
    _delay_ms(time);
    PORTA&=~_BV(6);
       }
    // Funkcja OFF
          if (przycisk==1){
       
      PORTA|= _BV(0);
      _delay_ms(time);
      PORTA&=~_BV(0);
         
       }     
    //Funkcja Source 
       if (przycisk==2){
       
       PORTA|= _BV(1);
      _delay_ms(time);
      PORTA&=~_BV(1);

    }
       if (przycisk==3){
       
       PORTA|= _BV(2);
      _delay_ms(time);
      PORTA&=~_BV(2);
    }
    // Voll -
       if (przycisk==4){
       PORTA|= _BV(3);
      _delay_ms(time);
      PORTA&=~_BV(3);
      _delay_ms(time); 
    }
    //Voll +
       if (przycisk==5){
      PORTA|= _BV(4);
      _delay_ms(time);
      PORTA&=~_BV(4);
       
       }
    //Zmieniarka
        if (przycisk==6){
         
       PORTA|= _BV(5);
      _delay_ms(time);
      PORTA&=~_BV(5);
       
       }
      /* if (przycisk==7){
      PORTA|= _BV(6);
      _delay_ms(time);
      PORTA&=~_BV(6);
       }
     //  if (przycisk==8){
       PORTA|= _BV(7);
      _delay_ms(time);
      PORTA&=~_BV(7);
       }
       if (przycisk==9){
       PORTA|= _BV(1);
      _delay_ms(100);
      PORTA&=~_BV(1);
      _delay_ms(200); 
       }
    */
    }
    }
      [/syntax]




    Co chce osiągnąć?
    Możliwość wciśnięcia 2 przycisków tzn, jeden przycisk zwarty w zależności od pozycji rolki (cały czas), reszta wywołanie takich funkcji jak vol+ vol-, source, off, itd...

    Spróbuję rozjaśnić małym filmikiem:

    Link
  • Poziom 32  
    Jeśli chcesz stworzyć klawiaturę matrycową, w której można nacisnąć dowolną kombinację klawiszy to każdy przycisk musi być podłączony przez diodę. Jeden wyróżniony przycisk (taki "SHIFT") prościej będzie po prostu podpiąć oddzielnie.
  • Poziom 17  
    Klawiatura matrycowa obsługująca wiele przycisków
    Taki jest schemat pilota, teraz jak to podłączyć??
  • Moderator na urlopie...
    A nie dałoby rady tak: Podajesz low na 1 i odczytujesz rolkę, potem zostawiasz 1 jako input bez podciagania i nie zwracając uwagi na rolkę skanujesz (2,3,4)*(5,6).
    Chyba że źle zrozumiałem schemat...
  • Poziom 32  
    Tutaj jest prościej niż w pełnej matrycy, bo fizycznie niemożliwe jest zwarcie więcej niż jednego styku przez rolkę. Trzeba tylko zagwarantować na tyle dużą częstotliwość odczytu, by nie pominąć żadnej zmiany stanu rolki.

    Jednak, ponieważ nie ma diod przy przyciskach, w sytuacji gdy naciśnięte są równocześnie np. 3 pierwsze przyciski (MUTE, VOL- i VOL+), zwarte ze sobą są 3 linie - 2, 3 i 6. W tym momencie zwarte są także styki lewego przycisku SOURCE i nie ma możliwości jego odczytania.
    Potrzebne są diody (o ile działamy w technice cyfrowej, zero-jedynkowej).
    Jest to jednak znacznie więcej niż podano w wymaganiach i rzadko potrzebne jest aż tak dokładne skanowanie klawiatury.
  • Poziom 16  
    jasiek89 napisał:
    Taki jest schemat pilota, teraz jak to podłączyć??

    Pilot podłączamy bezpośrednio do 6 nóżek AVR-a. Piny 1, 5 i 6 dołączamy do wejść z „pull-up’em“. Piny 2, 3 i 4 spełniają rolę wyjść typu „otwarty dren“.
    Oto cyklicznie powtarzane fazy obsługi:
    a) pin 2 = wyjście/stan niski; piny 3 i 4 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (nazwijmy je S1a, S5a i S6a);
    b) pin 3 = wyjście/stan niski; piny 2 i 4 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (S1b, S5b i S6b);
    c) pin 4 = wyjście/stan niski; piny 2 i 3 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (S1c, S5c i S6c);
    Ruch rolki odzwierciedlają zmiany S1a, S1b i S1c. Stany przycisków: MUTE=S6a, VOL-=S5b itd.
  • Poziom 17  
    jarekz_2 napisał:
    jasiek89 napisał:
    Taki jest schemat pilota, teraz jak to podłączyć??

    Pilot podłączamy bezpośrednio do 6 nóżek AVR-a. Piny 1, 5 i 6 dołączamy do wejść z „pull-up’em“. Piny 2, 3 i 4 spełniają rolę wyjść typu „otwarty dren“.
    Oto cyklicznie powtarzane fazy obsługi:
    a) pin 2 = wyjście/stan niski; piny 3 i 4 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (nazwijmy je S1a, S5a i S6a);
    b) pin 3 = wyjście/stan niski; piny 2 i 4 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (S1b, S5b i S6b);
    c) pin 4 = wyjście/stan niski; piny 2 i 3 = wejście/wielka impedancja; odczytujemy stany pinów 1, 5 i 6 (S1c, S5c i S6c);
    Ruch rolki odzwierciedlają zmiany S1a, S1b i S1c. Stany przycisków: MUTE=S6a, VOL-=S5b itd.


    Może mógłbyś podać jakiś kod jak to obsłużyć niby rozumiem, ale nie umiem napisać tego w c
  • Poziom 16  
    jasiek89 napisał:
    Może mógłbyś podać jakiś kod jak to obsłużyć niby rozumiem, ale nie umiem napisać tego w c

    Nie programuję AVR-ów w C, ale będzie to kod mniej więcej taki (zakładam dla ustalenia uwagi, że piny 1…6 pilota podłączamy do nóżek PB0…PB5):
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Oczywiście gorąco się zaleca stosowanie stałych symbolicznych, predefiniowanych masek bitowych itp.