Tagchen Leute,
im Folgenden ist erstmal mein Quelltext zu sehen:
;-----------------------------------------------------------------------
------------
;-Programmheader--------------------------------------------------------
------------
;-----------------------------------------------------------------------
------------
;Projekt : Binaerzaehler
; (Taster1/PIN D2(oben) zaehlt hoch)
; (Taster2/PIN D3(unten) zaehlt runter)
;Prozessor : AT90S8535
;Takt : 8MHz
;
;Stand :
;Fehler :
;Hardware :
;
;-----------------------------------------------------------------------
------------
;-Deklarationen---------------------------------------------------------
------------
;-----------------------------------------------------------------------
------------
.include "8535def.inc" ; Prozessor ATmega8 einbinden
.def vara = r16 ; Variable vara
.def varb = r17 ; Variable varb
.cseg ; Start eines Code Segments
rjmp RESET
RESET:
ldi vara, 0x00 ; Register 16 als 0 laden
out PORTA, vara ; Port-Register A setzen
ldi vara, 0xFF ; Register 16 als 255 laden
out DDRA, vara ; DDRA setzen (PIN 0 bis 7 Ausgaenge)
ldi vara, 0x00 ; Register 16 als 0 laden
out PORTB, vara ; Port-Register B setzen
ldi vara, 0x00 ; Register 16 als 0 laden
out DDRB, vara ; DDRB setzen (PIN 0 bis 7 Ausgaenge)
ldi vara, 0x00 ; Register 16 als 0 laden
out PORTC, vara ; Port-Register C setzen
ldi vara, 0x00 ; Register 16 als 0 laden
out DDRC, vara ; DDRC setzen (PIN 0 bis 7 Eingaenge)
ldi vara, 0x00 ; Register 16 als 0 laden
out PORTD, vara ; Port-Register D setzen
ldi vara, 0x00 ; Register 16 als 0 laden
out DDRD, vara ; DDRD setzen (PIN 0 bis 7 Ausgaenge)
nop
START:
in varb,PORTD ; Port D wird ins Register 17 geladen
sbic PIND, 2 ; wenn an PIN D2 0 steht, dann soll der naechste
Schritt uebersprungen werden
rjmp TASTER1 ; wird uebersprungen, wenn PIN D2 auf 0 steht
sbic PIND, 3 ; wenn an PIN D3 0 steht, dann soll der naechste
Schritt uebersprungen werden
rjmp TASTER2 ; wird uebersprungen, wenn PIN D3 auf 0 steht
rjmp START ; wird aktiviert, wenn an PIN D3 0 steht
TASTER1: ; hochzaehlen an PIN D2
inc vara ; Register 16 mit 1 addieren
out PORTA, vara ; das Register 16 wird auf Port A ausgegeben
rjmp START ; wenn Register 16 mit 1 addiert wurde, zurueck zu
START springen
TASTER2: ; runterzaehlen an PIN D3
dec vara ; Register 16 mit 1 subtrahieren
out PORTA, vara ; das Register 16 wird auf Port A ausgegeben
rjmp START ; wenn Register 16 mit 1 subtrahiert wurde, zurueck
zu START
Nun ist meine Frage, wie ich meine Taster entprelle, da diese nicht
+/-1, sondern beliebig viel zählen?
Bitte, bitte helft mir mal. :)
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tastenhttp://www.mikrocontroller.net/articles/Entprellung
Das Problem hier ist aber weniger das Prellen, als das Verhältnis
Mensch/Rechengeschwindigkeit.
Dein Programm benötigt max 1,5µs und ändert die Variablen in dem Tempo,
wenn eine Taste gedrückt ist. Mensch hat Reaktionszeit >>100ms, wird
also immer viele tausend Zählschritte aufrufen. Wenn du dich mit Timern
noch nicht auskennst, bau zumindest eine Warteschleife über 400.000
Takte ein.
Mark
Hi
Na, dann sagt doch mal einer, das hier eine Flankenauswertung hilft.
Übrigends, Kommentarzeilen für Vara und Varb machen keinen Sinn. Erstens
erklärt sich der Name fast von selbst und zweitens sind's keine
Variablen, sondern Register, die du nur umbenennst.
Ok, genug gemeckert, jetzt helf ich mal....
Also, angenommen, deine Taster sind entprellt. Und möchtest du die
Tasterbetätigung zählen, dazu brauchst du eine Flankenauswertung. Zuerst
merkst du dir den alten Zustand. Dann liest du den neuen Zustand der
eingaänge und machst eine Exclusiv-Oder Veerknüpfung. Das Ergebnis sind
die geänderten Bits mit der Lage "1". iNun machst du eine Und-Verküpfung
mit dem Alten Zusatand. Das Ergebnis ist nur bei einer Änderung von 1
nach 0 eine "1"
Also hast du die fallende Flanke. Arbeiten deine Taster gegen "0", dann
bedeutet dies, der Taster wurde gedrückt.
Danach schreibst du neu nach alt.
Damit du nur 1x zählst, mußt du dieses Bit benutzen, eine Zählroutine
aufzurufen, die Zählung durchführen und dieses Bit löschen. Damit dieses
Bit wieder gesetzt werden kann, muß der Taster erneut gedrückt werden.
Willst du die andere Bitlage haben, also den Wechsel von 0 nach 1, muß
die Und-Verküpfung mit dem Ergebnis aus der Exclsiv-Oder mit dem neuen
gelesenen Wert durchgeführt werden.
Hier mal ein Assemblercode eines Atmega8
1
LDI New_In, 0 ; New_In ist ein Register
2
LDI Old_In, 0 ; Old_In ist ein Register
3
; Dies war die Initialisierung vor der Programmschleife
4
Loop:
5
In New_In, Port_B
6
Mov Temp, New_In ; Eingamg merken, Temp ist Register
7
EOR Temp, Old_In ; geänderte Bits in Temp
8
Push Temp ; Ergebnis Exclusiv-Oder auf Stack merken
9
AND Temp, New_In ; 1 in Temp ist Flanke von 0 nach 1
10
Or Flag_To High, Temp ; die 1 in ein Flag-Register übertragen
11
POP Temp ; Eor zurückholen
12
And Temp, Old_In ; 1 in Temp ist Wechsel von 1 nach 0
13
Or Flag_To_Low, Temp ; die 1 in ein Flagregister übertragen
14
Mov Old_In, New_In ; Register auf neuen Stand gleichziehen
15
.....
16
Cpi Flag_To_High, 0
17
BREQ Chk_Low
18
RCALL Event_High
19
Chk_Low:
20
Cpi Flag_to_High,0
21
BREQ weiter
22
RCall Event_Low
23
Weiter:
24
....
25
RJmp Loop
26
27
28
Event_High:
29
.... ; hier steht deine Bearbeitung
30
Ldi Flag_To_High , 0 ; Flags zurücksetzen
31
ret
32
33
Event_Low:
34
.... ; hier steht deine Bearbeitung
35
Ldi Flag_To_Low , 0 ; Flags zurücksetzen
36
ret
Das ist mal eben so dahergeschmiert, hoffe es hilft.
Gruß oldmax