www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik T-Flag testen


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ).
clt             ;T-Flag wird in der Initialisierung gelöscht
        ....
        in r16,SREG     ;r16 mit dem Inhalt von SREG laden 
  sbrc r16,6      ;kontrollieren,ob das 6. Bit gestezt ist (T-Flag)
  jmp ausgabe2    ;falls es nicht gesezt ist diesen Befehl überspringen


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

Gruss
Thomas

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Niemand (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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


;Ansteuerung der beiden 7-Segmente-Anzeigen, sowie der Taster

;Rechner: Auf jeweils einer Anzeige kann eine Zahl hochgezählt werden 
;und anschliessend das Produkt berechnet werden

;Für die Taster werden INT0/INT1 (==PD2/PD3) und für die 7-Segmente-Anzeigen einmal PORTA und 
;einmal PORTB verwendet

  .INCLUDE "m32def.inc"   ;Deklaration für den ATmega32
  .DEF   zaehler1    = r17  ;zählvariable für 1. Anzeige
  .DEF  zaehler2    = r18       ;zählvariable für 2. Anzeige
  .DEF  zehn_ms     = r19       ;für Timer0_interruptroutine
  .DEF  status      = r20            
  .DEF  einer      = r21            
  .DEF  zehner      = r25
  .DEF  preloader   = r23
  .DEF  uelreg      = r24
  .DEF  resultat    = r22
  .DEF  zz      = r26
  .CSEG                        ;Flash-Programm
  rjmp initialisierung
  .ORG INT0addr
  jmp interrupt0
  .ORG INT1addr
  jmp interrupt1
  .ORG OVF0addr
  jmp timer0
;Initialisierung
  
initialisierung:
   ;PORTs definieren
   ldi r16,0xFF
   out DDRB,r16         ;PORTB als Ausgang definieren
   out DDRA,r16         ;PORTA als Ausgang definieren
   ldi r16,0x3F
   out PORTA,r16  ;Am Anfang 0 auf beiden Anzeigen anzeigen
   out PORTB,r16          
   ldi r16,0x0C                
   out PORTD,r16   ;PD2/PD3 (=INT0/INT2) Pull-Up aktivieren --> für Taster
   ldi r16,0x00                
   out DDRD,r16     ;PORTD als Eingang definieren

  
;Variablen
 ldi zaehler1,0x00  ;Zähler auf 0 setzen  
 ldi zaehler2,0x00
 ldi zehn_ms, 0x00   
 ldi status,0x00
 ldi zehner,0x0A               
 ldi einer,0x00
                
;Stack initialisieren
 ldi r16,LOW(RAMEND)
 out SPL,r16
 ldi r16,HIGH(RAMEND)
 out SPH,r16

;Interrupts
 in  r16,MCUCR      ;lade MCUCR-Steuerregister ins Register r16
 sbr r16,1<<ISC00   ;INT0 wird bei steigender Taktflanke ausgelöst
 sbr r16,1<<ISC01
 sbr r16,1<<ISC10   ;INT1 wird bei steigender Taktflanke ausgelöst
 sbr r16,1<<ISC11
 out MCUCR,r16     ;lade MCUCR-Register mit r16
 in  r16,GICR
 sbr r16,1<<INT0
 sbr r16,1<<INT1
 out GICR, r16
  
;Timer  
 ldi preloader,0x70
 out TCNT0,preloader    ;Preloader 111
 in  r16,TCCR0
 cbr r16,1<<FOC0
 cbr r16,1<<WGM00
 cbr r16,1<<COM01
 cbr r16,1<<COM00
 cbr r16,1<<WGM01  ;Disable Force Mode,select Normal Mode no Compare Match ;Output
 sbr r16,1<<CS00
 cbr r16,1<<CS01
 sbr r16,1<<CS02    ;Prescaler 1024
 out TCCR0,r16
 in  r16,TIMSK
 sbr r16,1<<TOIE0
 out TIMSK,r16   ; Timer/Counter0 Overflow Interrupt Enable
 sei          ;Interrupts global freischalten
 clt    ;loescht T-Flag im SREG



hauptschleife:
 in  r16,GICR       ;Interrupts (INT0/INT1) wieder aktivieren
 sbr r16,1<<INT0
 sbr r16,1<<INT1
 out GICR, r16
  
 call ueberlaufkontrolle  

 brts ausgabe1      ;falls das T-Flag gesetzt ist nach "ausgabe1" springen

 cpi status,0x00  ;Statusabfrage
 breq ausgabe1
 cpi status,0x01
 breq ausgabe2
 cpi status,0x02
 breq berechnen

 jmp hauptschleife


berechnen:
 set            ;Setzt T-Flag, um dann in der "hauptschleife" das  ;Ergenis auszugeben
 mul zaehler1,zaehler2
 mov resultat,r0
 jmp ausres1                


warten:    ;für die Entprellung des Tasters --> wartet 90ms  
 cpi zehn_ms,0x09
 breq hauptschleife
 jmp warten   




ausres1:  ;Berrechnet den Wert für die Variable "zaehler1",um die die ;Zehnerstelle auf der 1. 7-Segmente-Anzeige ;auszugeben          
 mov r16,resultat
 sub r16,zehner                
 tst r16  ;auf null testen
 breq einererhoehen
 brne zehnererhoehen

ausres2:
 mov r16,resultat
 add zehner,einer              
 sub r16,zehner 
 mov zaehler2,einer
 tst r16
 breq hauptschleife
 brne einererhoehen

zehnererhoehen:
 ldi r16,0x0A
 add zehner,r16
 inc zz
 jmp ausres1

einererhoehen:
 mov zaehler1,zz              
 inc einer
 jmp ausres2

ausgabe1:
 ldi zaehler2,0x00            
 push r16
 push ZL
 push ZH

 ldi ZL,Low(zahlen<<1)
 ldi ZH,High(zahlen<<1)    ; Adresse Tabelle
 clr r16                   ; Null für Übertrag
 add ZL,zaehler1           ; +Offset
 adc ZH,r16                ; Übertrag berücksichtigen
 lpm r16,Z                 ; Tabellenwert holen
 out PORTA,r16             ; ausgeben

 pop ZH
 pop ZL
 pop r16
  
 brts ausgabe2  

 ldi zehn_ms,0x00      ;Zeitzähler auf 0 setzen
 jmp warten

ausgabe2:
 push r16
 push ZL
 push ZH

 ldi ZL,Low(zahlen<<1)
 ldi ZH,High(zahlen<<1)    ; Adresse Tabelle
 clr r16                   ; Null für Übertrag
 add ZL,zaehler2           ; +Offset
 adc ZH,r16                ; Übertrag berücksichtigen
 lpm r16,Z                 ; Tabellenwert holen
 out PORTB,r16             ; ausgeben
    
 pop ZH
 pop ZL
 pop r16  

 ldi zehn_ms,0x00
 jmp warten


  
ueberlaufkontrolle:
 in  r16,GICR
 cbr r16,1<<INT0
 cbr r16,1<<INT1
 out GICR, r16
  
 ldi r16,0x05
 mov uelreg,status
 cp uelreg,r16
 breq ueberlauf

 ldi r16,0x0A
 mov uelreg,zaehler1
 cp uelreg,r16
 breq ueberlauf

 ldi r16,0x0A
 mov uelreg,zaehler2
 cp uelreg,r16
 breq ueberlauf
   
 ret

ueberlauf:
 ldi uelreg,0x00
 jmp hauptschleife



zahlen:    ;Tabelle mit PORT-Masken für die Zahlen von 0-9
.db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F

  
interrupt0: ;T-Flag (im SREG) setzen um in der "Hauptschleife" in die ;Ausgaberoutine zu kommen  
 inc zaehler1
 inc zaehler2
 reti

interrupt1:  
 inc status  
 reti

timer0:  
 ldi preloader,0x70
 out TCNT0,preloader ;Preloader 111          
 inc zehn_ms       ;pro 10 Millisekunden wird "10ms" um 1 heraufgezählt  
 clc            ;"clear carry" bei einem Überlauf der Variable 10ms  
 reti




Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

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

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Kommando zurück. Habs gefunden.

MfG spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.