Forum: Mikrocontroller und Digitale Elektronik SREG untersuchung in C


von micha (Gast)


Lesenswert?

Hey alle,

ich experimentiere gerade mit dem SREG-Register rum.
Mein Ziel ist es die einzelnen Bits auszulesen und daraufhin eine LED 
leuchten lassen.
1
#include <avr/io.h>
2
3
int main (void) {           
4
5
  DDRC = ( 1 << PC5 );        // PC5 an PORTC als Ausgang setzen
6
  PORTC ^= ( 1 << PC5 );      // LED erstmal ausschalten
7
  
8
  uint8_t Ergebnis = 0x00 + 0x00;  // Rechnen
9
  
10
   if (SREG & 0x02)       // wenn Zero-Flag gesetzt dann ...
11
   {
12
     PORTC &= ~(1 << PC5);        // LED an
13
   }
14
   
15
   while(1) {      
16
   
17
   }                         
18
 
19
   return 0;            
20
}

nur leider geht der LED kein Licht auf, und mir auch nicht :-(

Wie kann ich dem Atmega8 sagen das er bei der Berechnung die 
Statusregister unbedingt setzten soll ?

Viele Grüsse
Micha

von holger (Gast)


Lesenswert?

>Wie kann ich dem Atmega8 sagen das er bei der Berechnung die
>Statusregister unbedingt setzten soll ?

Wozu?

  uint8_t Ergebnis = 0x00 + 0x00;  // Rechnen

   if (Ergebnis == 0)       // wenn Zero-Flag gesetzt dann ...
   {
     PORTC &= ~(1 << PC5);        // LED an
   }

von Matthias L. (Gast)


Lesenswert?

>Wie kann ich dem Atmega8 sagen das er bei der Berechnung die
>Statusregister unbedingt setzten soll ?

Das passiert immer. Siehe instruction set summary, letzte spalte im 
datenblatt.

Ich glaube eher, dass es deshalb nicht geht, weil:

Die Berechnung durch den Linker oder Präprozessor schon geschieht. Der 
Prozessor selber wird die garnicht mehr sehen, sondern nur eine leere 
while

von micha (Gast)


Lesenswert?

Hey Holger,

weil mir nicht drum geht die Rechnung durchzuführen sondern das SREG 
auszulesen. Die Rechnung selbst ist nur mittel zum Zweck.

Viele Grüsse
Micha

von holger (Gast)


Lesenswert?

>weil mir nicht drum geht die Rechnung durchzuführen sondern das SREG
>auszulesen. Die Rechnung selbst ist nur mittel zum Zweck.

Das solltest du in C aber besser sein lassen SREG kann sich
z.B. in einer ISR unerwartet ändern. Also bleib bei C oder
programmier gleich in Assembler;)

von spess53 (Gast)


Lesenswert?

HI

>weil mir nicht drum geht die Rechnung durchzuführen sondern das SREG
>auszulesen. Die Rechnung selbst ist nur mittel zum Zweck.

Dann sieh dir den produzierten Assemblercode an. Bei C kannst du nicht 
sicher sein, das zwischen

  uint8_t Ergebnis = 0x00 + 0x00;  // Rechnen

und

   if (SREG & 0x02)       // wenn Zero-Flag gesetzt dann ...

nicht noch Assemblerbefehle sind, die SREG beeinflussen. Das Ganze ist 
eigentlich nur in Assembler sinnvoll.

MfG Spess

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

micha schrieb:
1
>    uint8_t Ergebnis = 0x00 + 0x00;  // Rechnen
2
> 
3
>    if (SREG & 0x02)       // wenn Zero-Flag gesetzt dann ...
4
>    {
5
>      PORTC &= ~(1 << PC5);        // LED an
6
>    }

Das kannst du in C so nicht machen!

Entweder du verwendest Assembler, oder schreibt sinnvolles C:
1
    uint8_t Ergebnis = 0x00 + 0x00;  // Rechnen
2
 
3
    if (Ergebnis == 0)       // wenn Zero-Flag gesetzt dann ...
4
    {
5
       PORTC &= ~(1 << PC5);        // LED an
6
    }
Das + muss nicht berechnet werden, weil das Ergenis immer 0 ist und der 
Compiler zB ein CLR Rn,0 oder ein LDI Rn,0 verwendn kann oder ein 
anderes Register per MOV, von dem er schon weiß, das da eine 0 drinne 
ist.

Ein paar Anmerkungen gibt's in [[Compilerfehler#Die häufigsten 
Nicht-Fehler]].

von Peter D. (peda)


Lesenswert?

Das SREG brauchst Du unter C nicht mehr.

Das ist ja der Witz an C, daß man sich nicht mehr um CPU spezifische 
Eigenheiten kümmern muß.


Peter

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Johann L. schrieb:
> Ein paar Anmerkungen gibt's in Compilerfehler: Die häufigsten Nicht-Fehler.

Konkret in deinem Fall heisst das, daß der Compiler Code erzeugt, der 
gleichbedeutend ist mit
1
    PORTC &= ~(1 << PC5);        // LED an
Denn "Ergebnis" ist komplett überflüssig.

von micha (Gast)


Lesenswert?

Danke euch allen
in Assembler funktioniert es
1
.include "m8def.inc"         
2
 
3
ldi r16, 0x20      
4
out DDRC, r16       ; PC5 ist Ausgang
5
 
6
ldi r16, 0x20
7
out PORTC, r16      ; LED erstmal aus
8
9
ldi r16, 0x00
10
ldi r17, 0x00
11
add r16, r17        ; Rechnung
12
13
in r16, SREG
14
cpi r16, 0x02       ; Vergleiche ob Zero-Flag gesetzt  
15
brne ende           ; wenn nicht spring
16
17
ldi r16, 0x00      ; ansonsten ...
18
out PORTC, r16     ; LED an    
19
 
20
ende:    rjmp ende

von Karl H. (kbuchegg)


Lesenswert?

micha schrieb:
> Danke euch allen
> in Assembler funktioniert es

Darum geht es nicht.
Niemand bezeifelt, dass das funktioniert.

Aber du musst akzeptieren, dass du durch die Benutzung eines C-Compilers 
die Kontrolle über so einiges aufgegeben hast. Die Arbeitsregister sowie 
das SREG stehen unter Kontrolle des Compilers. Aus C-Sicht existieren 
die nicht einmal. C hat kein Konzept eines Statusregisters oder eines 
Zero-Flags. Wenn du wissen willst, ob etwas 0 ist, dann schreibst du

   if( Ergebnis == 0 )

und wie der Compiler das realisiert ist sein Bier. Ob mit oder ohne SREG

von micha (Gast)


Lesenswert?

Hey Karl Heinz

ich habe ja schon akzeptiert das C mich da nicht weiter bring.
Ich bin nur gerade dabei auf eine Klausur zu lernen und in der einen 
Aufgabe geht es drum zu sagen welche Flags bei verschiedenen Rechnungen 
gesetzt werden.
Jetzt kann ich die Fälle bei denen ich mir nicht sicher bin wenigstens 
mal praktisch durchprobieren.

Grüsse Micha

von Matthias L. (Gast)


Lesenswert?

>Jetzt kann ich die Fälle bei denen ich mir nicht sicher bin wenigstens
>mal praktisch durchprobieren.

Oder das Datenblatt lesen. Dahinter steckt nämlich eine gewisse Logik.

von spess53 (Gast)


Lesenswert?

Hi

>Oder das Datenblatt lesen. Dahinter steckt nämlich eine gewisse Logik.

Eher das Instruction Set.

http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf

MfG Spess

von micha (Gast)


Lesenswert?

Ok, das Instruktion Set ist wirklich sinnvoll


ich tausche:
1
in r16, SREG
2
cpi r16, 0x02       ; Vergleiche ob Zero-Flag gesetzt  
3
brne ende           ; wenn nicht spring

gegen
1
brbc 1, ende        ;Branch if Status Flag Cleared

von spess53 (Gast)


Lesenswert?

HI

Nein.

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