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
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 |
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
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.