1 | Lesepointer++;
|
2 |
|
3 | if (Lesepointer == toppointer) Lesepointer = bottompointer;
|
4 | Anzahl_Pufferelemente--;
|
In den drei Zeilen kann es schief gehen. Lesepointer als 16bit-Wert wird
mit zwei Befehlen aus dem Speicher geholt (unkritisch, da Lesepointer in
der in ISR nicht verändert wird), und nach der Veränderung in zwei
Schritten wieder reingeschrieben (kritisch). Wenn der Interrrupt genau
zwischen den Schreibbefehlen zuschlägt, liest die ISR Datensalat.
Wenn er Interrupt genau hinter der Aktualisierung von Lesepointer kommt,
ist Anzahl_Pufferelemente noch nicht aktualisiert, und damit nicht
konsistent zu den Pointern.
Also sollten die drei Zeilen zwischen cli() und sei().
Allerdings ist das alles mit Sicherheit nicht das einzige Problem, denn
der Fehler kommt nur, wenn der Intrerrupt genau an der ungünstigen
Stelle passiert. Mehr fällt mir aber an den paar Zeilen nicht auf (was
nichts bedeuten muß :-)
Ausserdem erschliesst sich mir der Sinn des Programms nicht so ganz. Das
Senden der 6 bytes per uart dauert viel länger als der Abfragezyklus des
ADC's. Warum liest du den nicht nur so oft aus, wie du die Werte auch
verarbeiten kannst? Sobald der Ringpuffer einmal voll ist, passiert ja
genau das. Da kannst du doch geleich alles in die Schleife des
Hauptprogramms packen, ganz ohne Ringpuffer.
Oliver