Forum: Mikrocontroller und Digitale Elektronik Controller in C rechnet falsch


von Thomas (Gast)


Lesenswert?

Hallo zusammen,

habe hier ein Problem, an dem ich jetzt seit Tagen nicht weiter komme.
Ich habe einen PIC18F46K22 mit dem C18 Compilter und dem PICkit 3.
Realisieren will ich einen Timer, dazu habe ich einen globalen Counter
1
unsigned int tick10msCount;
der durch eine ISR alle 10 ms hoch gezählt wird.

Dazu habe ich eine Funktion
1
unsigned int Get10msDiff(unsigned int stamp)
2
{
3
      return (tick10msCount - stamp);
4
}
die mir die Differenz von einer Variablen zum aktuellen Counterstand 
zurückgibt.

Mein Code sieht dann folgendermaßen aus:
1
unsigned int diff = 0;
2
unsigned int current_timer = 0;
3
..
4
..
5
diff = Get10msDiff(toggle_timer);
6
if( diff >= 0x00c8 ) // 0xc8 => 200 x 10ms = 2 Sekunden
7
{
8
   // Code, der alle 2 Sekunden ausgeführt werden soll
9
   toggle_timer = tick10msCount;
10
}

Jetzt habe ich relativ oft das Problem, dass mir die Funktion falsch 
rechnet, bzw. eine "1" an der dritten Stelle hinzusetzt. Aus dem 
Debugger weiß ich, dass die Differenz z.B. 0x006b sein müsste, die 
Funktion gibt mir aber 0x016b zurück. Oder es müsste 0x0037 sein, aber 
die Variable diff hat dann 0x0137. Es wird also immer genau 0x0100 
zuviel ausgegeben.

Ich hoffe sehr, ich habe irgendwo einen dummen Fehler und ihr könnt 
helfen.

DANKE
Gruß Thomas
von Tom (Gast)


Lesenswert?

Dann wird dein Zugriff auf die in der ISR geänderte Variable nicht 
atomar sein und das High-Byte wird zwischendurch geändert.
von g457 (Gast)


Lesenswert?

ISR und globale Variable klingt zuallererst mal nach einem fehlenden 
volatile..

HTH
von lorsen (Gast)


Lesenswert?

>volatile..
nein.

Aber Tom hat wahrscheinlich recht mit seiner Vermutung.
Wenn es ein 8 Bit Rechner ist und in der ISR werden 16Bit Variablen 
manipuliert,
dann muss man im Hauptprogramm beim Zugriff auf die Variable sowas 
schreiben:

Interrupt_sperren();
i = meine16BitVariable;
Interrupt_freigeben();
von Thomas (Gast)


Lesenswert?

Hallo zusammen

Vielen Dank! Ich habe die Interrupts jetzt gesperrt, sobald ich mit der 
Variable arbeite. Es scheint jetzt zu funktionieren, zumindest hatte ich 
die letzten Minuten keinen Fehler mehr. Im Nachhinein erscheint das 
völlig logisch. Hätte vielleicht früher mal fragen sollen, dann hätte 
ich mir viele Stunden erspart...

Noch einmal vielen Dank an alle und ebenso allen einen schönen Sonntag.

Gruß Thomas
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.