KLawiatura 3x3 BASCOM, problem.

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ODPOWIEDZ
Awatar użytkownika
M@ciej
Użytkownik
Posty: 736
Rejestracja: 13 sie 2005, 21:38
Lokalizacja: Szczecin

KLawiatura 3x3 BASCOM, problem.

Post autor: M@ciej » 17 kwie 2010, 10:50

Witam.

Wykonałem układ, który zawiera klawiaturę 3x3 multipleksowaną. Wszystkim steruje Atmega16 spod Bascoma. Jako informację o naciśnięciu klawisza mam prędkość obrotów silnika (9 kroków, PWM, ile jest klawiszy). Napisałem program do obsługi tej klawiatury, ale działa zupełnie przypadkowo. Nie działają niektóre klawisze, inne działają tylko w momencie naciśnięcia,a po puszczeniu jest jakiś inny stan (prędkość obrotowa silniczka), jeszcze inne wydają się działać poprawnie. Męczę się z tym już kilka dni, próbowałem na inne sposoby odczytywać tą klawiaturę i efekty są mniej więcej takie same.

Oto fragment programu:

Kod: Zaznacz cały

$regfile = "m16def.dat"
$crystal = 8000000
$hwstack = 40
$swstack = 40

'########### klawiatura - wejścia ############
 Config Portc.3 = Input
 Set Pinc.3
 Config Portc.4 = Input
 Set Pinc.4
 Config Portc.5 = Input
 Set Pinc.5

 '########### klawiatura - wyjścia ############
 Config Portc.6 = Output
  Set Portc.6
 Config Portc.7 = Output
  Set Portc.7
 Config Porta.7 = Output
  Set Porta.7

 '########### Ustawienie PWM ############
 Ddrd.7 = 1                              'PD.7 jako wyjście
 Tccr2 = &B01100010                     'Pwm = On, Prescale = 64, Clear Up
 Ch3_pwm Alias Ocr2

 Config Timer0 = Timer , Prescale = 8
 On Timer0 Przerwanie
 Enable Interrupts
 Enable Timer0
 Load Timer0 , 250


 '########### Kilka zmiennych ############
 Dim Licznik As Byte
 Dim Klawisz As Byte                     'zmienna kodu klawisza (1-9)
 Dim Temp1 As Byte
 Dim Temp2 As Byte

 Do

 'rem tu inne opcje programu

 Loop
 End

Przerwanie:
Load Timer0 , 250
Incr Licznik

Select Case Licznik

 Case 0:
  Portc.6 = 0 : Portc.7 = 1 : Porta.7 = 1       'wybranie 1 kolumny
  If Pinc.3 = 0 Then Temp1 = 1          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 2          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 3          'sprawdzenie 3 rzędu

 Case 1:
  Portc.6 = 1 : Portc.7 = 0 : Porta.7 = 1       'wybranie 2 kolumny
  If Pinc.3 = 0 Then Temp1 = 4          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 5          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 6          'sprawdzenie 3 rzędu

 Case 2:
  Portc.6 = 1 : Portc.7 = 1 : Porta.7 = 0       'wybranie 3 kolumny
  If Pinc.3 = 0 Then Temp1 = 7          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 8          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 9          'sprawdzenie 3 rzędu

Rem powtórne sprawdzenie po jakimś czasie w celu eliminacji drgań styków
 Case 30:
  Portc.6 = 0 : Portc.7 = 1 : Porta.7 = 1       'wybranie 1 kolumny
  If Pinc.3 = 0 Then Temp2 = 1          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp2 = 2          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp2 = 3          'sprawdzenie 3 rzędu

 Case 31:
  Portc.6 = 1 : Portc.7 = 0 : Porta.7 = 1       'wybranie 2 kolumny
  If Pinc.3 = 0 Then Temp2 = 4          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp2 = 5          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp2 = 6          'sprawdzenie 3 rzędu

 Case 32:
  Portc.6 = 1 : Portc.7 = 1 : Porta.7 = 0       'wybranie 3 kolumny
  If Pinc.3 = 0 Then Temp2 = 7          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp2 = 8          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp2 = 9          'sprawdzenie 3 rzędu

 Case 40:
  If Temp1 = Temp2 Then
   Klawisz = Temp1                      'Klawisz nadal naciśnięty
   Ch3_pwm = Klawisz * 27
   Portc.6 = 1 : Portc.7 = 1 : Porta.7 = 1       'zerowanie wyboru kolumn
  End If
  Licznik = 0                           'zerowanie licznika, cykl od początku


End Select

Return

Awatar użytkownika
Ertew
Użytkownik
Posty: 1414
Rejestracja: 03 lip 2005, 10:36
Lokalizacja: Leszno
Kontakt:

Post autor: Ertew » 17 kwie 2010, 11:12

Może tak:

Kod: Zaznacz cały

 Case 1:
  Portc.6 = 0 : Portc.7 = 1 : Porta.7 = 1       'wybranie 1 kolumny

 Case 2:
  If Pinc.3 = 0 Then Temp1 = 1          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 2          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 3          'sprawdzenie 3 rzędu

 Case 3:
  Portc.6 = 1 : Portc.7 = 0 : Porta.7 = 1       'wybranie 2 kolumny

 Case 4:
  If Pinc.3 = 0 Then Temp1 = 4          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 5          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 6          'sprawdzenie 3 rzędu

 Case 5:
  Portc.6 = 1 : Portc.7 = 1 : Porta.7 = 0       'wybranie 3 kolumny

 Case 6:
  If Pinc.3 = 0 Then Temp1 = 7          'sprawdzenie 1 rzędu
  If Pinc.4 = 0 Then Temp1 = 8          'sprawdzenie 2 rzędu
  If Pinc.5 = 0 Then Temp1 = 9          'sprawdzenie 3 rzędu 
Układy wejściowe portów potrzebują chwilki na wykrycie zmiany stanu.

[ Dodano: 2010-04-17, 12:17 ]
Nie jestem pewien tego fragmentu:

Kod: Zaznacz cały

'########### klawiatura - wejścia ############
 Config Portc.3 = Input
 Set Pinc.3
 Config Portc.4 = Input
 Set Pinc.4
 Config Portc.5 = Input
 Set Pinc.5
Dawno nie siedziałem w basconie, ale wyjście podciągane do + włączało się chyba inaczej.

Awatar użytkownika
M@ciej
Użytkownik
Posty: 736
Rejestracja: 13 sie 2005, 21:38
Lokalizacja: Szczecin

Post autor: M@ciej » 17 kwie 2010, 13:40

Co do drugiego fragmentu kodu. Wiersze sterowane są przez wejścia podciągnięte do zasilania, tak jak jest to tam napisane. Aktywując dana kolumnę wystawiamy na niej "0". Wtedy po naciśnięciu jakiegoś klawisza, wejścia zostaną zwarte "do masy", a konkretnie do stanu niskiego i wejścia powinny to już złapać.
Wcześniej zrobiłem tak, że na kolumnach (PC.6, PC.7 i PA.7) wystawiałem stan wysoki i próbowałem go odczytać na wejściach (PC.3, PC.4, PC.5) nie podciągniętych - wyszło podobnie.
Dodałem do każdego przycisku równolegle kondensator 100nF, ale tylko częściowo pomogło.

keruseykaryu

Post autor: keruseykaryu » 17 kwie 2010, 17:56

O Config Kbd słyszeli?
Set Pinc.3? Coś się koledze Port z Pin pomieszał. :grin:

Awatar użytkownika
M@ciej
Użytkownik
Posty: 736
Rejestracja: 13 sie 2005, 21:38
Lokalizacja: Szczecin

Post autor: M@ciej » 18 kwie 2010, 7:55

Wszystko fajnie z tym KBD, jeśli się ma klawiaturę podłączoną jak w HELPIE, niestety ja mam inaczej (wymogi płytki). Co do instrukcji PIN/PORT rzeczywiście jest błąd, ale to akurat chodziło.

Żeby zobaczyć co w układzie piszczy, odpiąłem wiele peryferiów i podłączyłem wyświetlacz. Dzięki temu udało się okiełznać tą klawiaturę. Na razie działa w pętli głównej, ale myślę że po wrzuceniu tego w przerwania też będzie śmigać. Program wygląda tak:

Kod: Zaznacz cały

$regfile = "m16def.dat"
$crystal = 8000000

Config Portc.3 = Input
Set Portc.3
Config Portc.4 = Input
Set Portc.4
Config Portc.5 = Input
Set Portc.5

Config Portc.6 = Output
Set Portc.6
Config Portc.7 = Output
Set Portc.7
Config Porta.7 = Output
Set Porta.7

Dim I As Byte
Dim Klawisz As Byte

Dim Silnik1 As Bit
Dim Silnik2 As Bit
Dim Silnik3 As Bit

Dim Zw1 As Bit
Dim Zw2 As Bit
Dim Zw3 As Bit


Config Lcd = 20 * 4
Config Lcdpin = Pin , Db4 = Portb.1 , Db5 = Portb.2 , Db6 = Portb.3 , Db7 = Portb.4 , E = Portb.0 , Rs = Porta.0

Cls
Locate 1 , 1 : Lcd "Dziala LCD!"

Do
 Incr I

 If I = 1 Then
  Portc.6 = 0 : Portc.7 = 1 : Porta.7 = 1       'Ustawienie kolumny 1
  If Pinc.3 = 0 Then Klawisz = 1        'Sprawdzenie wiersza 1
  If Pinc.4 = 0 Then Klawisz = 2        'Sprawdzenie wiersza 2
  If Pinc.5 = 0 Then Klawisz = 3        'Sprawdzenie wiersza 3
 End If

 If I = 2 Then
  Portc.6 = 1 : Portc.7 = 0 : Porta.7 = 1       'Ustawienie kolumny 3
  If Pinc.3 = 0 Then Klawisz = 7        'Sprawdzenie wiersza 1
  If Pinc.4 = 0 Then Klawisz = 8        'Sprawdzenie wiersza 2
  If Pinc.5 = 0 Then Klawisz = 9        'Sprawdzenie wiersza 3
 End If

 If I = 3 Then
  Portc.6 = 1 : Portc.7 = 1 : Porta.7 = 0       'Ustawienie kolumny 2
  If Pinc.3 = 0 Then Klawisz = 4        'Sprawdzenie wiersza 1
  If Pinc.4 = 0 Then Klawisz = 5        'Sprawdzenie wiersza 2
  If Pinc.5 = 0 Then Klawisz = 6        'Sprawdzenie wiersza 3
 End If

 If I = 4 Then                          'sprawdzenie stanu klawiszy i odp. przypisania
  Locate 2 , 1 : Lcd "Klawisz=" ; Klawisz
  Klawisz = 0
 End If

 If I = 5 Then I = 0

 Waitms 20
Loop
End

Awatar użytkownika
kayron
Użytkownik
Posty: 2088
Rejestracja: 21 wrz 2008, 12:53
Lokalizacja: Poland
Kontakt:

Post autor: kayron » 19 kwie 2010, 10:47

Skomplikowana ta obsługa.? Nie prościej odczytywać cały port i maskować zbędne bity za pomocą AND.
A - szybsze
B - prostsze
C - kod wynikowy mniejszy
D - pozwala wykrywać kombinacje klawiszy.

Awatar użytkownika
M@ciej
Użytkownik
Posty: 736
Rejestracja: 13 sie 2005, 21:38
Lokalizacja: Szczecin

Post autor: M@ciej » 19 kwie 2010, 15:27

Na pewno byłoby łatwiej, ale ja już mam wykonaną płytkę pod nową klawiaturę. Ponieważ do klawiatury podprowadzony jest port (porta.7), czyli także wejście ADC, zrobiłem drabinkę rezystorów i info o tym, który klawisz jest naciśnięty, będę zbierał w postaci analogowej. Pozostałe piny posłużą do sterowania podświetleniem klawiszy (sterownik diod LED MBI5026GD) i powinno obyć się tym razem bez kłopotu.

ODPOWIEDZ