Habe gestern von Karl Heinz Buchegger folgenden Code Vorschlag bekommen um unterschiedliche buffer zum speichern von Daten zu Nutzen. Ich habe noch folgendes Problem: Ich möchte vier Interrupt nutzen um Zeiten zu messen! Mit der funktion store (siehe unten) kann ich auch im Interrupt den Wert des ICU abspeichern. Wie ist das jetzt zu realisieren das von jeder Zeit nur fünf Werte in den Buffer geschrieben werden und der dann automatisch wechselt in den nächsten. Zur Auswertung soll dann immer der Buffer genutzt werden der zuletzt aktiv war. Bitte kann mir jemand helfen wie soetwas zu realisieren ist? struct Buffer { int Werte[100]; int NrWerte; }; struct Buffer Messung1; // der erste Buffer struct Buffer Messung2; // der zweite Buffer struct Buffer Messung3; // der dritte Buffer struct Buffer* Active; // Zeiger auf den aktiven Buffer // in den aktiven Buffer werden Werte // geschrieben void Store( int Wert ) { // Speicher den Wert im aktiven Buffer Active->Werte[ Active->NrWerte ] = Wert; Active->NrWerte++; } int main() { // den ersten Buffer aktivieren Messung1.NrWerte = 0; Active = &Messung1; // speichere ein paar Werte im aktiven Buffer Store( 100 ); Store( 50 ); Store( 150 ); // Es ist Zeit den 2. Buffer zu aktivieren ... Messung2.NrWerte = 0; Active = &Messung2; // .. denn wir wollen mit der ersten Messreihe was machen Compute( &Messung1 ); } void Compute( struct Buffer& Buff ) { int i; for( i = 0; i < Buff->NrWerte; ++i ) printf( Buff->Werte[i] ); }
//Initialisiere struct Buffer* temp; struct Buffer* Active; struct Buffer* Last_active; struct Buffer* Next_active; //Definiere vor der main Loop Active = &Messung1; Next_active = &Messung2; Last_active = &Messung3; //In der main Loop temp = Last_active; Last_active = Active; Active = Next_active; Next_active= temp; /* und nun hast du die Buffer bei jeder main Loop durchgetauscht, kannst den Alten bearbeiten und den Neuen beschreiben. Compute( &Last_active ); Store( 100 ); Store( 50 ); Store( 150 ); Warum sind eigentlich deine Buffer so groß, wenn du blos je 3 Werte speichern möchtest? Gruß */
Das war nur das Codebeispiel! Hatte im ersten Beitrag keine Angabe zur größe des Buffers gemacht. Habe in der main allerdings wenig stehen meine application wird durch reload timer interrupts zyklisch aufgerufen!
Kann das auch in einer switch case erfolgen mit dem Buffer umschalten?
> struct Buffer Messung1; // der erste Buffer > struct Buffer Messung2; // der zweite Buffer > struct Buffer Messung3; // der dritte Buffer Durchnummerierte Variablen sind ein sicherer Hinweis darauf dass man eigentlich ein Array verwenden möchte. Dann kann man sich auch sowas sparen: temp = Last_active; Last_active = Active; Active = Next_active; Next_active= temp; ...und stattdessen einfach einen Index inkrementieren.
natürlich, warum nicht? Ich hab das Gefühl, du solltest dir über die Struktur und den Aufbau deines Programms mal ein paar Gedanken machen und über das was du eigentlich wie realisieren möchtest. Grüße
Und vor allen Dingen: Hinsetzen und mal auf dem Papier ein paar Skizzen machen: Welche variablen gibt es, wie verhalten sie sich zueinander, was ist wo gespeichert, was muss wann passieren. Dann löst sich so manches Problem von alleine in Luft auf.
to Andreas! Das ist ja alles richtig mein problem bei der ganzen sache ist doch das ich mir bei einem Array nicht sicher bin wenn ich in der Berechnung bin ob da nun schon neue oder die eigentlich zu verwendeden alten werte stehen. Aufgrund dessen soll für einen Messwert ein Array für fünf werte zur verfühgung stehen. Von diesem Array brauche ich fünf damit die Berechnung in ruhe und ohne sorge das die werte überschrieben werden durchgeführt werden kann. Grundsätzlicher Aufbau main initialisiert die ICU, ADC, Eingänge, Ausgänge usw. geht dann in eine Endlosschleife die durch Interrupts unterbrochen wird. Z.B. um ADC Messwerte abzuholen. Ein reload Timer steuert diese ganze Geschichte. Jetzt habe ich Input Capture mit Interrupt programmiert in welchem der Zeitwert in einem Buffer geschrieben werden soll. Dieses habe ich für vier Input Capture gemacht. Die Interrupts sind gegeneinander gesperrt so das sie nur in der richtigen reihenfolge auftreten können. Meine Application wird zyklisch aufgerufen um jetzt zu verhindern das soetwas wie oben beschrieben passiert d.h. das alte Werte mit in die Berechnung einfließen suche ich nach einer Kompforttablen lösung die mir aber leider nicht einfällt. Also Interrupt kommt > Wert wird gespeichert > wenn 5 Werte im buffer(bei allen Messungen) soll der nächste buffer genommen werde > hinweis für die App Note buffer"1" voll berechnung kann starten > nach füllen des letzten buffers switchen auf den ersten. Und ich kriegs nicht hin und brauche eure Hilfe!!
Wie Andreas schon sagte: Anstatt 3 einzelnen struct Buffer Variablen macht man halt ein Array aus diesen. Anstatt dem komplizierten Pointer-häck-mäck tritt dann eine ganz einfache Indexvariable. struct Buffer Messungen[10]; // 10 mögliche Buffer int ActiveBuffer; // der Index des aktiven Buffers wenn du einen Buffer weiterschalten willst, machst du einfach ActiveBuffer++; Natürlich musst du aufpassen, dass das ganze auch immer schön im Kreis rumgeht, d.h. wenn ActiveBuffer den Wert 10 erreicht hat, gehts wieder bei 0 los: ActiveBuffer++; if( ActiveBuffer == 10 ) ActiveBuffer = 0; Der vorhergehende Buffer ist dann auch leicht zu bestimmen, das ist einfach der mit dem Index um 1 kleiner als ActiveBuffer. Auch hier wieder aufpassen: das geht im Kreis herum, der vorhergehende Buffer zum Index 0 ist der Buffer Nr. 9 und nicht -1. Der Zugriff auf die Werte gestaltet sich dann: Messungen[ActiveBuffer].Werte[5] = ... Über die Nummer in ActiveBuffer wird ein Buffer aus dem Array aller Buffer ausgewählt. In diesem einen Buffer gibt es dann wieder ein Array in dem alle Werte sind und mit dem zweiten Index wird einer davon ausgewählt. Wie ich schon sagte: mal eine Zeichnung machen: Mesungen +-----------------------------------------------+ | Werte | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | | | | | | | | | | | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | NrWerte | | +------+ | | | | | | +------+ | +-----------------------------------------------+ | Werte | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | | | | | | | | | | | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | NrWerte | | +------+ | | | | | | +------+ | +-----------------------------------------------+ . . . . . . +-----------------------------------------------+ | Werte | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | | | | | | | | | | | | +---+---+---+---+---+- ... -+---+---+---+---+ | | | | NrWerte | | +------+ | | | | | | +------+ | +-----------------------------------------------+
Ich auch mal meinen Senf dazugebend: unsigned char messungen[10][10]; unsigned char zeile,spalte; adc_int messungen[zeile][spalte] = adc; if (zeile < 9) { zeile++; } else zeile = 0; if (spalte < 9) { spalte++; } else { spalte = 0; } } ... und zum berechnen: if (spalte == 0) { brechne spalte 9; } else { berechne spalte - 1; } müsste doch gehen oder? MW
Klar geht das genauso. Die eigentliche Frage sollte aber sein. Warum diese künstliche Unterteilung in x Messwerte? Wenn es keinen wirklichen Grund dafür gibt, jeweils x Messwerte zu einer Gruppe zusammenzufassen ist ein stink normaler Ringbuffer doch viel einfacher als ein 2D Array. Egal wie es realisiert wird (meine Lösung ist auch nur ein glorifiziertes 2D Array, wobei jede Zeile seinen eigenen Füllstandsmesser hat). Ringbuffer: +---+---+---+---+---+---+---+---+ | | | | | | | | | +---+---+---+---+---+---+---+---+ ^ ^ | | ReadIndex | | +----+ | | | o-----------+ | +----+ | | WriteIndex | +----+ | | o-------------------+ +----+ Der WriteIndex sagt immer wo als nächstes geschrieben werden darf und wird bei einem Schreibvorgang um ein Feld weitergesetzt (und natürlich an den Anfang zurück, wenn das Ende des Arrays erreicht ist). Read ReadIndex sagt aus von wo der nächste Wert zur Verarbeitung gelesen werden kann (und wird nach dem Lesevorgang weitergesetzt). Ist der ReadIndex identisch mit dem WriteIndex, so ist der Buffer leer. Ist der WriteIndex um 1 kleiner als der ReadIndex, so ist der Buffer voll und es passt nichts mehr rein. Aber das kann ich nicht beurteilen. Ich kenne die Aufgabenstellung nicht und weiss dahere nicht ob es einen speziellen Grund dafür gibt jeweils x Einträge zusammenzufassen (was man im übrigen auch mit dem Ringbuffer erreichen könnte). Abgesehen davon ist das bisher Vorgeschlagene eine gute Übung im Arbeiten mit Strukturen und Arrays.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.