uint32_t in ISR

OP #735140
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
Gast #735161
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.
Gast #735162
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.
Gast #735176
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ß.
Gast #735338
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
OP #735376
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

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