Forum: Mikrocontroller und Digitale Elektronik T-Flag testen


von Thomas (Gast)


Lesenswert?

Hallo,
ich programmiere meinen ATmega32 gerade in Assembler. Nun weiss ich aber 
nicht genau, wie ich das von mir gesezte T-Flag abfragen kann. (So wie 
ich das versucht habe hat es nicht geklaptt - "jmp ausgabe2" wurde immer 
ausgeführt ).
1
clt             ;T-Flag wird in der Initialisierung gelöscht
2
        ....
3
        in r16,SREG     ;r16 mit dem Inhalt von SREG laden 
4
  sbrc r16,6      ;kontrollieren,ob das 6. Bit gestezt ist (T-Flag)
5
  jmp ausgabe2    ;falls es nicht gesezt ist diesen Befehl überspringen

Hat jemand eine Idee woran das liegen kann? Verbesserungsvorschläge?

Gruss
Thomas

von spess53 (Gast)


Lesenswert?

Hi

Es gibt auch bedingte Sprünge für das T-Flag -> brts/brtc.

>Hat jemand eine Idee woran das liegen kann?

Nein. In dem Codebrösel kann ich keinen Fehler entdecken.

MfG Spess

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Es gibt die Befehle 'brts' und 'brtc', die springen, wenn das T-Flag 
gesetzt bzw. gelöscht ist. Dein Code müßte auch funktionieren, 
wahrscheinlich ist das T-flag einfach immer gesetzt. Man müßte mal den 
Rest vom Code sehen.

von Niemand (Gast)


Lesenswert?

>sbrc r16,6      ;kontrollieren,ob das 6. Bit gestezt ist (T-Flag)

Was genau soll hier passieren?
Was meinst Du mit "kontrollieren"? Es ist schon klar was Du abstrakt 
"meinst", aber hier könnte zusätzlich stehen, was "konkret" passieren 
soll.
Die sbxx-Befehle beeinflussen den Programmcounter.
Was soll mit dem PC unter welchen Bedingungen geschehen?

von Thomas (Gast)


Angehängte Dateien:

Lesenswert?

Hier noch der ganze Code.
Funktionsweise: 1. beide 7-Segmente-Anzeigen können einzeln erhöht 
werden
                2. beide Zähler werden multipliziert
                3. Berechnung was auf jeder 7-Segmente-Anzeige angezeigt
                  werden soll
1
;Ansteuerung der beiden 7-Segmente-Anzeigen, sowie der Taster
2
3
;Rechner: Auf jeweils einer Anzeige kann eine Zahl hochgezählt werden 
4
;und anschliessend das Produkt berechnet werden
5
6
;Für die Taster werden INT0/INT1 (==PD2/PD3) und für die 7-Segmente-Anzeigen einmal PORTA und 
7
;einmal PORTB verwendet
8
9
  .INCLUDE "m32def.inc"   ;Deklaration für den ATmega32
10
  .DEF   zaehler1    = r17  ;zählvariable für 1. Anzeige
11
  .DEF  zaehler2    = r18       ;zählvariable für 2. Anzeige
12
  .DEF  zehn_ms     = r19       ;für Timer0_interruptroutine
13
  .DEF  status      = r20            
14
  .DEF  einer      = r21            
15
  .DEF  zehner      = r25
16
  .DEF  preloader   = r23
17
  .DEF  uelreg      = r24
18
  .DEF  resultat    = r22
19
  .DEF  zz      = r26
20
  .CSEG                        ;Flash-Programm
21
  rjmp initialisierung
22
  .ORG INT0addr
23
  jmp interrupt0
24
  .ORG INT1addr
25
  jmp interrupt1
26
  .ORG OVF0addr
27
  jmp timer0
28
;Initialisierung
29
  
30
initialisierung:
31
   ;PORTs definieren
32
   ldi r16,0xFF
33
   out DDRB,r16         ;PORTB als Ausgang definieren
34
   out DDRA,r16         ;PORTA als Ausgang definieren
35
   ldi r16,0x3F
36
   out PORTA,r16  ;Am Anfang 0 auf beiden Anzeigen anzeigen
37
   out PORTB,r16          
38
   ldi r16,0x0C                
39
   out PORTD,r16   ;PD2/PD3 (=INT0/INT2) Pull-Up aktivieren --> für Taster
40
   ldi r16,0x00                
41
   out DDRD,r16     ;PORTD als Eingang definieren
42
43
  
44
;Variablen
45
 ldi zaehler1,0x00  ;Zähler auf 0 setzen  
46
 ldi zaehler2,0x00
47
 ldi zehn_ms, 0x00   
48
 ldi status,0x00
49
 ldi zehner,0x0A               
50
 ldi einer,0x00
51
                
52
;Stack initialisieren
53
 ldi r16,LOW(RAMEND)
54
 out SPL,r16
55
 ldi r16,HIGH(RAMEND)
56
 out SPH,r16
57
58
;Interrupts
59
 in  r16,MCUCR      ;lade MCUCR-Steuerregister ins Register r16
60
 sbr r16,1<<ISC00   ;INT0 wird bei steigender Taktflanke ausgelöst
61
 sbr r16,1<<ISC01
62
 sbr r16,1<<ISC10   ;INT1 wird bei steigender Taktflanke ausgelöst
63
 sbr r16,1<<ISC11
64
 out MCUCR,r16     ;lade MCUCR-Register mit r16
65
 in  r16,GICR
66
 sbr r16,1<<INT0
67
 sbr r16,1<<INT1
68
 out GICR, r16
69
  
70
;Timer  
71
 ldi preloader,0x70
72
 out TCNT0,preloader    ;Preloader 111
73
 in  r16,TCCR0
74
 cbr r16,1<<FOC0
75
 cbr r16,1<<WGM00
76
 cbr r16,1<<COM01
77
 cbr r16,1<<COM00
78
 cbr r16,1<<WGM01  ;Disable Force Mode,select Normal Mode no Compare Match ;Output
79
 sbr r16,1<<CS00
80
 cbr r16,1<<CS01
81
 sbr r16,1<<CS02    ;Prescaler 1024
82
 out TCCR0,r16
83
 in  r16,TIMSK
84
 sbr r16,1<<TOIE0
85
 out TIMSK,r16   ; Timer/Counter0 Overflow Interrupt Enable
86
 sei          ;Interrupts global freischalten
87
 clt    ;loescht T-Flag im SREG
88
89
90
91
hauptschleife:
92
 in  r16,GICR       ;Interrupts (INT0/INT1) wieder aktivieren
93
 sbr r16,1<<INT0
94
 sbr r16,1<<INT1
95
 out GICR, r16
96
  
97
 call ueberlaufkontrolle  
98
99
 brts ausgabe1      ;falls das T-Flag gesetzt ist nach "ausgabe1" springen
100
101
 cpi status,0x00  ;Statusabfrage
102
 breq ausgabe1
103
 cpi status,0x01
104
 breq ausgabe2
105
 cpi status,0x02
106
 breq berechnen
107
108
 jmp hauptschleife
109
110
111
berechnen:
112
 set            ;Setzt T-Flag, um dann in der "hauptschleife" das  ;Ergenis auszugeben
113
 mul zaehler1,zaehler2
114
 mov resultat,r0
115
 jmp ausres1                
116
117
118
warten:    ;für die Entprellung des Tasters --> wartet 90ms  
119
 cpi zehn_ms,0x09
120
 breq hauptschleife
121
 jmp warten   
122
123
124
125
126
ausres1:  ;Berrechnet den Wert für die Variable "zaehler1",um die die ;Zehnerstelle auf der 1. 7-Segmente-Anzeige ;auszugeben          
127
 mov r16,resultat
128
 sub r16,zehner                
129
 tst r16  ;auf null testen
130
 breq einererhoehen
131
 brne zehnererhoehen
132
133
ausres2:
134
 mov r16,resultat
135
 add zehner,einer              
136
 sub r16,zehner 
137
 mov zaehler2,einer
138
 tst r16
139
 breq hauptschleife
140
 brne einererhoehen
141
142
zehnererhoehen:
143
 ldi r16,0x0A
144
 add zehner,r16
145
 inc zz
146
 jmp ausres1
147
148
einererhoehen:
149
 mov zaehler1,zz              
150
 inc einer
151
 jmp ausres2
152
153
ausgabe1:
154
 ldi zaehler2,0x00            
155
 push r16
156
 push ZL
157
 push ZH
158
159
 ldi ZL,Low(zahlen<<1)
160
 ldi ZH,High(zahlen<<1)    ; Adresse Tabelle
161
 clr r16                   ; Null für Übertrag
162
 add ZL,zaehler1           ; +Offset
163
 adc ZH,r16                ; Übertrag berücksichtigen
164
 lpm r16,Z                 ; Tabellenwert holen
165
 out PORTA,r16             ; ausgeben
166
167
 pop ZH
168
 pop ZL
169
 pop r16
170
  
171
 brts ausgabe2  
172
173
 ldi zehn_ms,0x00      ;Zeitzähler auf 0 setzen
174
 jmp warten
175
176
ausgabe2:
177
 push r16
178
 push ZL
179
 push ZH
180
181
 ldi ZL,Low(zahlen<<1)
182
 ldi ZH,High(zahlen<<1)    ; Adresse Tabelle
183
 clr r16                   ; Null für Übertrag
184
 add ZL,zaehler2           ; +Offset
185
 adc ZH,r16                ; Übertrag berücksichtigen
186
 lpm r16,Z                 ; Tabellenwert holen
187
 out PORTB,r16             ; ausgeben
188
    
189
 pop ZH
190
 pop ZL
191
 pop r16  
192
193
 ldi zehn_ms,0x00
194
 jmp warten
195
196
197
  
198
ueberlaufkontrolle:
199
 in  r16,GICR
200
 cbr r16,1<<INT0
201
 cbr r16,1<<INT1
202
 out GICR, r16
203
  
204
 ldi r16,0x05
205
 mov uelreg,status
206
 cp uelreg,r16
207
 breq ueberlauf
208
209
 ldi r16,0x0A
210
 mov uelreg,zaehler1
211
 cp uelreg,r16
212
 breq ueberlauf
213
214
 ldi r16,0x0A
215
 mov uelreg,zaehler2
216
 cp uelreg,r16
217
 breq ueberlauf
218
   
219
 ret
220
221
ueberlauf:
222
 ldi uelreg,0x00
223
 jmp hauptschleife
224
225
226
227
zahlen:    ;Tabelle mit PORT-Masken für die Zahlen von 0-9
228
.db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F
229
230
  
231
interrupt0: ;T-Flag (im SREG) setzen um in der "Hauptschleife" in die ;Ausgaberoutine zu kommen  
232
 inc zaehler1
233
 inc zaehler2
234
 reti
235
236
interrupt1:  
237
 inc status  
238
 reti
239
240
timer0:  
241
 ldi preloader,0x70
242
 out TCNT0,preloader ;Preloader 111          
243
 inc zehn_ms       ;pro 10 Millisekunden wird "10ms" um 1 heraufgezählt  
244
 clc            ;"clear carry" bei einem Überlauf der Variable 10ms  
245
 reti

von spess53 (Gast)


Lesenswert?

Hi

Habe ich jetzt etwas übersehen? Aber ich finde keine Stelle, wo T wieder 
zurückgesetzt wird.

MfG Spess

von spess53 (Gast)


Lesenswert?

Hi

Kommando zurück. Habs gefunden.

MfG spess

von spess53 (Gast)


Lesenswert?

Hi

War aber nur eins am Anfang. Innerhalb des Programms wird T nur gesetzt, 
Aber nicht wieder gelöscht.
Schwerwiegender:

Stack ist falsch initialisiert: Erst High-Byte dann Low-Byte


ueberlaufkontrolle:
 in  r16,GICR
 cbr r16,1<<INT0
 cbr r16,1<<INT1
 ....
 cp uelreg,r16
 breq ueberlauf   !!!!!!!!!!!!!!
 ret

ueberlauf:
 ldi uelreg,0x00
 jmp hauptschleife  !!!!!!!!!!!!

Das geht nicht. Du kannst aus einem Unterprogramm nicht nicht wieder so 
ins Programm springen.

MfG Spess

von Michael U. (amiga)


Lesenswert?

Hallo,

spess53 schrieb:
> Stack ist falsch initialisiert: Erst High-Byte dann Low-Byte

Ist beim Stackpointer egal, der wird intern nicht gelatcht.

Gruß aus berlin
Michael

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
Noch kein Account? Hier anmelden.