mikrocontroller.net

Forum: Compiler & IDEs uint32_t in ISR


Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Ich hab ein Problem.
Ich hab ne Routine, die nen uint32_t auf dem LCD Display ausgiebt:
void LCD_putn(uint32_t n)
{
    unsigned char i = 0;
    unsigned char buf[7];      
    do                          //fill the buffer iteratively...
    {
        buf[i++] = '0' + n % 10;
        n = n / 10;
    } while (n != 0);


    while( i > 0)               //...and print it backwards
    {
        lcd_data( buf[ --i ] ); // lcd_data sendet ein char auf das Display
    }
}

 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

Autor: HEADER (Gast)
Datum:

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



Gruss.

Autor: Andreas K. (a-k)
Datum:

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

Autor: Daniel Schillinger (enton)
Datum:

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

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: blub (Gast)
Datum:

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

Autor: blub (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
volatile unsigned char i = 0;

Autor: Andreas K. (a-k)
Datum:

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

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: blub (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
machs mit volatile und es wird klappe ...

schon hundert mal beim avr-gcc und isrs gesehen

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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ß.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Daniel Schillinger (enton)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Warum sollte ich die dann volatile machen?

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.