Probleme mit Ringspeicher

Gast #216890
Hallo,

ich habe da noch Probleme mit dem Ringspeicher.

unsigned char LeseZeiger;
unsigned char SchreibZeiger;
unsigned char Feld[100];
---
..
while(1)
{
 Feld[SchreibZeiger++] = T; //Temperaturwerte im Array

             if (SchreibZeiger == 100)
                {
                  SchreibZeiger = 0;
                  LeseZeiger ++;
                  if (LeseZeiger == 100)
                   {
                    LeseZeiger = 0;
                    for(x=0;x<100;x++)
                     {
                      LCD_PutPixel(x,Feld[x++], 1);  //Ausgabe


                     }
                   }
                }
}

Was muss ich da ändern? Bei mir tut sich nix.
Ich möchte es so haben, dass das die Kurve aussieht wie in einem
Echtzeit Diagramm
Gast
Ich hab mal die Glaskugel ausgepackt und folgende aenderungen
vorgenommen:
(Ich denke naemlich nicht dass du alle 10000 Durchlaeufe die
Temperaturwerte ausgeben willst...)

for(;;) {

   Feld[SchreibZeiger++] = T;

   if(SchreibZeiger == 100)
      SchreibZeiger = 0;

   LeseZeiger++;

   if(LeseZeiger == 100)
      LeseZeiger = 0;

   for(x=0;x<100;x++)
       LCD_PutPixel(x,Feld[x++], 1);
}

natuerlich aendert das nichts daran dass:

1. Der LeseZeiger gar nichts bewirkt.
2. Auch wenn er was machen wuerde, was bringt die Speicherung der
Temperaturwerte, wieso gibst du die ned direkt auf dem Display aus?
3. Wenn das reinschreiben und auslesen getrennt voneinander geschehen
soll, warum das ganze in eine Schleife packen?
4. Du dringend an deinem Programmierstil arbeiten solltest.
Nicht ganz, Rufus:
Es geht um einen Ringspeicher, in den die Messwerte eingetragen werden
und auf einem Display angezeigt werden sollen (dazu gibt es hier auch
einen Thread [Echtzeit-Diagramm]; dass es für C-Sachen ein eigenes
Forum gibt, ignoriere ich jetzt mal...).

Der Lesezeiger soll den ersten auszugebenden Wert markieren.
Solange der Puffer noch nicht voll ist (Schreibzeiger <100) passiert
mit dem Lesezeiger nichts.
Sobald der Schreibzeiger wieder von vorne anfängt, muss der Lesezeiger
auch bei jedem neuen Messwert inkrementiert werden.
Die Ausgabeschleife an das Display gibt dann das Feld ab dem Lesezeiger
aus.

Lösungsvorschlag (Diskussionsgrundlage):

for(;;)
{
  Feld[Schreibzeiger++] = T;


  if (Schreibzeiger >= 100)
  {
    Schreibzeiger = 0;
    if (Lesezeiger == 0)
    {
      Lesezeiger ++;
    }
  }
  if (Lesezeiger >= 100)
  {
    Lesezeiger = 0;
  }
  Hilfszeiger = Leseszeiger;
  for(x=0;x<100;x++)
  {
    LCD_PutPixel(x, Feld[Hilfszeiger++], 1);
    if (Hilfszeiger >= 100)
    {
      Hilfszeiger = 0;
    }
  }
}

Sind jetzt viele Klammern dabei, die nicht sein müssten...
Gast
Du solltes für die Ringpuffer-Operationen Makros nehmen:

// increment for ring buffer index (0..n-1), also works with start
value -1
#   define mc_RING_INC(x, n) {++(x); (x) %= (n);}

// next value at incrementing, preview
#   define mc_RING_NEXT(x, n) (((x)+1)%(n))

// decrement for ring buffer index (0..n-1), also works with start
value < 0
#   define mc_RING_DEC(x, n) {if((x) > 0)  --(x); else (x)=(n)-1;}

// value before last increment, review
#   define mc_RING_LAST(x, n) ( (x) ? ((x)-1) : ((n)-1))

// number of elements in the ring buffer
#   define mc_RING_QUANTITY(x, n) ( (x) >= n-1 ? n : ((x)+1))

Damit wird der Code a) übersichtlicher (und kompakter) sowie b)
sicherer, da man Sachen wie Inkrementieren eines Rinpuffer-Indexes (mit
Wrap Around) nicht immer neu erfinden und debuggen muß.
wieso hab ich mich auf Rufus bezogen? Son Quatsch.

@Rolf:
Wie soll er die Makros verstehen, wenn er nicht mal weiß, wie man einen
Ringspeicher auf "einfache" Weise programmiert?
Das muß ihm erst mal klar werden...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.