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][C] - Nieprawidłowe działanie klawiatury matrycowej 4x4 - przesunięcie kolumn

Hculap 14 Lis 2020 12:53 591 6
REKLAMA
  • #1 19042964
    Hculap
    Poziom 2  
    Witam,
    Korzystam z klawiatury matrycowej (membranowej) 4x4. Niestety nie mogę zamieścić linku, ale łatwo ją znaleźć, np. na botlandzie pod hasłem klawiatura numeryczna membranowa - 16 klawiszy. Postanowiłem, że napiszę prosty kod do obsługi tej klawiatury, jednak po drodze napotkałem na błąd. Zakomentowana instrukcja switch(PINB) w funkcji pobierz_klawisz() działa poprawnie jednak jest dość długa i chciałem ją skrócić. Powstała instrukcja switch(PINB & 0x0F), która jednak nie działa poprawnie. Otóż wciskając na klawiaturze przycisk oznaczony numerem 1, funkcja pobierz_klawisz() powinna zwrócić wartość 1, a zwraca 2, wciskając 2 jest 3, wciskając 3 jest 4, a wciskając A jest 1. Taka sytuacja z przesunięciem pierwszej kolumny na koniec jest w każdym wierszu. Wciskając przycisk od góry powinno być:

    1 2 3 4
    5 6 7 8
    9 10 11 12
    13 14 15 16

    a jest:

    2 3 4 1
    6 7 8 5
    10 11 12 9
    14 15 16 13

    Wiersze klawiatury podłączone są do PB0, PB1, PB2 i PB3 (wejścia), a kolumny do PB4, PB5, PB6 i PB7 (wyjścia). Sprawdzałem kilka razy połączenie czy aby na pewno jest dobrze, ale z zakomentowaną instrukcją switch działało poprawnie więc to chyba nie tu trzeba szukać winnego. Nie wiem czemu tak się dzieje. Uczę się dopiero programować, dlatego proszę o wyrozumiałość bo mój kod może być daleki od idealnego. Korzystam ze środowiska AtmelStudio 7 i bibliotek Procyon AVRlib (choć to w tym przypadku raczej mało istotne). Będę wdzięczny jeśli ktoś byłby mi w stanie wyjaśnić co źle robię albo czemu tak się dzieje.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 19043802
    excray
    Poziom 41  
    Jak oglądam kod zakomentowany i nowy to widzę, że pomyliły się nibble. Przykładowo masz:
    zakomentowane ->case 0xDE:
    nowy: ->case 0x0D (w domyśle 0xED)

    EDIT> Nie, jest ok.
  • REKLAMA
  • #3 19043876
    Hculap
    Poziom 2  
    Przecież PINB & 0x0F ignoruje starszą część bajtu dlatego w nowych case w starszej części jest 0. Najlepiej to widać na zdjęciu z rozpiską.
    [Atmega8][C] - Nieprawidłowe działanie klawiatury matrycowej 4x4 - przesunięcie kolumn
    0x0E, 0x0D, 0x0B i 0x07 odpowiada poszczególnym wierszom, natomiast dokładne określenie, który klawisz został wciśnięty zależy od zmiennej ch (wszystko wykonuje się w pętli for). Ten kod częściowo działa bo po wciśnięciu są zwracane wartości, ale nie wiedzieć czemu pierwsza kolumna przeniesiona jest na koniec i to jest główny problem. Patrząc na zdjęcie powyżej to 1. klawisz jest za 4. a powinien być na początku itd.
  • #4 19044014
    Scyś
    Poziom 3  
    Spróbuj zamienić
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    na
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    jest to trochę bardziej czytelne a działa tak samo.
  • REKLAMA
  • #5 19044060
    Hculap
    Poziom 2  
    Faktycznie działa tak samo, ale problem pozostał. Nadal 1. kolumna jest przesunięta na koniec.

    Dodano po 34 [minuty]:

    Problem rozwiązany, wystarczyło dodać delay po zmianie stanu na porcie B. Niby 1 us ale wpływa na działanie programu. Najwidoczniej bez opóźnienia nim stan się ustabilizował to pętla przeszła już do następnej iteracji. Niby drobnostka, a zabrała sporo czasu.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #6 19045016
    mpier
    Poziom 29  
    Witaj,
    Przemyśl obsługę klawiatury jeszcze raz. Teraz ustawiając kolumny jako wyjścia robisz zwarcie, naciskając jednocześnie dwa przyciski z różnych kolumn. Cały switch jest zbędny. Numer przycisku to zawsze numerwiersza*liczbakolumn+numerkolumny.
  • #7 19045285
    Hculap
    Poziom 2  
    Co do tego, że wciśnięcie dwóch przycisków powoduje zwarcie to zdaje sobie z tego sprawę, ale mam już jakiś kod bazowy który działa i mogę go zmieniać. Co do obliczania numeru przycisku to zakładając, że wciskam pierwszy przycisk w pierwszej kolumnie to: numerwiersza*liczbakolumn + numerkolumny = 1*4 + 1 = 5. No chyba, że przyjmuje się konwencje liczenia od 0 to wtedy: 0*4 + 0 = 0 i dla każdego klawisza wzrasta o 1. Wydaje mi się, że miałeś na myśli tą drugą opcje bo daje bardziej logiczne wyniki i pozwala pozbyć się switch, a w zamian tego zastosować dwie pętle for, zewnętrzna do przesuwania zera po wierszach, a wewnętrzna do przesuwania zera po kolumnach.
REKLAMA