Atmega32 - GCC: Problem mit long

Gast #916185
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
#916208
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...
Gast #916713
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?
#916718
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
Gast #916733
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?!?
#916735
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren