Obsługa Klawiatury Wieloprzyciskowej


10
Ocena: None Średnia: 10 (2 głosujących)

W układach mikroprocesorowych bardzo często w roli interfejsu między urządzeniem a jego użytkownikiem wykorzystujemy klawiaturę złożoną z przycisków uSwitch. Gdy jest kilka przycisków to wystarczy proste podłączenie między portem mikrokontrolera a masą, dla większej liczby klawiszy wygodnie będzie zrobić klawiaturę matrycową, bo uzyskamy wtedy większą liczbę klawiszy a wykorzystamy mniej pinów procesora. Przedstawione tutaj procedury dotyczą obsługi tych dwóch typów klawiatury.

Język Bascom AVR

Poniżej przedstawiona jest prosta procedura odczytu czterech przycisków podłączonych do jednego portu, niewrażliwa na drgania styków i pozwalająca ustawić różny czas reakcji przy pojedynczym kliknięciu i podczas trzymania klawisza:

Przyciski:
Sw = PIND And &B11110000             'maskowanie nieużywanych pinów
 
If Sw <> &B11110000 And Stan_sw = Sw Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B01110000:                                   
           'tutaj to co będzie po kliknięciu S1   
        Case &B10110000:                                   
           'tutaj to co będzie po kliknięciu S2 
        Case &B11010000: 
           'tutaj to co będzie po kliknięciu S3                              
        Case &B11100000:         
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:         
           'tutaj to co będzie po kliknięciu S1 i S2 razem        
      End Select
    End If
  Else
    Stan_sw = Sw
    Licznik_sw = 80
  End If
Return

Procedura dotyczy podłączenia jak na rysunku poniżej, zakładamy że inne piny tego portu są wykorzystywane w dowolny sposób i nie mamy wpływu na ich stany logiczne podczas odczytu klawiatury:

Jak widać przyciski są podłączone do starszych 4 bitów portu D mikrokontrolera (żeby nie było za prosto). Musimy zatem uniezależnić się od zmieniających się stanów logicznych na pozostałych 4 bitach tego portu aby nie było problemów z klawiaturą. Wykonujemy to w pierwszej linijce procedury przypisując do zmiennej Sw(byte) wartość całego portu D ale z wyzerowanymi za pomocą polecenia And &B11110000 wartościami najmłodszych bitów (starsze 4 są bez zmian). Jeżeli nic nie zostało naciśnięte to stan odczytu przycisków wynosi zatem &B11110000, bo żaden nie zwarł do masy pinu procesora. Sprawdzane jest to w pierwszej instrukcji warunkowej i w spoczynku kiedy nic nie naciskamy to zawsze wykonują się polecenia po instrukcji Else, czyli przypisywanie aktualnego Stanu klawiatury do zmiennej Stan_sw, która przechowuje poprzednią wartość stanu przycisków, oraz ustawianie Licznik_sw = 80 na określoną wartość.

Gdy Przycisk został wciśnięty to warunek sprawdza jeszcze dodatkowo czy stan klawisza jest taki jak był poprzednio (czy to na przykład nie jest drganie styku) i jeśli tak to zwiększany jest stan licznika (Licznik_sw). Gdy licznik dojdzie do ustalonej wartości (przycisk odpowiednio długo trzymany) to zostanie wykonana akcja dla klawiatury w zależności od tego co zostało kliknięte. Załatwia to wewnętrzna instrukcja Select Case Stan_sw, która wykonuje odpowiedni Case w zależności od stanu klawiszy. Dla przykładu stan &B01110000 odpowiada za kliknięcie przycisku S1 (zero na pinie PD.7), a &B00110000 odpowiada jednoczesnemu wciśnięciu S1 i S2 (zera na pinach PD.7 i PD.6)

Tłumaczenia mogą jeszcze wymagać wartość zmiennej Licznik_sw pojawiające się w dwóch miejscach w procedurze. Zależą one od częstotliwości wywoływania procedury obsługi klawiatury przez program, oraz od żądanego czasu reakcji klawisza na przyciskanie. Wartości te zostały dobrane dla procedury wywoływanej co 4ms. Podczas spoczynku gdy nic nie jest naciskane zmienna Licznik_sw ma wartość 80, a podczas naciśnięcia przycisku jej wartość jest zwiększana aż do 100 po czym następuje reakcja na naciśnięcie, gdy Licznik_sw nie urośnie do 100 zanim puścimy przycisk to zostanie ustawiony znów na 80. Różnica między tymi wartościami pomnożona przez czas odstępu między wywołaniami procedury daje czas reakcji na naciśnięcie przycisku (w tym przypadku: (100-80)*4ms = 80ms). Gdy natomiast licznik urośnie do 100 to jego wartość zostanie wyzerowana i wykona się obsługa klawiatury. Dalsze trzymanie klawisza będzie teraz zwiększało licznik od 0 a zatem podczas trzymania klawisza reakcja nastąpi co 100*4ms=400ms. W efekcie po pierwszym wciśnięciu przycisk zareaguje po 80ms a gdy trzymamy ciągle to co każde 400ms.

Kiedy potrzebujemy większej liczby klawiszy to przeważnie wybór pada na klawiaturę matrycową, podobną do tej na rysunku poniżej(cztery młodsze bity są wejściami, a cztery starsze wyjściami i należy je podłączyć poprzez rezystory np. 1k):

Przy takim ustawieniu jak nie trudno zauważyć nie da się odczytać od razu całej klawiatury. Najprościej jest przeskanować całą klawiaturę a wynik zapisać do 16-bitowej zmiennej typu Word. Mając już stan klawiszy można skorzystać z procedury działającej analogicznie jak wyżej. Skanowanie klawiatury może się odbywać za pomocą procedury:

Matrycowka:
  Klawisze = 0
  For Wiersz = 4 To 7
    Portd = Portd Or &B11111111
    Portd.Wiersz = 0
    Shift Klawisze , Left , 4
    Stan_Wiersz = Pind And &B00001111
    Klawisze = Klawisze + Stan_Wiersz
  Next Wiersz
Return

Procedura ta odczytuje wszystkie przyciski i zapisuje ich stan do 16-bitowej zmiennej Klawisze, jej bity począwszy od najstarszego odpowiadają klawiszom w kolejności: S4, S3, S2, S1, S8, S7, S6, S5, S12, S11, S10, S9, S16, S15, S14, S13. Odczyt przebiega następująco: Za pomocą pętli For zmienna pomocniacza Wiersz zmienia swoje wartości od 4 do 7 co odpowiada ustawieniu stanu niskiego po kolei na pinach PD.4 do PD.7. Jednocześnie podczas gdy kolejne piny przyjmują stan niski z pozostałych 4 młodszych pinów portu odczytywany jest stan 4 przycisków i wpisywany do zmiennej Klawisze, potem bity są przesuwane w lewo o 4 pozycje (Shift Klawisze , Left , 4) aby kolejne 4 przyciski zapisały się na wolnych miejscach w zmiennej Klawisze. Mówiąc w skrócie odczyt klawiatury jest dynamiczny, ustawiamy niski stan logiczny na jednym wierszu, po czym odczytujemy na które młodsze bity portu D stan ten się przeniósł. Potem ustawiamy 0 w drugim wierszu i znowu odczytujemy młodsze bity. Bezpośrednio po odczycie klawiatury musimy jeszcze zinterpretować stan klawiatury, wykonujemy to za pomocą procedury analogicznej jak przy zwykłej klawiaturze:

Przyciski:
If Klawisze <> &B1111111111111111 And Stan_sw = Klawisze Then
    Incr Licznik_sw
    If Licznik_sw = 56 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B1111111111111110:
             'tutaj akcja klawisza S13
        Case &B1111111111111101: 
             'tutaj akcja klawisza S14
        Case &B1111111111111011:
        Case &B1111111111110111: 
        Case &B1111111111101111: 
        Case &B1111111111011111: 
        Case &B1111111110111111: 
        Case &B1111111101111111:
        Case &B1111111011111111: 
        Case &B1111110111111111:
        Case &B1111101111111111: 
        Case &B1111011111111111: 
        Case &B1110111111111111: 
        Case &B1101111111111111: 
        Case &B1011111111111111: 
        Case &B0111111111111111: 
      End Select    
    End If
  Else
    Stan_sw = Klawisze
    Licznik_sw = 50
  End If
Return 

Ponieważ działanie jest takie samo jak w przypadku zwykłej klawiatury, nie będę omawiał szczegółowy wszystkich punktów procedury. Wartości zmiennej Klawisze są 16-bitowe podobnie jak Stan_sw. Działanie liczników jest analogiczne jak wyżej. Ponieważ procedura ta jest bardziej skomplikowana lepiej nie wykonywać jej co 4ms a np co 20ms. Z tak ustawionymi licznikami dało by to czas reakcji 120ms dla pierwszego kliknięcia i 1120ms dla ciągłego trzymania. Wywoływanie procedur klawiatury matrycowej powinno wyglądać tak:

   Gosub Matrycowka
   Gosub Przyciski




Portret użytkownika serv_

Praktyczna teoria

Artykuł prosty, lecz na prawdę trafiony. Mało się o tym mówi, a to tak ważna kwestia.
Na pewno przyda się dla początkujących konstuktorów, jak i jako mała ściągawka dla starszych wyjadaczy ;)

Dzięki za trud włożony w napisanie.
Pozdrawiam!

-

-Mamo, zrób mi kanapkę.
-Sam sobie zrób.
-SUDO Mamo, zrób mi kanapkę.
-OK.

Portret użytkownika mirley

Re: Klawiatury

To są procedurki które używam w swoich projektach. Klawiatura matrycowa, ten patent ze skanowaniem, wymyśliłem sobie niedawno, wcześniejsza procedura zajmowała kilka stron i dodatkowo wstrzymywała program procesora.

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika gparnicki

Re klawiatura

Mam takiego kumpla co zrobił taką klawiaturę tzn na 16 klawiszy tylko są tam jeszcze cztery diody i całość podłączył do połowy portu a nie do całego jak pokazano powyżej. Jak on to obługuje to jeszcze to poznaje. Ale gość wymiata w asemblerze to co my możemy powiedzieć tzn użytkownicy Bascoma.

Portret użytkownika mirley

Re: Klawiatura

Na 4 pinach też by się dało z biedą ale wtedy naciśnięcie dwóch klawiszy naraz nie wiadomo co da a cała rzecz polega na tym abym mógł sobie naciskać kilka klawiszy naraz.

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika gparnicki

Re: Klawiatura

Jesteś wstanie odczytać które klawisze zostały wciśnięte nawet jeżeli jest ich kilka. Po to są tam diody

Portret użytkownika mirley

Re: Klawiatura

Prześlij mi schemat tej klawiatury.... Bo nie bardzo rozumiem jak możesz zdekodować 256 stanów klawiatury na 4 liniach

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika gparnicki

http://picasaweb.google.pl/lh

Portret użytkownika gosc

AT89Cx051

Czy dla procków jak w tytule nie trzeba stosować rezystorów podciągających linie do uSwitch-ów?

Portret użytkownika mirley

Re: Rezystory

Zależy które piny, w 2051, 4051 wszystkie piny poza wyjściami komparatora analogowego mają rezystory w środku

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika dwpl

:D Genialne, tylko S1, S6,

:D Genialne, tylko S1, S6, S11, S16 są dla zmyły przeciwnika. I oczywiście nie można rozpoznać dowolnej informacji tj 2^12 (bo 12 przycisków).

Proszę zauważyć, że zwarcie dowolnej kolumny np. S2 do S4 powoduje zwarcie na liniach sygnałowych, kolejne naciśnięcią są źle rozpoznawane.

Portret użytkownika mirley

Re; klawiatura

Wszystkie przyciski działają jak najbardziej porawnie, nie rozumiem czemu miałby być problem z S1, S6, S11, S16. Albo ja jestem niewyspany albo kolega nie doczytał opisu

Poza tym dodanie rezystorów szeregowych na starszej części portu poprawi sprawę. taki typ klawiatury stosowany jest przeważnie w zamkach szyfrowych itp, gdzie nie klika sie przycisków naraz

------
ps. po dodaniu diod szeregowo z przyciskami wszystkie kombinacje są możliwe 2^16

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika Rrolnik3

Jak wkleić to do programu?

Witam.
Jestem początkujący jeżeli chodzi o Bascom.
Mam zamiar włączać i wyłączać 8 tranzystorów i 6 przekaźników i tutaj się rodzi się moje pytanie jak wkleić to do programu??
Czy istnieje możliwość napisania przykładowego programu lub wytłumaczenia jak to mam zrobić?
Z Góry dziękuję.

Dodam, że chodzi mi o klawiaturę 4x4

-

Rrolnik

Portret użytkownika mirley

Re: Klawiatura

tworzysz sobie program i konfigurujesz timer na przerwanie co około 4ms. W przerwaniu trzeba ustawić zmienną flaga_4ms, której wartość będziesz sprawdzał w pętli głównej.... w pętli głównej jeśli flaga_4ms = 1 to wyzeruj flagę i przejdź do obsługi klawiatury, czyli wywołujesz najpierw:

gosub matrycowka
gosub przyciski

W drugiej procedurze nalezy dopisac akcję przycisków.... co ma się stać jeśli klikniesz konkretny przycisk

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika Macius700

Algorytm do obsługi klawiatury matrycowej

Zamieszczam tutaj algorytm do obsługi 12 przyciskowej klawiatury matrycowej.

Mam pytanie jak ująć warunek, aby wszystkie cztery wejścia sprawdzać jednocześnie?

Portret użytkownika Mario.......

gotowa komenda Bascom

A może by użyć gotowej komendy Bascoma Getkbd() ,mógłbyś zamieścić przykład ,bo w PDF jest trochę nie jasno wyjaśnione :(

Portret użytkownika mirley

Re: Klawiatura

Niestety w tej kwestii nie pomogę bo działanie tego polecenia jest dla mnie nie jasne i sam nie używałem go nigdy

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika LeonPro

RE: Obsługa Klawiatury Wieloprzyciskowej

Witam,
jestem dość początkujący w elektronice i programowaniu ale chciałbym stworzyć klawiaturę na ok. 40 przycisków, każdy przycisk wciskany osobno. Czy da radę to jakoś obsłużyć?

Portret użytkownika mirley

Re: Klawiatura

Jeśli nie będziesz chciał wykrywać naciśnięcia np przycisku 1 5 i 34 naraz to się da w miarę prosto wykonać. Dokładnie na takiej samej zasadzie jak przedstawiłem wyżej, tworząc matrycę przycisków. W twoim przypadku zrobił bym 5 kolumn po 8 przycisków. Wynik skanowania klawiatury trzeba będzie zachować nie w zmiennej 16bit ale w 5 zmiennych 8bit. Na początek sprawdził bym działanie klawiatury z 16 klawiszami a dopiero potem próbował coś zmieniać

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika BIGjack

1wire - klawiatura

Jak pogodzić odczyt z klawiatury w przerwaniach z konwersja ds-a podczas której muszę mieć wyłączone przerwania?

Portret użytkownika mirley

Re: 1-Wire

Do odczyty Ds nie musisz mieć wyłączonych przerwań, po prostu musisz zagwarantować w programie że polecenia wysyłane do ds skończą się zanim przydzie następne przerwanie. Trzeba wysyłąć ewentualnie do ds dane częściami, w pierwszym przerwaniu wysyłam np tylko rozkaz konwersji, w drugim rozkaz adresowania, i co kolejne przerwanie kolejny bajt adresu ds, itd cyklicznie, trzeba by zrobić jakąś zmienną licznikową i tak to wysyłąć.

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika BIGjack

re:re: 1-Wire

no tak ale po rozkazie konwersji następne przerwanie może byc wywołane dopiero po upływie 750ms w innym przypadku transmisja zostanie przerwana, czy da sie to jakos ominąć?
Czy jest już moze jakiś AVR ze sprzętowym 1wire?

Portret użytkownika mirley

Re: 1-wire

Dlaczego niby, przecież 750ms to czas konwersji, wtedy nie jest utrzymywana transmisja. Wysyłasz tylko rozkaz 1 bajt do konwersji i tyle, potem robisz co chcesz w programie i znowu po dowolnie długim czasie łączysz się do ds'a

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika BIGjack

No to wyprowadziłeś mnie z

No to wyprowadziłeś mnie z błędu ponieważ żyłem w przekonaniu że podczas konwersji musi być utrzymywana transmisja.
Czy da się w bascom-ie zrobić obsługę kilku ds-ów i wyświetlić to na 7led-owych wyświetlaczach aby nie było migotania?
Czy masz może jakiś przykład obsługi ds-a w przerwaniach?

Portret użytkownika mirley

RE: DS

Napewno się da zrobić na led i kilka dsów jednak sam tego nigdy nie pisałem, wiem że się da bo znajomy tak zrobił i działa. Nie mam niestety żandnego przykłądu, musisz sam kombinować

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika slavcio2012

jak uruchomić tą klawiaturę

Witam,

mam problem z uruchomieniem tej klawiatury sam bascom nie wyrzuca mi błędów , brak reakcja na naciśnięcie klawiszy

$regfile = "m644pdef.dat"                                   ' specify the used micro
$crystal = 1000000
$baud = 9600
$hwstack = 64
$swstack = 64
$framesize = 64
 
 
'-----------------------------------------------------------------
'konfiguracja wys'wietlacza
 Config Lcd = 16 * 2
 Config Lcdpin = Pin , Db4 = Porta.4 , Db5 = Porta.5 , Db6 = Porta.6 , Db7 = Porta.7 , E = Porta.3 , Rs = Porta.2
 
'-----------------------------------------------------------------
Portd = &B11111111
Dim Klawisze As Byte
Dim Wiersz As Byte
Dim Stan_wiersz As Byte
Dim Stan_sw As Byte
Dim Licznik_sw As Byte
Dim Sw As Byte
Cursor Off
Echo Off
Cls
Do
'Gosub Matrycowka
Gosub Przyciski
Gosub Matrycowka
Loop
 
 
Matrycowka:
  Klawisze = 0
  For Wiersz = 4 To 7
    Portd = Portd Or &B11111111
    Portd.Wiersz = 0
    Shift Klawisze , Left , 4
    Stan_Wiersz = Pind And &B00001111
    Klawisze = Klawisze + Stan_Wiersz
  Next Wiersz
Return
 
Przyciski:
If Klawisze <> &B1111111111111111 And Stan_sw = Klawisze Then
    Incr Licznik_sw
    If Licznik_sw = 56 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B1111111111111110:
        Locate 1 , 1 : Lcd "13"                             'tutaj akcja klawisza S13
        Case &B1111111111111101:
        Locate 1 , 1 : Lcd "14"                             'tutaj akcja klawisza S14
        Case &B1111111111111011:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111111110111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111111101111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111111011111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111110111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111101111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111011111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111110111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111101111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111011111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1110111111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1101111111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1011111111111111:
        Locate 1 , 1 : Lcd "14"
        Case &B1111111111111111:
        Locate 1 , 1 : Lcd "14"
      End Select
    End If
  Else
    Stan_sw = Klawisze
    Licznik_sw = 50
  End If
Return

Portret użytkownika Łb

No dobrze a jak...

Witam! No dobrze a jak rozwiązać problem z taką sytuacją. Naciskam raz zmienna od przycisku przyjmuje wartość i wyświetla na LCD, ale jak przytrzymam dłużej to ciągle się powiększa (wiadomo, pętla) gdzie dać warunek Until loop by działało tylko jeden raz po wciśnięciu aż do puszczenia. A teraz najlepsze - jakiś rok temu to pisałem, działało jak chcę ale kod mi się zgubił po formacie i próby napisania z pamięci raz jeszcze - nie wychodzą! Wiem, że używałem Do loop Until na końcu podprogramu matrycowej klawiatury.

Portret użytkownika slavcio2012

Hmm... czy aby na pewno

Hmm... czy aby na pewno &B1111111111111111 ?

Portret użytkownika mirley

Re: Port

Gdzie masz konfigurację wszystkich portów?

CO do jednorazowego klikania to broż boże żadne do loop bo to zatrzyma program.... wystaczy napisać zamiast Incr Licznik_sw, if Licznik_sw < 60 Then Incr Licznik_sw i po problemie. Zadziała tylko raz

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika slavcio2012

czyli co mam poprawić w

czyli co mam poprawić w kodzie ?

Portret użytkownika mirley

Klawiatura

Przede wszystkim na początku przed konfiguracją LCD masz dać:

Config Portd = &B11110000 : Portd = &B11111111

podobnie dla wszystkich portów procesora nawet tych nie podpiętych do niczego

Poza tym nie masz timera i wywołujesz w do loop bez żadnej przerwy skanowanie klawiatury.... wstaw tam chociaż waitms 4 zanim jakiegoś timera nie użyjesz i nie zrobisz porządnego taktowania

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika mareks6

ATtiny2313

Witam, próbowałem przetestować ten kod na mikrokontrolerze ATtiny2313 oraz uniwersalnej płycie testowej którą Ty mirley zaprojektowałeś (ta z modułami pod różne procesorki). Niestety wyświetla mi się na sekundkę napis "test" który specjalnie zrobiłem by sprawdzić czy procek rusza ale po tym już nic. Poniżej wklejam kod, prosiłbym o wskazówki co zrobiłem źle. Dodam że z powodu iż tiny2313 ma tylko 7 wyprowadzeń portu D, zmieniłem wartość pętli for z 4 do 7 na 4 do 6. W tym momencie klawiatura powinna chodzić bez jednego wiersza. Z niezmienionymi wartościami też chyba powinna działać tak samo ale na wszelki wypadek zmieniłem.

'************* Konfiguracja uC *****************
'***********************************************
$regfile = "attiny2313.dat"
$crystal = 8000000
 
Config Portb = &B11111111 : Portb = &B11111111
Config Portd = &B11110000 : Portd = &B11111111
 
Config Lcdpin = Pin , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5 , E = Portb.1 , Rs = Portb.0       'mirley UPT T2313
Config Lcd = 20 * 4
Cls
Lcd "test"
Wait 1
Cursor Off Noblink
 
Portd = &B11111111
 
 
 
'*************  Zmienne Koniec  ****************
 
Dim Klawisze As Byte
Dim Wiersz As Byte
Dim Stan_wiersz As Byte
Dim Stan_sw As Integer
Dim Licznik_sw As Byte
Dim Sw As Byte
 
'**************  Petla glowna ******************
'***********************************************
Cls
 
Do
 
 
Gosub Przyciski
Gosub Matrycowka
 
 
Loop
 
'************ Petla glowna Koniec **************
 
 
 
 
Matrycowka:
  Klawisze = 0
  For Wiersz = 4 To 6
    Portd = Portd Or &B11111111
    Portd.Wiersz = 0
    Shift Klawisze , Left , 4
    Stan_Wiersz = Pind And &B00001111
    Klawisze = Klawisze + Stan_Wiersz
  Next Wiersz
Return
 
 
 
 
Przyciski:
If Klawisze <> &B1111111111111111 And Stan_sw = Klawisze Then
    Incr Licznik_sw
    If Licznik_sw = 56 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B1111111111111110:
             Cls
             Locate 1 , 1
             Lcd "1"                                        'tutaj akcja klawisza S13
        Case &B1111111111111101:
             Cls
             Locate 1 , 1
             Lcd "2"                                        'tutaj akcja klawisza S14
        Case &B1111111111111011:
             Cls
             Locate 1 , 1
             Lcd "3"
        Case &B1111111111110111:
             Cls
             Locate 1 , 1
             Lcd "4"
        Case &B1111111111101111:
             Cls
             Locate 1 , 1
             Lcd "5"
        Case &B1111111111011111:
             Cls
             Locate 1 , 1
             Lcd "6"
        Case &B1111111110111111:
             Cls
             Locate 1 , 1
             Lcd "7"
        Case &B1111111101111111:
             Cls
             Locate 1 , 1
             Lcd "8"
        Case &B1111111011111111:
             Cls
             Locate 1 , 1
             Lcd "9"
        Case &B1111110111111111:
             Cls
             Locate 1 , 1
             Lcd "10"
        Case &B1111101111111111:
             Cls
             Locate 1 , 1
             Lcd "11"
        Case &B1111011111111111:
             Cls
             Locate 1 , 1
             Lcd "12"
        Case &B1110111111111111:
             Cls
             Locate 1 , 1
             Lcd "13"
        Case &B1101111111111111:
             Cls
             Locate 1 , 1
             Lcd "14"
        Case &B1011111111111111:
             Cls
             Locate 1 , 1
             Lcd "15"
        Case &B0111111111111111:
             Cls
             Locate 1 , 1
             Lcd "16"
 
      End Select
    End If
  Else
    Stan_sw = Klawisze
    Licznik_sw = 50
  End If
Return
 
End

Portret użytkownika mirley

Re: Klawiatura

po pierwsze jesli nie robisz skanu po 4 liniach to nie wiadomo jaki jest stan zmiennej Klawisze po wykonaniu procedury &B1111111111111111 to wartość jaką daje przesunięcie 4 bitów 4 razy e lewo, za każdym razem skanując 1111, jesli robisz pętle 3 razy to stan podstawowy powinien wynosić &B0000111111111111 i w kazdym case powinna być iloczyn logiczny tego stanu z 0 w miejscach klawiszy na które chcesz reagować:
np: &B0000111111111110, &B0000111111111101 itd. 12 klawiszy w sumie dasz radę zrobić.

Poza tym potrzebne jest jakieś opóźnienie np 4ms albo trzeba włożyć tą matrycówkę do timera albo chociaż w do loop dodać waitms 4ms na czas testów. Poza tym na samym początku dał bym w do loop wait 1 i zakomentował gosub przyciski a na lcd wypisywał zmienną klawisze. Zapisz wartości jakie są czytane gdy nic nie naciskasz i gdy naciskasz kolejne przyciski (przynajmniej 1s musisz trzymać dla wait 1s w pętli). Przelicz te wartości na kod binarny za pomocą kalkulatora

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika marcinforty

przyciski

przyciski S1, S6, S11, S16 łączą tę samą linię nie będą działać na pewno ,przyciski aby działać muszą być zawsze wpięte pomiędzy dwie różne linie

Portret użytkownika Dawid

klawiatura 4x4 bascom

chyba tak jest szybciej i miej problemowo

$regfile = "m32def.dat"
$crystal = 16000000
$baud = 9600
 
Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0       
Config Lcd = 16 * 2
 
Config Pind.0 = Output
Config Pind.1 = Input
Config Kbd = Portb , Delay = 100
Dim A As Byte
 
Wait 1
 Cls
 
 
Do
A = Getkbd()
Print A
Lcd A
Loop
End

Portret użytkownika matrix

Re: klawiatura 4x4 bascom

Dawid wrote:
tak jest szybciej i miej problemowo

Nie "miej problemowo" tylko "mniej problemowo" i jeśli się nie mylę to taka konfiguracja we/wy

Config Pind.0 = Output

Nie jest właściwa. Jeśli konfigurujemy wyjście to piszemy

Config Portd.0 = Output

Portret użytkownika gosc 1234

Kalwiatura na Portb

witam próbowałem zmienić kod aby klawiature podłączyć od PB.0 do PB.7 ale wyrzuca mi błąd przy

 Case &B0111111111111111 : Print "15"   

value doen't fit into BYTE [&B0111111111111111]

tu całość kodu

$regfile = "m8adef.dat"
$crystal = 8000000
$baud = 115200
Osccal = 170
 
 
Config Portb = &B11110000 : Portb = &B11111111
 
 
 
Portb = &B11111111
 
Dim Klawisze As Byte
Dim Wiersz As Byte
Dim Stan_wiersz As Byte
Dim Stan_sw As Byte
Dim Licznik_sw As Word
Dim Sw As Byte
 
 
Print "uart ok"
 
Do
 
 Gosub Matrycowka
 Gosub Przyciski
 
 Waitms 10
 
Loop
 
Matrycowka:
  Klawisze = 0
  For Wiersz = 4 To 7
    Portb = Portb Or &B11111111
    Portb.wiersz = 0
    Shift Klawisze , Left , 4
    Stan_wiersz = Pinb And &B00001111
    Klawisze = Klawisze + Stan_wiersz
  Next Wiersz
Return
 
     Przyciski:
If Klawisze <> &B1111111111111111 And Stan_sw = Klawisze Then
    Incr Licznik_sw
    If Licznik_sw = 56 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B1111111111111110 : Print "0"
             'tutaj akcja klawisza S13
        Case &B1111111111111101 : Print "1"
             'tutaj akcja klawisza S14
        Case &B1111111111111011 : Print "2"
        Case &B1111111111110111 : Print "3"
        Case &B1111111111101111 : Print "4"
        Case &B1111111111011111 : Print "5"
        Case &B1111111110111111 : Print "6"
        Case &B1111111101111111 : Print "7"
        Case &B1111111011111111 : Print "8"
        Case &B1111110111111111 : Print "9"
        Case &B1111101111111111 : Print "10"
        Case &B1111011111111111 : Print "11"
        Case &B1110111111111111 : Print "12"
        Case &B1101111111111111 : Print "13"
        Case &B1011111111111111 : Print "14"
        Case &B0111111111111111 : Print "15"
      End Select
    End If
  Else
    Stan_sw = Klawisze
    Licznik_sw = 50
  End If
Return
 
End

jak usune ta linike to chodzi niby dobrze ale tylko polowa klawiatury jak to naprawic ?

Portret użytkownika EDC

Odp. Klawiatura matrycowa

Pisze, ze wynik nie mieści się w Bajcie. Zmienne Stan_sw i Klawisze musisz zadeklarować jako Word, nie Byte. Za to Word dla Licznik_sw nie jest potrzebny. Tam wystarczy Byte.
Pomyśl Byte pomieści tylko osiem Bitów a tylko Word pomieści 16 Bitów.

Miłego dnia

-

BARTek
Moja strona

Portret użytkownika gosc234632456

program na attiny

Witam.
Chcę zrobić włącznik światła sterowany zarówno pilotem jak i włącznikiem monostabilnym.
Mam problem z eliminacją wpływu drgań styków - próbowałem już filtrami RC bo z programowania jestem delikatnie mówiąc kiepski ale się nie udało. Jak więc przystosować ten kod

Przyciski:
Sw = PIND And &B11110000             'maskowanie nieużywanych pinów
 
If Sw <> &B11110000 And Stan_sw = Sw Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B01110000:                                   
           'tutaj to co będzie po kliknięciu S1   
        Case &B10110000:                                   
           'tutaj to co będzie po kliknięciu S2 
        Case &B11010000: 
           'tutaj to co będzie po kliknięciu S3                              
        Case &B11100000:         
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:         
           'tutaj to co będzie po kliknięciu S1 i S2 razem        
      End Select
    End If
  Else
    Stan_sw = Sw
    Licznik_sw = 80
  End If
Return
do jednego przycisku tak żeby wyeliminować wpływ drgań ?
Oto mój kod
$regfile = "attiny13.dat"
$crystal = 1200000
Config Portb.4 = Output
Config Rc5 = Portb.0
Config Pinb.1 = Input
$hwstack = 20
$swstack = 10
$framesize = 40
Dim Address As Byte , Command As Byte
Enable Interrupts
Do
If Pinb.1 = 1 Then 'jeżeli przycisk 1 wciśnięty
Toggle Portb.4 'zmień stan wyprowadzenia
waitms 100
End If
Getrc5(address , Command)
Command = Command And &B01111111
Waitms 1
If Address = 1 And Command = 1 Then ' W miejscu x wpisz adres pilota
Portb.4 = 1                                   'w miejscu y wpisz komendę pilota
End If
If Address = 1 And Command = 3 Then ' W miejscu x wpisz adres pilota
Portb.4 = 0                                   'w miejscu y wpisz komendę pilota
End If
Loop

Portret użytkownika EDC

Odp. Program na Attiny

Prosze, powinno działać. Pisze powinno bo nie testowałem.

$regfile = "attiny13.dat"
$crystal = 1200000
$hwstack = 24
$swstack = 18
$framesize = 16
 
Config Pinb.1 = Input : Portb.1 = 1
Config Portb.4 = Output
 
Config Rc5 = Portb.0, Wait = 2000
 
Dim Lock As Word  'albo Dword
'Dword pomiesci 4 294 967 295 ;) Sekunda to dokładnie predkosc taktowania wiec 1 200 000
Const Dlugosc_blokady = 65535 'najwiecej tyle pomiesci Word
 
Dim Address As Byte , Command As Byte
 
Enable Interrupts
 
Do
 
Debounce Pinb.1 , 0 , Zmien , Sub
 
Getrc5(address , Command)
Command = Command And &B01111111
 
If Lock = 0 Then
 
  If Address = 1 And Command = 1 Then                       ' W miejscu x wpisz adres pilota
   Portb.4 = 1
    Lock = Dlugosc_blokady                                  'w miejscu y wpisz komendę pilota
  End If
 
  If Address = 1 And Command = 3 Then                       ' W miejscu x wpisz adres pilota
   Portb.4 = 0
    Lock = Dlugosc_blokady                                  'w miejscu y wpisz komendę pilota
  End If
 
End If
 
If Lock > 0 Then Decr Lock
Loop
 
Zmien:
Toggle Portb.4                                              'zmień stan wyprowadzenia
Return

Miłego dnia

-

BARTek
Moja strona

Portret użytkownika gosc234632456

Niestety teraz uP nie reaguje

Niestety teraz uP nie reaguje w ogóle na włącznik :)a da się zrobić tak że po zmianie stanu na wyjściu PB.4 układ będzie mógł zmienić stan na przeciwny dopiero po upływie np 1s? Drgania styków większe niż 30ms chyba nie są więc to by raczej problem rozwiązało :) tylko jak to wpisać?
P.S Dziękuję za odpowiedź :)

Portret użytkownika EDC

Odp. Program na Attiny

Nawet tak proste kody, jak widać, trzeba potestować :D Problem leżał w instrukcji Getrc5, a dokładniej w jej konfiguracji. Dopisałem teraz czas - ile funkcja ma oczekiwać na komendę, po czym ma sobie darować. Taki kod wydaje się działać ;)
Żeby niepotrzebnie nie śmiecić zmieniłem swój poprzedni kod o zapis Config Rc5 = Portb.0, Wait = 2000
Aaaaa.. zapomniałbym o blokadzie kliknięcia na której Ci zależało..proszę bardzo!
Ewentualnie zwiększ sobie zmienną do Dword i wpisz większa wartość do odliczenia.

Spróbuj ;)
Miłego dnia

-

BARTek
Moja strona

Portret użytkownika gosc234632456

Jesteś wielki kolego!

Jesteś wielki kolego! Siedziałem nad tym dwa tygodnie a tobie zajęło to pewnie 10min :)Włącznik ręczny działa i wreszcie nie ma dyskoteki jak włączam żarówkę - luba będzie wreszcie zadowolona, że są jakieś postępy w pracach nad włącznikiem światła na pilota dla niej :D Co do RC5 to jeszcze nie wiem czy działa bo muszę pilot zrobić dopiero ale może podołam :D
Dzięki i również miłego dnia życzę ;)

Portret użytkownika pablo5-5

Długie naciśnięcie

Witam,
Czy w tej procedurze da się zrobić taką rzecz:
1. Jeżeli przycisk będzie naciśnięty krótko (poniżej 1s) wykona się "jedna czynność"
2. Jeżeli przycisk będzie naciśnięty długo (np. dłużej niż 5s) wykona się "druga czynność", ale jednocześnie nie wykona się "czynność pierwsza"

Czyli krótko mówiąc czy da się rozróżnić w tej procedurze długi i krótkie naciśnięcie przycisku?

Pozdrawiam,
PWcisło

Portret użytkownika mirley

Re: Przyciski

Chyba da się tak zrobić w prosty sposob...

Przyciski:
Sw = PIND And &B11110000             'maskowanie nieużywanych pinów
 
If Sw <> &B11110000 And Stan_sw = Sw Then
    If Licznik_sw <255 Then Incr Licznik_sw
 
  Else
     if Licznik_sw>10 Then
       Select Case Stan_sw
        Case &B01110000:                                   
 
           if Licznik_sw < 100 Then
             'tutaj to co będzie po krotkim kliknięciu S1 
           else
              'tutaj to co będzie po dlugim kliknięciu S1   
           End if  
 
        Case &B10110000:                                   
           'tutaj to co będzie po kliknięciu S2 
        Case &B11010000: 
           'tutaj to co będzie po kliknięciu S3                              
        Case &B11100000:         
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:         
           'tutaj to co będzie po kliknięciu S1 i S2 razem        
      End Select
    End If
    Stan_sw = Sw
    Licznik_sw = 0
  End If
Return

Nie sprawdzałem tego, napisałem to na szybko z głowy ale idea powinna być dobra. Działanie będzie dopiero po puszczeniu klawisza ale bedzie działał teraz krótkie naciśnięcie poniżej 100 wywołań procedury a długie powyżej 100. Czyli jak procedura będzie wywoływana co 10ms to uzyskasz czas 1sek. Można też zwiększyć licznik, dac zmienną word i wtedy można więcej pokombinować

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika pablo5-5

Długie naciśnięcie

Dzięki za odpowiedź.
Zastanawiam się skąd procedura Select Case po puszczeniu przycisku będzie wiedziała, do którego case'a "skoczyć"? Do zmiennej Stan_sw będzie wpisywana za każdym razem wartość &B11110000, tak mi się przynajmniej wydaje. Dlatego chyba linijka Stan_sw = Sw powinna być zaraz po If Licznik_sw <255 Then...
Chyba, że się mylę?

Tylko, że ta procedura nie załatwi mi jeszcze jednej sprawy, o której w sumie wcześniej nie wspomniałem. A mianowicie - krótkie naciśnięcie przycisku chciałbym, aby zmieniało stan zmiennej z 0 na 1, a długie naciśnięcie tego samego przycisku (powiedzmy minimum 3s) i dalsze trzymanie go, inkrementowało inną zmienną. W tej wersji, procedura wykona się dopiero po puszczeniu przycisku, czyli o inkrementacji mogę zapomnieć.

Da się taką procedurę zrobić? Będę wdzięczny za każdą pomoc.

Portret użytkownika EDC

Odp. Klawiatura matrycowa

Da się zrobić na pewno.
Masz w swoim projekcie Timer? Potrzebujesz tam klawiatury czy przycisk?
Klawiaturki Mirleya używam do "zadań specjalnych" kiedy potrzebne jest wykrycie wciśnięcia dwóch przycisków na raz. Tego Getkbd() nie potrafi ...ale na codzień to Getkbd() załatwia wszystko.
Właśnie zrobiłem dla zabawy taki konwerter jednostek i on rozróżnia długie i krótkie wciśnięcia na klawiaturce 4x4.

-

BARTek
Moja strona

Portret użytkownika mirley

Re: Klawiatura

Czemu od razu nie piszesz jak to dokładnie ma działać. W obecnej wersji po puszczeniu klawiatury stan klawiszy zostaje w zmiennej stan_sw.

Da sie to wsztko zrobić ale opsze to słowami bo troche mi brak czasu na napisanie całej procedurki i jej sprawdzenie....

Przyciski:
Sw = PIND And &B11110000             'maskowanie nieużywanych pinów
 
If Sw <> &B11110000 And Stan_sw = Sw Then
    Incr Licznik_sw
'to trzeba dobrac w celu zapewnienia czestości powtarzania przycisku może będzie konieczna wieksza zmienna
    if licznik_sw = 250 then licznik = 0  'powtarzanie dlugich klikniec co 250 wywolan
 
    if Licznik_sw = 200 Then  'dlugie kliniecia klawiszy co 200 wywolan procedury
      set dlugi_klawisz
      Select Case Stan_sw
        Case &B01110000:                                   
             'tutaj to co będzie po kliknięciu S1 
        Case &B10110000:                                   
           'tutaj to co będzie po kliknięciu S2 
        Case &B11010000: 
           'tutaj to co będzie po kliknięciu S3                              
        Case &B11100000:         
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:         
           'tutaj to co będzie po kliknięciu S1 i S2 razem        
      End Select   
    End if
  Else
     if Licznik_sw>5  and dlugi_klawisz = 0 Then  
    'krotkie klikniecia jak trzymanie klawisza przynajmniej przez 5 cykli procedury i wczesniej nie bylo trzymanego klawisza
       Select Case Stan_sw
        Case &B01110000:                                   
             'tutaj to co będzie po krotkim kliknięciu S1 
        Case &B10110000:                                   
           'tutaj to co będzie po kliknięciu S2 
        Case &B11010000: 
           'tutaj to co będzie po kliknięciu S3                              
        Case &B11100000:         
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:         
           'tutaj to co będzie po kliknięciu S1 i S2 razem        
      End Select
    End If
    reset dlugi_klawisz
    Stan_sw = Sw
    Licznik_sw = 0
  End If
Return

Trzeba to sprawdzić i dopracować

-

UWAGA! Możliwy jest zakup zaprogramowanych uC i zestawów elementów itp. do niektórych projektów. O dostępność proszę pytać via email. Konkretne oferty pojawiają się w cenniku.

Portret użytkownika marekszy

przycisk

witam, podpowie mi ktoś jak napisać obsługę przycisku którym startuję timer1.
Przycisk po wciśnięciu załącza timer1 który zlicza ustawiony czas i czeka na ponowne naciśnięcie.
Problem polega na tym aby po wciśnięciu i trzymaniu procedura wykonała się tylko raz, dopiero puszczenie i ponowne wciśnięcie wystartuje ponownie timer1.Teraz jak wcisnę i nie puszczę timer1 lata w kółko.

Select Case Stan_sw
        Case &B01110000:
           start timer1                        
           'tutaj to co będzie po kliknięciu S1 

Portret użytkownika EDC

Odp. Przycisk

Powinno działać ;)

Dim Blokada As Byte                                         ' <<<<<<<<< zadeklaruj
 
Przyciski:
Sw = PIND And &B11110000             'maskowanie nieużywanych pinów
 
If Sw <> &B11110000 And Stan_sw = Sw Then
    Incr Licznik_sw
    If Licznik_sw = 100 Then
      Licznik_sw = 0
      Select Case Stan_sw
        Case &B01110000:
 
            If Blokada = 0 Then
                Blokada = 1
                  'tutaj to co będzie po kliknięciu S1 TYLKO RAZ
            End If
 
        Case &B10110000:
           'tutaj to co będzie po kliknięciu S2
        Case &B11010000:
           'tutaj to co będzie po kliknięciu S3
        Case &B11100000:
           'tutaj to co będzie po kliknięciu S4
        Case &B00110000:
           'tutaj to co będzie po kliknięciu S1 i S2 razem
      End Select
    End If
  Else
    Stan_sw = Sw
    Licznik_sw = 80
     Blokada = 0                                            ' <<<<<<<<<<< Dodano
  End If
Return

-

BARTek
Moja strona

Portret użytkownika marekszy

przycisk

Kurcze, jakie to było oczywiste, działa super, dzięki wielkie.