Hallo
Ich habe mit 2 Atmega8515 auf einem Fernseher ein Bild (PAL über RGB,
192x144) dargestellt. Ein µC übernimmt das Timing: Er bekommt die Zeilen
von dem anderen µC und zeigt jede Zeile doppelt an, damit das Bild nicht
zu klein auf dem Fernseher angezeigt wird.
Der 2. µC ist für Grafikroutinen zuständig und hat dafür auch einen
externen Sram Während dem horizontalen Zeilenrücklauf wird die
übernächste Zeile zur Hälfte übertragen. Dafür bleiben nur 320 Takte
übrig. Die beiden µC werden von einem Quarz (22Mhz) versorgt, damit sie
Synchron arbeiten. Wenn die nächste Zeile übertragen wird,
synchronisieren sie sich über 2 ext. Interrupte. Darauf liest der
Grafik-µC 96 Pixel (Bytes) aus seinem Ram und der andere empfängt sie:
Grafik-µC:
1
.org INT0addr
2
push ZH
3
push ZL
4
push temp
5
6
;Synchronisieren
7
cbi PORTD, 4
8
9
;Nach 6 Takten liest der andere µC die Pixel ein
10
lds ZL, PixelPosL
11
lds ZH, PixelPosH
12
write_line2:
13
out32
14
out32
15
out32
16
sts PixelPosH, ZH
17
sts PixelPosL, ZL
18
sbi PORTD, 4
19
pop temp
20
pop ZL
21
pop ZH
22
reti
out32 ist ein Makro für 32x
1
ld temp, Z+
Wobei Z aus dem externen Sram liest.
Der andere µC liest die Daten einfach ein:
1
.org INT0addr
2
rjmp read
3
...
4
5
read:
6
in temp, PINC
7
st Z+, temp
8
in temp, PINC
9
st Z+, temp
10
...
Da dieser nur internes Ram hat, dauert der st-Befehl nur 2 Takte.
Der ganze Code funktioniert auch, allerdings wandert sehr selten (man
muss manchmal eine viertel Stunde oder länger warten) ein Balken durch
das Bild. Meistens 2 mal hintereinander - danach passiert wieder lange
nichts mehr.
Woran könnte das liegen? Liegt es vielleicht an dem Steckbrettaufbau?
Das Timing ist schließlich ziemlich kritisch. Würde es etwas bringen
einen Puffer (74HC574) zwischen die µCs zu schalten?
Samuel K. schrieb:> ein Balken durch> das Bild.
Was für ein Balken, wie schnell? So ein Flimmern wie (früher) beim
Abfilmen vom TV? Dann wäre es vermutlich eine Störung in der
Bildfrequenz, evtl. 'nur' ein paar Takte je Bildschirmseite zuviel oder
zuwenig.
Wenn's eine Störung in den Pixeln ist, dann könnte es hier dran liegen:
> ;Nach 6 Takten liest der andere µC die Pixel ein
Das stimmt so nicht, du hast bis zu 2 Takte Jitter, da du nicht sicher
weißt, bei welchem Opcode der IRQ ausgelöst wird. Auch wird das
Eingang-Latch einen halben Takt vor dem in-Opcode geschlossen.
Grüße
Mark
Ein Vertikaler Balken wandert mit einer geschätzten Geschwindigkeit von
20-30cm / s durch das Bild. Nach gut einer Sekunde ist der Balken wieder
verschwunden.
Mark L. schrieb:> Das stimmt so nicht, du hast bis zu 2 Takte Jitter, da du nicht sicher> weißt, bei welchem Opcode der IRQ ausgelöst wird.
Das hatte ich vergessen zu schreiben: Einen Jitter gibt es nicht, da der
µC (der an den Fernseher angeschlossen ist) vor jedem Interrupt in eine
nop Sequenz springt. Beim Grafik-µC gibt es einen Jitter, deswegen muss
er 6 Takte vor dem Übertragen einen Interrupt beim anderen µC auslösen.
> Auch wird das> Eingang-Latch einen halben Takt vor dem in-Opcode geschlossen.
Das stimmt. Das Lesen eines Bytes aus dem externen Ram dauert 3 Takte.
Es gibt eigentlich nur die Möglichkeit beim 3. Takt das nächste Byte
einzulesen.
Das könnte das Problem sein.
Ich habe gerade im Datenblatt gelesen, dass das XMEM Interface Asynchron
arbeitet. Allerdings muss der Interface spätestens am Ende der 3 Takte,
den Wert gelesen haben. Wenn ich den Takt des einen µCs invertiere, dann
müsste der Wert eigentlich immer richtig gelesen werden. Der Buskeeper
muss dafür natürlich aktiviert werden.
Das blöde an dem Fehler ist, dass er kaum reproduzierbar ist. Daher ist
es schwer seine Ursache zu finden.
Die Notlösung wäre ein nop mit Buskeeper zum Auslesen, das sollte
aufjedenfall funktionieren, kostet aber ein Takt.
Ich hatte gerade Glück und konnte die Streifen aufnehmen. Wie man sieht
sind sie bläulich und nicht weiß wie der Testpunkt der auf dem
Bildschirm wandert.
Das könnte auch gut ein Zähler- oder Stackfehler bei deinen
Grafikroutinen sein.
Ich habe hier selbst gerade 3(eigentlich sogar 4)
synchronisierte/parallel arbeitende AVRs mit Video. Langfristig stabil
läuft das nur mit 1 Takt 'Spiel'. Es passt zwar rechnerisch, es läuft
stabil, aber irgendwann treten Fehler auf. Weiß nicht, ob das korrekt
ist, aber wenn ich einplane, dass sich die Taktflanken im Betrieb im
ns-Bereich gegen einander verschieben, erklären sich die Fehler und die
Lösung.
Du könntest das aber umgehen, indem du beide AVRs an deinen Speicher
hängst, so wie in den 80ern üblich. Ist zwar ein größerer HW-Aufwand,
aber Synchronisationfehler würdest du so ausschließen.
Mark
Mark L. schrieb:> Du könntest das aber umgehen, indem du beide AVRs an deinen Speicher> hängst, so wie in den 80ern üblich. Ist zwar ein größerer HW-Aufwand,> aber Synchronisationfehler würdest du so ausschließen.
Daran hab ich auch schon gedacht, allerdings braucht der µC dann zu
lange um die Zeilen zu lesen (3 Takte um aus dem Sram zu lesen, 2 um in
den internen zu speichern).
Stackfehler schließe ich im Zeilen-µC aus, da dieser ohne Stack
arbeitet: Nach jedem Interrupt nehme ich die Rücksprungadresse vom Stack
runter und springe in eine nop Sequenz, damit es beim nächsten Interrupt
keinen Jitter gibt. Am liebsteb würde ich den Stackpointer deaktivieren.
Ich habe jetzt die 22 Mhz von einem 3. µC mit ClockOut erzeugen lassen.
Der Grafik-µC bekommt die 22Mhz direkt, der andere invertiert. Das ganze
funktioniert, allerdings scheinen die µCs sehr anfällig gegenüber einem
externen Takt zu sein: Erst nachdem der Taktgebende µC läuft darf ich
CKOUT zu den anderen µCs führen, sonst stürzen sie völlig ab. Manchmal
muss ich den Abblockkondensator raus- und wieder reinstecken, damit es
funktioniert. Leider hab ich kein Oszilloskop, sonst könnte ich das
genauer analysieren.