- LiFePO4 Speicher Test         
Ergebnis 1 bis 4 von 4

Thema: while, 16 Bit Zahlen und Interrupt.

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    08.06.2010
    Beiträge
    26

    while, 16 Bit Zahlen und Interrupt.

    Anzeige

    Praxistest und DIY Projekte
    Hatte eben ein merkwürdiges Phänomen:

    Ich habe einen 16 Bit-Counter, der in einem TMR0 Interrupt alle 0,68ms dekrementiert wird.
    Ab und an wurde der Counter in der while-Schleife als 0 erkannt, obwohl er auf 0xFF stand.
    Nach kurzer Überlegung bin ich drauf gekommen, dass es an daran liegen muss, dass der Counter 16-Bit lang ist und während der while Schleife ein TMR0-Int auftritt, der einen Unterlauf im Counter verursacht.

    Code:
    while (tmrFREQcounter) ;
    Gelöst habe ich das jetzt so:

    Code:
    while (tmrFREQcounter) while (tmrFREQcounter);;
    Das funktioniert auch, aber vielleicht gibt es ja eine bessere Lösung. Globale Interrupts verbieten kommt nicht in betracht.

    Ich bin jetzt erstmal auf ein char umgestiegen, da habe ich das Problem nicht.

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    So schlecht ist die Lösung mit dem 2 mal Abfragen gar nicht. Es geht aber auch besser. Die normale Lösung für eine Atomaren zugriff ist es Interrupts kurz zu sperren und dann wieder freizugeben.

    Die erste bessere Lösung ist es die Abfrage in der ISR zu machen, und dann ein extra Flag zu nutzen, das halt nur 1 Byte groß ist.

    Die 2 te besser Lösung ist es das Porgramm anders zu schreiben. Es gibt bessere Methoden um Zeiten zu messen oder defierniert zu warten, als in einer ISR zu zählen. Für die Zeitmessung kann man gleich das Timer Regeistser nutzen, und dann ggf. nur noch die Überläufe Zählen. Für eine Wartezeit kann man ähnlich nur die Überläufe Zählen, und den Startwert des Timers passend vorladen. Das Hauptprogramm kann dann ggf. auch den sleep Befehl nutzen. Das gibt dann zyklus-genaue Wartezeiten, und nebenbei weniger Stromverbrauch.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    08.06.2010
    Beiträge
    26
    Das mit dem Flag gefällt mir.

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo,
    mit dem 16 Bit (2 Byte) Problem hatte ich auch zu kämpfen.
    Das Problem tritt unter Umständen immer dann auf, wenn Der Zählerstand zum Beispiel grad auf 256 steht.
    Dann ist das High Byte auf 1 und das Low Byte auf 0.

    während jetzt das Low Byte abgefragt wird, welches im Moment noch 0 war, springt der Wert eins runter.
    dadurch steht nun im Low Byte plötzlich 255 und im High Byte ein 0
    Jenachdem, wie der C Compiler seinen Code erstellt hat, kommt dann sicher Blödsinn raus.

    Da der PIC nicht 16 Bit direkt vergleichen kann, kommt es hier zu "Unannehmlichkeiten"
    Er läd z.B den Wert den Highbytes. Dieser stand auf 1 (wegen dem Zählerstand 256)
    durch einen erneuten Zählerwechsel steht aber nun das Lowbyte auf 255 und das High Byte auf 0
    Nun erfolgt der Zugriff aufs Low Byte, welches plötzlich auf 255 steht. Das muss unweigerlich in die Hose gehen.

    Ich habe meine 16 Bit Timer Null Abfrage zum Beispiel so gelöst:

    Lade das Low Byte des Zählers
    oderiere das High Byte des Zählers.
    oderiere nun nochmal das Low Byte des Zählers.

    Wenn jetzt 0 rauskommt, ist der Zähler wirklich auf 0. Selbst wenn innerhalb der Abfrage sich der Zählerstand per Interrupt geändert hat.
    Das macht sich in Assembler recht einfach. In "C" hat man nicht so ohne weiteres Zugriff auf die einzelnen Bytes eines
    16 Bit Wertes.

    in Assembler würde es dann so aussehen:

    ; warte bis der 16 Bit Zählerwert, welcher im Interrupt runtergezählt wird, Null wird

    WarteAufNull:
    movf ZaehlerLowByte,W
    iorwf ZaehlerHighByte,W
    iorwf ZaehlerLowByte,W
    btfss STATUS,Z
    goto WarteAufNull


    vielleicht kannst Du ja etwas damit anfangen.
    mfg. Siro

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen