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

Klawiatura matrycowa obsługująca wiele przycisków

jasiek89 03 Paź 2011 20:49 2488 11
REKLAMA
  • #1 9990093
    jasiek89
    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.
  • REKLAMA
  • #2 9990166
    asembler
    Poziom 32  
    Co?
  • REKLAMA
  • #4 9990554
    jasiek89
    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.
    |=======|=======|=======|======| 
    |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.


    [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:


  • REKLAMA
  • #6 9991033
    krru
    Poziom 33  
    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.
  • REKLAMA
  • #7 9991037
    jasiek89
    Poziom 17  
    Klawiatura matrycowa obsługująca wiele przycisków
    Taki jest schemat pilota, teraz jak to podłączyć??
  • #8 9991057
    piotrva
    VIP Zasłużony dla elektroda
    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...
  • #9 9991163
    krru
    Poziom 33  
    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.
  • #10 9994524
    jarekz_2
    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.
  • #11 10003712
    jasiek89
    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
  • #12 10006330
    jarekz_2
    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 / C++
    Zaloguj się, aby zobaczyć kod

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