Mikrocontroller und Digitale Elektronik
›
Thread
Problem beim Entprellen/Timer0
T
Thomas
Gast
08.05.2009 18:31
#1256120
Hallo,
Mein Assemblercode, der eine 7-Semgente-Anzeige pro Tastendruck um 1
erhöht funktioniert soweit gut.
Als ich dann den Timer0 einbaute, um den Taster zu entprellen,
funktionierte gar nichts mehr.
Hat jemand eine Idee woran das liegen kann?
Code ist im Anhang
Gruss
S
spess53
Gast
08.05.2009 18:37
#1256121
Hi
>Code ist im Anhang
Aber gut versteckt.
MfG Spess
T
Thomas
Gast
08.05.2009 18:41
#1256126
Sorry das mit dem Anhang hat nicht geklappt.
Hier der Code
1 ;Ansteuern der Segmente und des Tasters
2 ;PB0-PB7 sind für die Segmente (Ausgang) und PD2 ist für den Taster (Eingang) bestimmt.
3
4 .INCLUDE "m32def.inc" ;Deklaration für ATmega32
5 .DEF status = r16 ;Variable, die überprüft, ob die Initialisierung schon einmal durchgeführt wurde
6 .DEF zaehler = r17 ;Zählregister
7 .DEF vergl_reg = r18 ;Register für den Vergleich
8 .DEF universal_reg = r19 ;Register für Init.,Masken,...
9 .DEF ms_zaehler = r20 ;Zählt die Zeit für die Entprellung des Tasters
10 .DEF status_timer0 = r21 ;wenn timer0 Zeit gezählt hat,nächster überspringen
11 .DEF wartezeit = r22 ;Zeit zum Entprellen des Tasters
12 .ORG 0x000
13 rjmp initialisierung ;Nach Reset muss Initialisierung durchgeführt werden
14 .ORG INT0addr
15 rjmp interrupt0
16 .ORG OVF0addr
17 rjmp timer0_interrup
18
19 ;Interrupt initialisieren
20 initialisierung:
21 ldi wartezeit,0x04 ;Wartezeit = 1 sek.
22 ldi zaehler,0x00 ;Zähler auf 0 setzten
23 ldi universal_reg,0x3F ;0 Anzeigen
24 out PORTA,universal_reg
25 ldi universal_reg,LOW(RAMEND) ;Stapel anlegen
26 out SPL,universal_reg
27 ldi universal_reg,HIGH(RAMEND)
28 out SPH,universal_reg
29 in universal_reg,MCUCR ;altes Steuerregister
30 cbr universal_reg,1 << ISC00 ;lösche Bit bei ISC00
31 sbr universal_reg,1 << ISC01 ;sezte Bit bei ISC01
32 out MCUCR,universal_reg ;Bei einer fallenden Flanke wird im INT0 ein Interrupt ausgelöst
33 in universal_reg,GICR ;altes Freigaberegister
34 sbr universal_reg,1 << INT0 ;setze Bit bei INT0
35 out GICR,universal_reg ;Interrupt feigegeben
36 sei ;alle Interrupts global frei
37
38 ;allg. Initialisierung
39
40
41
42 ldi zaehler,0x00 ;Zähler für Vergleich, Anfangswert 0
43
44 ldi wartezeit,0xFF
45
46 ldi universal_reg,0xFF
47 out DDRA,universal_reg ;Port A als Ausgang
48
49 ldi universal_reg,0x00
50 out DDRD,universal_reg ;Port D als Eingang
51
52 ldi universal_reg,0x04
53 out PORTD,universal_reg ;INT0/PD2 Pull-up aktiviert
54
55 ldi universal_reg,0x01
56 out TIMSK,universal_reg ;Timer/Counter0 Overflow Interrupt Enable
57
58 ldi universal_reg,0x05
59 out TCCR0,universal_reg ;Disable Force Mode, select Normal Mode, no Compare Match Output
60 ;Select Prescaler 1024 (CS02..00 = 101)
61 ldi universal_reg,0x70
62 out TCNT0,universal_reg ;Preloader = 111, jetzt startet der timer0
63 ;"main"
64
65 main:
66 jmp main ;Endlosscheife
67
68 timer0_interrup:
69 push universal_reg
70 in universal_reg,SREG
71 push universal_reg
72
73 inc ms_zaehler
74
75 pop universal_reg
76 out SREG,universal_reg
77 pop universal_reg
78
79 reti
80
81
82 warten:
83 push universal_reg
84 in universal_reg,SREG
85 push universal_reg
86
87 cpse wartezeit,ms_zaehler
88 jmp warten
89
90
91 pop universal_reg
92 out SREG,universal_reg
93 pop universal_reg
94
95
96 ret
97
98
99 ;"interrupt0"
100
101 interrupt0:
102 ldi ms_zaehler,0x00 ;ms_zähler auf 0 sezten
103 call warten
104
105 ;->varible hochzählen
106 ;Zeitschritte zählen
107 inc zaehler ;Zähler: Register r17 + 1
108
109 ldi vergl_reg,0x0A ;wenn Zähler 10 -> overflow -> Zähler wieder auf 0 setzen
110 cp zaehler,vergl_reg
111 breq overflow
112
113 ;->Vergleich
114
115 ldi vergl_reg,0x00 ;lade Zahlenwert in Register
116 cp zaehler,vergl_reg ;Registervergleich wenn gleich (r17 - Zahl) Z=1
117 breq set0 ;wenn Z=1 Sprung nach "set_"
118
119 ldi vergl_reg,0x01
120 cp zaehler,vergl_reg
121 breq set1
122
123 ldi vergl_reg,0x02
124 cp zaehler,vergl_reg
125 breq set2
126
127 ldi vergl_reg,0x03
128 cp zaehler,vergl_reg
129 breq set3
130
131 ldi vergl_reg,0x04
132 cp zaehler,vergl_reg
133 breq set4
134
135 ldi vergl_reg,0x05
136 cp zaehler,vergl_reg
137 breq set5
138
139 ldi vergl_reg,0x06
140 cp zaehler,vergl_reg
141 breq set6
142
143 ldi vergl_reg,0x07
144 cp zaehler,vergl_reg
145 breq set7
146
147 ldi vergl_reg,0x08
148 cp zaehler,vergl_reg
149 breq set8
150
151 ldi vergl_reg,0x09
152 cp zaehler,vergl_reg
153 breq set9
154
155 ;->Sprung nach "main"
156 reti
157
158 ;Wenn Zähler =10 -> auf -1 setzten
159 overflow: ldi zaehler,-0x01
160 jmp interrupt0
161
162 ;"set_"
163 ;->Maske für PORTA ausgeben
164 ;->Sprung nach "interrupt0"
165 set0:
166 ldi universal_reg,0x3F
167 out PORTA,universal_reg
168 reti
169
170 set1:
171 ldi universal_reg,0x06
172 out PORTA,universal_reg
173 reti
174
175
176 set2:
177 ldi universal_reg,0x6D
178 out PORTA,universal_reg
179 reti
180
181
182 set3:
183 ldi universal_reg,0x4F
184 out PORTA,universal_reg
185 reti
186
187
188 set4:
189 ldi universal_reg,0x56
190 out PORTA,universal_reg
191 reti
192
193
194 set5:
195 ldi universal_reg,0x5B
196 out PORTA,universal_reg
197 reti
198
199
200 set6:
201 ldi universal_reg,0x7B
202 out PORTA,universal_reg
203 reti
204
205
206 set7:
207 ldi universal_reg,0x0E
208 out PORTA,universal_reg
209 reti
210
211
212 set8:
213 ldi universal_reg,0x7F
214 out PORTA,universal_reg
215 reti
216
217 set9:
218 ldi universal_reg,0x5F
219 out PORTA,universal_reg
220 reti
S
spess53
Gast
08.05.2009 19:30
#1256152
Hi
> warten:
> push universal_reg
> in universal_reg,SREG
> push universal_reg>
> cpse wartezeit,ms_zaehler
> jmp warten
Nette Methode den Stack vollzubekommen.
> overflow: ldi zaehler,-0x01
> jmp interrupt0
Ähnlicher Unsinn.
Zu deinen Programm kann ich dir nur raten: Gründlich überdenken und neu
anfangen.
Nur ein paar Tips:
- Interruptroutinen so lang wie nötig und so kurz wie möglich.
- Warteschleifen haben in ISRs nichts zu suche.
- in den Interrupts Flags setzen, die in 'main' abgefragt werden und
dann
in Abhängigkeit die entsprechenden Routinen abarbeiten.
....
MfG Spess
S
spess53
Gast
08.05.2009 20:00
#1256169
Hi
Im Anhang mal ein kleines Beispiel zur Gestaltung deiner Ausgaberoutine.
Ersetzt alles zwischen:
> ;->Vergleich
> ldi vergl_reg,0x00 ;lade Zahlenwert in Register
und
> set9:
> ldi universal_reg,0x5F
> out PORTA,universal_reg
> reti
Allerdings als Unterprogramm und nicht als ISR.
MfG Spess
T
Thomas
Gast
08.05.2009 20:56
#1256242
hallo spess53
danke!
Gruss
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
Noch kein Account?
Die Registrierung ist kostenlos und dauert nur eine Minute.
Jetzt registrieren