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

Atmega16 - Błędne przypisanie klawiszy w klawiaturze 4x3

fasset 30 Lis 2013 17:20 2697 10
REKLAMA
  • #1 13009656
    fasset
    Poziom 13  
    Witam.
    Oprogramowuje klawiaturę membranową 4x3. Wszystko działa pozą pewnym mankamentem, a mianowicie po naciśnięciu 1 wyświetla się 4, po naciśnięciu 4, 7 - wszystko przesunięte w kolumnie +1. O dziwo inne przyciski (w kolumnie 2 i 3) działają dobrze. Mikrokontroler to Atmega16.
    Kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wiersze podłączone do PB0...PB3 kolumny PB4...PB6
    Nie wiem gdzie leży przyczyna bo po przeanalizowaniu kodu wszystko powinno działać. Np. dla pierwszej iteracji (gdy ma wyświetlić 1):
    if(!(PINB & col))
    PB6/PB5/PB4/PB3/PB2/PB1/PB0
    1 1 0 1 1 1 0 - stan PINB
    0 0 1 0 0 0 0
    Wynik:
    1 1 1 1 1 1 1

    Na PB4 stan niski wymuszony jest naciśnięciem przycisku "1". Więc funkcja powinna zwrócić 1, ale zwraca 4. Co może być nie tak?
  • REKLAMA
  • #2 13009707
    tadzik85
    Poziom 38  
    Daj przed ifem co najmniej jednego NOPa.
  • REKLAMA
  • #3 13009773
    fasset
    Poziom 13  
    Dodałem asm volatile("nop"); i poza opóźnieniem nie pomaga.
  • Pomocny post
    #4 13009789
    tadzik85
    Poziom 38  
    wstaw przed: PORTB = row;

    Chodzi o to to wyjścia nie zdarzą się ustawić a ty już sprawdzasz wejścia.
  • REKLAMA
  • #5 13009829
    fasset
    Poziom 13  
    W takim razie nie przed tylko po PORTB :)
    Teraz działa, dzięki.
  • #7 13096592
    fasset
    Poziom 13  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Chodzi o napisanie kodu, który pozwalałby na wybieranie poszczególnych opcji przez klawiature. Tzn. np. po wybraniu trybu nr 1 mam możliwość regulowania zmiennej f o 2 lub -2.

    Próbowałem zagnieździć pętle while w pętli głównej - niestety nie działa:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W czym może tkwić błąd?
  • #8 13096649
    BlueDraco
    Specjalista - Mikrokontrolery
    W tym, że kiedy klawisze są zwolnione, read_key() zwraca 0, a ty próbujesz wisieć w pętlach, których warunkiem jest wciśnięcie klawisza i sprawdzać w nich, czy nie wciśnięto innego klawisza, niż ten, którego naciśnięcie jest warunkiem powtarzania pętli.
  • #9 13096685
    fasset
    Poziom 13  
    Pierwszy kod działa.
    O to chodzi, żeby po wciśnięciu klawisza 3 wisieć w pętli while(tryb==10) dopóki nie zostanie wciśnięty klawisz 10 (odpowiedzialny za wyjście z pętli do pętli głównej programu) dodatkowo w międzyczasie mieć możliwość (w pętli while(tryb==10)) odczytu klawiatury.

    Jeżeli to złe rozwiązanie to co sugerujesz?
  • REKLAMA
  • #10 13096923
    BlueDraco
    Specjalista - Mikrokontrolery
    Sęk w tym, że w Twoim kodzie zwolnienie klawisza powoduje natychmiastowe wyjście z pętli i już nie masz szans na zauważenie w tej pętli (z której wyszedłeś) zauważyć wciśnięcia innego klawisza.

    Proponuję programowanie w konwencji automatu, zwanego z angielska przez lokalnych dyslektyków "maszyną stanów". Przykładów takich rozwiązań znajdziesz sporo. No i oczywiście nie musi to być robione w żadnej "pętli głównej", ale to już zupełnie inna bajka.
  • #11 13107269
    Tomq
    Poziom 38  
    Chciałem zaadaptować ten kod, jednak mam problem z określeniem warunku zakończenia pętli wybierania wierszy.

    U mnie jest klawiatura szesnastkowa i zamienione są wiersze z kolumnami. Wiersze są podłączone do starszych bajtów PIND, a kolumny do młodszych.
    Wybór kolejnych wierszy wygląda tak: 11101111, 11011111, 10111111, 01111111.

    Działa następujący kod:

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



    Działa również taki kod:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jak widać została wprowadzona zmienna pomocnicza i służąca do odmierzania ilości iteracji. Nie wiem jak zrobić warunek zakończenia iteracji bez użycia tej zmiennej. Próbowałem tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

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

    i tak też:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Jednak w zadnym z tych wypadków nie ma żadnej reakcji na wciśniecie jakiegokolwiek klawisza.

    Edit. Coś w moich kodach musi być nie tak skoro nie widać żadnego zainteresowania ta sprawą.
    Koniec końców uznałem, że nie ma potrzeby warunkować zakończenia iteracji pętli wartością maksymalną rzędu kolumn. Ta zmienna ("i" teraz nazwana "mnożnik") którą wprowadziłem by zatrzymać pętlę i tak jest potrzebna by w łatwy sposób obliczyć numer klawisza który został wciśnięty.

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