Forum: Mikrocontroller und Digitale Elektronik Gemeinsammer zugriff auf Speicher


von ... (Gast)


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

von Peter II (Gast)


Lesenswert?

... schrieb:
> Finde beide Möglichkeiten nicht so toll. Wie macht man es richtig?

2 Puffer verwenden und diese dann umschaltet.

von Walter T. (nicolas)


Lesenswert?

Soetwas schreit entweder nach

http://de.wikipedia.org/wiki/Doppelpufferung

oder Du sperrst den Interrupt, während geschrieben wird.

von Doppelpuffer (Gast)


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?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Der Interrupt kann auch ein Flag setzen, das er gerade aktiv ist, und 
main checkt dieses Flag. Wenn du Flimmern vermeiden willst, sollte ja 
der IRQ möglichst störungsfrei zünden und main sich zurückhalten. Hängt 
also von deinen Prioritäten ab.

von Peter II (Gast)


Lesenswert?

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.

von ... (Gast)


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!

von Karl H. (kbuchegg)


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.

von Peter D. (peda)


Lesenswert?

... schrieb:
> Es wird immer zuerst der komplette Speicher gelöscht

Das ist natürlich sichtbar, da das Main ja Zeit braucht zum neu 
schreiben.
Besser ist daher, einfach überschreiben ohne zu löschen.

von Peter II (Gast)


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.

von Karlo (Gast)


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()

von amateur (Gast)


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.

von Falk B. (falk)


Lesenswert?

Wie das mit dem Doppelpuffer und Zeigern funktioniert, sieht amn im 
Artikel Soft-PWM, 3. Beispiel.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


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.

von Dietrich L. (dietrichl)


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

von Peter II (Gast)


Lesenswert?

Dietrich L. schrieb:
> Das ist aber Unsinn, denn 2x dasselbe ausgeben kann
> man sich dann sparen...

die matrix muss ständig ausgeben werden sonst sieht man nichts.

von Dietrich L. (dietrichl)


Lesenswert?

Peter II schrieb:
> die matrix muss ständig ausgeben werden sonst sieht man nichts

Ok, ja, ich hatte einen Gedankenfehler :-(

Wenn also der Speicher-Update lange dauern kann, ist die Lösung mit 
"doppelter Speicher" wohl die einzig sinnvolle :-)

Gruß Dietrich

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.