Forum: Compiler & IDEs uint32_t in ISR


von Daniel S. (enton)


Lesenswert?

Hallo Leute

Ich hab ein Problem.
Ich hab ne Routine, die nen uint32_t auf dem LCD Display ausgiebt:
1
void LCD_putn(uint32_t n)
2
{
3
    unsigned char i = 0;
4
    unsigned char buf[7];      
5
    do                          //fill the buffer iteratively...
6
    {
7
        buf[i++] = '0' + n % 10;
8
        n = n / 10;
9
    } while (n != 0);
10
11
12
    while( i > 0)               //...and print it backwards
13
    {
14
        lcd_data( buf[ --i ] ); // lcd_data sendet ein char auf das Display
15
    }
16
}

 Das funktioniert auch wunderbar in der main Routine, dort gibt er mir 
für
LCD_Putn(0xffff) 65535 aus. Wenn ich das aber in der ISR von INT1 mache, 
gibt er 4294901766 aus.
Wenn ich void LCD_putn(uint32_t n) zu void LCD_putn(uint16_t n)
umändere, funktioniert es auch in der ISR. Wenn ich uint32_t zu uint64_t 
mache, funktioniert es auch nicht.

Ist man in einer ISR irgendwie beschränkt bei der Zahlengröße, oder hat 
jemand ne Ahnung wo der Fehler sonst liegen könnte?

Gruß enton

von HEADER (Gast)


Lesenswert?

Schalte beim kompilieren den Schalter -Wall an. Evtl. hast du die 
Funktion nicht deklariert und der Kompiler geht von uint16_t aus.



Gruss.

von Andreas K. (a-k)


Lesenswert?

Dass ein 7-Byte Puffer für bis zu 10-stellige Zahlen etwas eng werden 
kann ist dir bewusst?

von Daniel S. (enton)


Lesenswert?

Ja. Das war nur zum ausprobieren. Für 0xffff reicht ja schon ein 5-Byte 
Puffer.

von Daniel S. (enton)


Lesenswert?

Wo kann ich -Wall einstellen. Bin bei WINAVR leider noch nicht so 
bewandert. Wenn der Kompiler von uint16_t ausgeht, warum funktioniert es 
dann in der main Routine und in der ISR nicht?

von Rolf Magnus (Gast)


Lesenswert?

> Evtl. hast du die Funktion nicht deklariert und der Kompiler geht von
> uint16_t aus.

Er würde in diesem Fall von int ausgehen, was auf dem AVR int16_t 
entsprechen würde (also vorzeichenbehaftet). Aber das könnte durchaus 
das Problem sein.

> Für 0xffff reicht ja schon ein 5-Byte Puffer

Dann brauchst du aber keinen uint32_t.

von Rolf Magnus (Gast)


Lesenswert?

> Wenn der Kompiler von uint16_t ausgeht, warum funktioniert esdann in
> der main Routine und in der ISR nicht?

Wenn die Definition vor main(), aber nach der ISR kommt, könnte das 
schon sein. Oder wenn die ISR in einer anderen .c-Datei steht.

von blub (Gast)


Lesenswert?

setze vor i mal ein volatile, der compiler optimiert sonst in der 
schleife im int den i++ kram weg

von blub (Gast)


Lesenswert?

volatile unsigned char i = 0;

von Andreas K. (a-k)


Lesenswert?

Und 4294901766 ist 10-stellig, das heisst da wurde schon falscher 
Speicher vernichtet.

von Andreas K. (a-k)


Lesenswert?

@blub: nein.

Lass ihn optimieren wie er will (wird er hier nicht), es wird das 
gleiche rauskommen. volatile ist wichtig wenn ohne Kenntnis des 
Compilers noch jemand anders daran rumfuhrwerkt, oder man sinnlosen Code 
erzwingen will (Zeitschleife).

von blub (Gast)


Lesenswert?

machs mit volatile und es wird klappe ...

schon hundert mal beim avr-gcc und isrs gesehen

von Rolf Magnus (Gast)


Lesenswert?

> machs mit volatile und es wird klappe ...

Unsinn.

> schon hundert mal beim avr-gcc und isrs gesehen

Nur weil's ein Problem mit einer ISR ist, bedeutet das nicht gleich, daß 
man nur einfach irgendeine Variable volatile machen muß, und schon 
tut's.
Bei diesem Schleifenzähler ist das einzige was volatile bewirkt, eine 
längere Laufzeit der ISR und etwas mehr Stackverbrauch, weil die 
Variable nicht mehr in einem Register gehalten werden kann, sondern 
ständig aus dem RAM gelesen und wieder hineingeschrieben werden muß.

von Walter (Gast)


Lesenswert?

ich würde empfehlen langwierige Aufgaben (wie die LCD Ausgabe) NICHT in 
Interrupts auszuführen,
das eine Problem ist wenns zu lange dauert,
das andere wenn auch im main Ausgaben erfolgen

Walter

von Karl H. (kbuchegg)


Lesenswert?

blub wrote:
> machs mit volatile und es wird klappe ...

Die Geschichte des volatile ist eine Geschichte voller
Missverständnisse.

volatile ist fast zu universell wie ein OB. Man kann damit
reiten, tennis spielen, tauchen und gegen Gicht und Rheuma
ist es auch gut.

von Daniel S. (enton)


Lesenswert?

Hat geklappt, es lag an der deklaration. Wie schon von  Rolf Magnus 
vermutet, war die definition vor main und nach der ISR. Hab die 
deklaration nun vor die ISR geschrieben und es hat geklappt. Das mit 
volatile hat nichts geändert.
Hätte da aber mal ne Frage zu:
Ich hatte immer gedacht, das man eine Variable nur volatile macht, wenn 
man eine globale Variable braucht, auf die man in der ISR als auch in 
der main Routine zugreifen kann.
Meine Variable i ist hier ja nur eine Laufvariable, die bei jedem 
Funktionsaufruf neu erzeugt wird. Warum sollte ich die dann volatile 
machen?

Gruß enton

von Markus (Gast)


Lesenswert?

>Warum sollte ich die dann volatile machen?

das solltest du auch nicht. es ist so wie du im letzten Posting 
geschrieben hast

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.