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!
-
M@ciej
- Użytkownik
- Posty: 736
- Rejestracja: 13 sie 2005, 21:38
- Lokalizacja: Szczecin
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
-
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.
-
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ł.

-
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
-
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.
-
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.