Forum: Mikrocontroller und Digitale Elektronik Atmega32 - GCC: Problem mit long


von Lalle (Gast)


Lesenswert?

Hi Ihrs,

ich habe folgenden Code:

volatile unsigned long seconds = 0;

void RTC_Overflow()
{
  seconds++;
  IO_Write(seconds);
}

IO_Write gibt den Wert einfach über LED's aus. RTC_Overflow wird jede 
Sekunde über einen Interupt aufgerufen.

Mein Problem ist das sich bei den LED's nichts tut (seconds beibt immer 
0). Wenn ich seconds als int deklariere (volatile unsigned int seconds = 
0;) klappt alles ohne Probleme.

Hat jemand eine Idee wodran das liegen könnte?
Früher hatte der selbe Code mal geklappt?!?

(Auch Optimierung ausschalten bringt nichts)

Gruß Lalle

von J. K. (rooot)


Lesenswert?

muss es nicht "long int" heißen?

von Johannes M. (johnny-m)


Lesenswert?

J. K. wrote:
> muss es nicht "long int" heißen?
Nö.

von Lalle (Gast)


Lesenswert?

mit long int passiert das gleiche wie bei long

von Johannes M. (johnny-m)


Lesenswert?

Lalle wrote:
> mit long int passiert das gleiche wie bei long
Hätte mich auch sehr gewundert wenn nicht...

Die Codezeilen, die Du oben zeigst, sind offensichtlich korrekt (bis auf 
die Tatsache, dass Du Dir die Initialisierung der Variablen mit 0 sparen 
kannst, da seconds global ist und so automatisch mit 0 initialisiert 
wird). Der Fehler dürfte also woanders stecken...

Wenn Du z.B. wenigstens die Funktion IO_write mal rausrücken 
könntest...

von Lalle (Gast)


Lesenswert?

IO_Write sieht wie folgt aus:

void IO_Write(char Data)
{
  PORTB = (Data & ((1<<0)|(1<<1)|(1<<2))) | (PORTB  & 
((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)));
}

Söllte aber eigentlich egal sein, da mit gleichen Parametern auch das 
gleiche Ausgegeben werden söllte.

Könnte es vielleicht sogar ein Compiler Fehler sein? Oder der Fehler 
ganz wo anders liegen? Hat jemand irgendeine Idee?

von Rudolph R. (rudolph)


Lesenswert?

Schau Dir doch mal an, was der Compiler daraus macht.
Also mal einen Blick in die .lss Datei werfen.


Kann daran nicht liegen aber die Verwendung der neueren Schreibweise für 
die Datentypen kann ich nur empfehlen, die sind wirklich eindeutig:

unsigned long -> uint32_t
char -> uint8_t

von Lalle (Gast)


Lesenswert?

000011aa <RTC_Overflow>:
    11aa:  80 91 d4 01   lds  r24, 0x01D4
    11ae:  90 91 d5 01   lds  r25, 0x01D5
    11b2:  a0 91 d6 01   lds  r26, 0x01D6
    11b6:  b0 91 d7 01   lds  r27, 0x01D7
    11ba:  01 96         adiw  r24, 0x01  ; 1
    11bc:  a1 1d         adc  r26, r1
    11be:  b1 1d         adc  r27, r1
    11c0:  80 93 d4 01   sts  0x01D4, r24
    11c4:  90 93 d5 01   sts  0x01D5, r25
    11c8:  a0 93 d6 01   sts  0x01D6, r26
    11cc:  b0 93 d7 01   sts  0x01D7, r27
    11d0:  60 91 d4 01   lds  r22, 0x01D4
    11d4:  70 91 d5 01   lds  r23, 0x01D5
    11d8:  80 91 d6 01   lds  r24, 0x01D6
    11dc:  90 91 d7 01   lds  r25, 0x01D7
    11e0:  0e 94 74 0c   call  0x18e8  ; 0x18e8 <IO_Write>
    11e4:  08 95         ret

Was mich wundert ist das er den Überlauf von r24 nicht auf r25 addiert. 
Oder sehe ich das falsch? Bei 11bc müsste doch erst ein adc r25, r1 
stehen?!?

von Andreas K. (a-k)


Lesenswert?

> Was mich wundert ist das er den Überlauf von r24 nicht auf r25 addiert.

Passt schon. ADIW = 16-Bit-Addition, R25:R24 += 1.

ABER: Es sieht so aus, als ob der Compiler die Funktion IO_Write zu dem 
Zeitpunkt nicht kennt, denn als Funktion mit 8-Bit Parameter erwartet 
sie den in R24, kriegt das untere Byte hier aber in R22.

Wenn seconds "int" ist, dann passt das wieder, weil das in R25:R24 statt 
R25:R24:R23:R22 landet.

Warnung ignoriert?

von Lalle (Gast)


Lesenswert?

Japp recht gehabt!
Vielen Dank! Jetzt klappt es...

Gruß Lalle

von Andreas K. (a-k)


Lesenswert?

Vielleicht ersparen dir die Optionen -Wall -Werror künftige Probleme 
dieser Art.

von Lalle (Gast)


Lesenswert?

Gute Idee. Danke!

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.