Gemeinsammer zugriff auf Speicher

Gast #3247034
Lesenswert?

Hallo zusammen,

ich hätte eine kurze Frage.
Ich habe einen Speicher den ich per Interrupt auf einer LED-Matrix 
ausgebe.
Jetzt habe ich eine Funktion die Werte in den Speicher legt (in der 
main).
Es wird immer zuerst der komplette Speicher gelöscht (da ich nicht jede 
Stelle beschreibe) und dann die neuen Informationen abgelegt. Der 
Interrupt schreibt die Daten auf die Anzeige wann immer er auch kommt. 
Ich dachte es macht nichts aus, wenn er "mittendrin" kommt, doch leider 
sieht man ab und zu ein flackern.
Da die Main noch ziemlich leer ist, wird die "Schreib-Funktion" häufig 
aufgerufen und wenn es doof läuft schreib die Ausgaberoutine immer einen 
leeren Videospeicher raus.

Deswegen möchte ich den Speicher nur ändern, wenn keine Ausgabe erfolgt.
Frage ist wie macht man das ordenlich.

Interupt deaktivieren
Speicher beschreiben
Interrupt aktivieren???
Dann würde die Interrupts wärend dieser Zeit flöten gehen.

Andere Möglichkeit wäre Speicher den Speicher nur während des Interrupts 
zu ändern.
D.h.
Interrupt
-> neue Daten übernehmen
-> Ausgabe
Ende.

Finde beide Möglichkeiten nicht so toll. Wie macht man es richtig?
Vielen Dank und viele Grüße
...
Gast #3247054
Lesenswert?

Wenn genug Speicher vorhanden ist: Zwei Puffer anlegen und in den main 
abwechselnd befüllen und nach jedem Befüllen ein bit toggeln, damit der 
Interrupt weiß, aus welchem Puffer er lesen soll.
Ansonsten musst du das Puffern und die Ausgaben synchronisieren. Wo 
kommen die Daten den her? Kannst du nach der Ausgabe im Interrupt 
prüfen, ob neue Daten zur Verfügung stehen und diese dann in den Puffer 
schreiben?
Gast #3247071
Lesenswert?

Wow,

das ging schnell... :-D
Hier haben wohl grad einige Mittagspäuschen.

Vielen Dank an alle!
Das mit dem Doppelspeicher probier ich mal aus.

D.h. wenn ich Speicher1 fertig beschrieben habe setze ich ein Flag auf 
Speicher1 -> Interrupt gibt Speicher 1 aus
Wenn ich das nächste mal schreiben möchte, teste ich das Flag und wenn 
es auf Speicher 1 steht schreibe ich in Speicher 2. Speicher 1 wird so 
lange ausgegeben, bis das Flag in der Schreibroutine auf Speicher 2 
umgestellt wird.

Super Danke!
Ist besser als den Interrupt zu deaktivieren.


VIELEN DANK!
#3247074
Lesenswert?

> Es wird immer zuerst der komplette Speicher gelöscht
> (da ich nicht jede Stelle beschreibe)

Diesen Teil würde ich in Frage stellen. Also, das komplette Löschen.
Tus nicht, dann flackert auch nichts.

Ist irgendwie dasselbe wie: Hilfe, mein LCD flackert.
UNd wenn man dann ins Programm reinschaut, wimmelt es da wieder nur so 
vor AUfrufen von LCD Lösch Routinen.

Der Trick besteht darin, eben nicht zu löschen wenn es nicht sein muss, 
sondern die Teile zu überschreiben, die sich ändern.
Gast #3247077
Lesenswert?

... schrieb:
> D.h. wenn ich Speicher1 fertig beschrieben habe setze ich ein Flag auf
> Speicher1 -> Interrupt gibt Speicher 1 aus
statt flag, kann man auch einen Zeiger verwenden der auf die aktuellen 
Daten zeigt.

> Ist besser als den Interrupt zu deaktivieren.
brauchst du dann nicht.
Gast #3247095
Lesenswert?

Mal eine Idee wie sowas aussehen könnte:
1
uint8_t myMatrix1[8];
2
uint8_t myMatrix2[8];
3

4
uint8_t *readPtr myMatrix1;
5
uint8_t *writePtr myMatrix2;

In der ISR benutzt du nur den readPtr, in der main, wo deine 
Berechnungen liegen verwendest du den writePtr.
Somit sparst du dir jedesmal die Flag-Abfrage.

Wenn ein neues Bild zur Ausgabe fertig berechnet wurde, einfach kurz die 
Pointer vertauschen. Dieser Abschnitt muss allerdings atomar sein.
1
uint8_t *tmpPtr;
2
 
3
cli();
4

5
tmpPtr = readPtr;
6
readPtr = writePtr;
7
writePtr = tmpPtr;
8

9
sei()
Gast #3247109
Lesenswert?

1. Beim Schreiben in "LEDs" geht es praktisch immer um die maximale
   Geschwindigkeit der menschlichen Wahrnehmung. Also nix mit
   Mikrosekunden oder gar schneller.
2. Einen Speicher komplett löschen, bedeutet erst mal: Du hast nix
   besseres zutun.

Fazit: Den Speicher von vorne beschreiben bis (gewünschtes) Ende,
       diesen Zeiger (Ende) merken und von da aus löschen. In praktisch
       allen Fällen merkt kein Mensch, wenn Du in dieser Zeit die
       Ausgabe stoppst.

Also spar' Dir das Dual-Ported-RAM und geh dafür mit Deiner Freundin mal 
gut essen.

Übrigens: Was soll das bringen? Offensichtlich hast Du ja kein Zugriffs- 
sonder ein Timing-Problem.
(Firma: matzetronics) #3247241
Lesenswert?

Peter II schrieb:
> Matthias Sch. schrieb:
>> Der Interrupt kann auch ein Flag setzen, das er gerade aktiv ist, und
>> main checkt dieses Flag
>
> das wird wohl nichts. Wenn der Interrupt aktiv ist, dann kann die main
> nichts checken weil sie schläft.
Das ist auch wieder wahr. Allerdings kann die ISR markieren, wann sie 
fertig ist und das für die nächste Zeit der Speicher frei ist.
#3247470
Lesenswert?

... schrieb:
> Interupt deaktivieren
> Speicher beschreiben
> Interrupt aktivieren???
> Dann würde die Interrupts wärend dieser Zeit flöten gehen.

Der Interrupt, der während dieser Zeit auftritt, wird dann anschließend 
(zeitlich verschoben) ausgeführt.
Nur wenn es mehrere Interrupts während "Speicher beschreiben" auftreten, 
können welche verloren gehen.
Nur wenn das so ist, dann stimmt was an der Gesamt-Zeitbilanz nicht: Du 
willst häufiger die Daten auf der LED-Matrix ausgeben als der Update des 
Speichers dauert. Das ist aber Unsinn, denn 2x dasselbe ausgeben kann 
man sich dann sparen...

Gruß Dietrich

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren