Forum: Mikrocontroller und Digitale Elektronik Probleme mit Ringspeicher


von Michael (Gast)


Lesenswert?

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

von Erwin T. (Gast)


Lesenswert?

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.

von Rahul D. (rahul)


Lesenswert?

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...

von Rolf F. (Gast)


Lesenswert?

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

von Rahul D. (rahul)


Lesenswert?

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...

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.