Forum: Projekte & Code AVR Videogenerator, 40x25 Zeichen, nur 60% CPU Auslastung !


von Benedikt (Gast)


Angehängte Dateien:

Lesenswert?

Das Programm erzeugt ein PAL ähnliches Videosignal aus Textdaten im
RAM:

- Das Hauptprogramm ist eine leere Endlosschleife, hier kann man also
beliebige Software einbauen, die bis zu 40% der CPU Leistung bekommt.
- Die Datenausgabe läuft im Interrupt, das Hauptrogramm hat damit also
nichts zu tun.
- Die Sync Impulse werden per Hardware erzeugt und sind absolut
stabil.
- Die Zeit während des Zeilen und Bildrücklaufs stehen also komplett
der Software im Hauptprogramm zur Verfügung.

von Bernhard S. (bernhard)


Lesenswert?

Hallo Benedikt

Respekt !!

Dein Programmcode ist wirklich sehr kurz, gefällt mir.


Bernhard

von Benedikt (Gast)


Lesenswert?

Ist auch immerhin schon die 3. Version die eigentlich komplett neu
geschrieben wurde. Insgesamt stecken da bestimmt schon >100h Arbeit
dahinter.
Irgendwann baue ich da noch "Big Numbers" ein, die gefallen mir bei
deiner Software. Allerdings setze ich diese aus einzelnen Buchstaben
als Pixel zusammen. Dazu definiere ich noch einige Sonderzeichen (3ecke
usw), da der ASCII Bereich <32 sowiso keine sinnvollen Zeichen bietet.
Das sollte dann schöne Zahlen aus je 4x4 Buchstaben ergeben.

von Bernhard S. (bernhard)


Lesenswert?

>Insgesamt stecken da bestimmt schon >100h Arbeit dahinter.

Bei mir ebenso,

hab' gerade mal in Deinen Thread geschaut

http://www.mikrocontroller.net/forum/read-1-290388.html

Dort stellte ich meine erste peinliche Frage, das war vor ca. 4Wochen.

Dein Thread inspirierte mich nicht nur, sondern half mir auch weiter.


>Irgendwann baue ich da noch "Big Numbers" ein, die gefallen mir bei
>deiner Software

Ja ja, die "Super Big Numbers" , die haben Ihre Vorteile, besonders
bei Präsentationen ;)





Bernhard

von Christian D. (Gast)


Lesenswert?

Hallo,
echt super Projekt, hab ich mir nachgebaut ;)
nun klappt auch alles, jedoch weis ich nicht wie ich die Ausgabe auf dem 
TV Formatieren kann, also z.b. Text Zentrieren oder den Bildschirminhalt 
löschen, oder in eine Bestimmte Zeile springen, das müsste doch 
irgendwie möglich sein?

gruß Christian D.

von Benedikt K. (benedikt)


Angehängte Dateien:

Lesenswert?

Mit der bisherigen Version geht das nicht, aber mit der Version im 
Anhang sollte das möglich sein.

von Christian B. (casandro)


Angehängte Dateien:

Lesenswert?

Ich hab da was relativ ähnliches gemacht, nur bin ich schon recht früh 
auf den ATMega16 umgestiegen.

Die Idee mit dem SPI ist schon sehr schick. Ich habe das noch mit 
Schiebebefehlen erledigt. Nur schade, dass der SPI nicht auch mit einer 
höheren Taktrate laufen kann.

Das mit der Jitterkorrektur ist auch toll.

Mein ähnliches Projekt ist hier:
Beitrag "Bild und Ton mit ATMega16"
Es funzt aber nur auf dem ATMega16 weil mein Programm inzwischen zu groß 
geworden ist.

Es hoffe es stört Dich nicht wenn ich den Algorithmus unter 
Namensnennung in mein kleines GPL-Projekt übernehme. Du kannst ja auch 
meinen Tonerzeuger übernehmen.

von Christian B. (casandro)


Lesenswert?

Farbe müsste übrigens, ganz grob skizziert so gehen:


hloop:                                          ;Loop f<FC>r 1 Zeile
        ld ZL, X+                               ;ASCII aus RAM lesen 
2
        lpm tempi, Z                    ;Byte aus CGROM lesen   3
        SBRC tempi,7 ; Skip wenn Bit 7 nicht gesetzt
        OUT PORTC,tempi
        out DDRB, spiaus                ;SPI aus, Port an 
1
        out SPDR, tempi                 ;Byte ausgeben 
1
        out DDRB, spian                 ;SPI an, Port aus 
1


An die untersten Bits hängst Du dann eine Schaltung dran, die die Farbe 
macht. Die erhält 7 Bits, sowie das Ausgangsbit deines SPIs.
Die Farbe schaltest Du mit einem Byte im Speicher um, welches Bit 7 
gesetzt hat. Natürlich kannst Du das noch quasi beliebig verfeinern.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Kannst du kurz nen Schaltplan dazu zeichnen wie das ausehen müßte?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ach ja hat jemand das ganze schon für den Mega16 portiert?
Im Prinzip müßte amn doch nur die Pins für OCRA und für das SPI anpassen 
oer gibts noch mehr zu beachten?

von Christian B. (casandro)


Angehängte Dateien:

Lesenswert?

So etwa. Leider hat der ATMega8 nur einen Port C. (Port D benutzt du ja 
schon wahrscheinlich) Grob gesagt kommt in die einen 3 Bit die 
Vordergrundfarbe, in die anderen die Hintergrundfarbe.
Die Schaltung gibt dann RGB an den Ausgängen ganz rechts aus. Jedes 
neuere Farbfernsehgerät hat die entsprechenden Eingänge an der 
SCART-Buchse.

Möchtest Du PAL haben, so wird das etwas schwieriger. Du müsstest 
eventuell noch einen Port dafür opfern. Und Du bräuchtest einen 
Oszilator, der auf der Farbunterträgerfrequenz, oder einem Vielfachen 
dieser Frequenz schwingt.

von Christian B. (casandro)


Lesenswert?

Warum wird denn eigentlich so lange gewartet? Eigentlich könnte man doch 
das nächste Zeichen schon nach 16 Taktzyklen an das SPI schicken? Oder?

von Benedikt K. (benedikt)


Lesenswert?

Du meinst, wiso erst nach dem 18. Takt ein neues Byte rausgeschoben wird 
?
Das SPI Interface braucht leider 18 Takte. Schreibt man das Byte zu 
früh, wird es ignoriert.

von Christian B. (casandro)


Lesenswert?

Hmm, das lässt meine Träume von der perfekten Bildwiedergabe wieder 
platzen. Und wahrscheinlich ist das letzte Bit dann auch noch high und 
deshalb machst Du die Klimmzüge mit dem 2. Port. Naja, mit der 
Ausgangselektronik kann man ja deinen Port invertieren, so dass man high 
als Hintergrundfarbe hat.

Naja, mehr als mit meiner Lösung ginge jedenfalls.

von Benedikt K. (benedikt)


Lesenswert?

Genau so ist es.
Anfangs hatte ich deshalb einen Inverter dran, aber um Bauteile zu 
sparen schalte ich den Ausgang auf den anderen Port um.
Besser als mit einem AVR geht es mit einem ARM von Philips/NXP: Dieser 
besitzt eine 16bit SPI Schnittstelle die lückenlos Daten ausgibt. 
Zusätzlich gibt es noch ein FIFO. Durch die 16bit und das 8Word FIFO 
kann man auf einmal  128 Pixel schreiben die dann von alleine ausgegeben 
werden.

von Christian B. (casandro)


Lesenswert?

Man könnte eventuell sich Speicher sparen, in dem man ein 
"newline"-Zeichen einführt. Wird dieses Zeichen gelesen, so wird 
nachgeschaut, ob man denn in der letzten Zeile der Textzeile ist, wenn 
nein, so wird der aktuelle Zeilenstart zurückgesetzt, wenn ja, so lässt 
man die aktuelle Position auf dem nächsten Zeichen und springt aus der 
ISR. Im RAM hättest Du dann so etwas ähnliches wie eine Textdatei. 
Halbvolle Zeilen brauchen dann auch viel weniger Speicher.

Ich hoffe, dass ich im Februar dazu komme, da etwas rumzuspielen.
Was gehen sollte ist etwa das:
* 8 Vordergrund Farben
* 8 Hintergrund Farben
* Blinken
* Doppelte Höhe
* Doppelte Breite
* Benutzerdefinierte Zeichen

Grob gesagt sollte man einen kompletten "Videotext"-Dekoder damit machen 
können. (zumindest die Textdarstellung davon)

von Christian B. (casandro)


Lesenswert?

Naja, die ARM-Prozessoren wären da schon ziemlich schick, wobei man das 
dann da schon fast interruptgesteuert machen müsste. Der Vorteil an den 
Prozessoren ist dann halt, dass man auch gleich Linux darauf laufen 
lassen kann. :)

Und gut, wenn der SPI 9 Bit an Zeit braucht, dann machen wir halt einen 
9 Pixel Font. :)

von JanB (Gast)


Lesenswert?

Das SPI-Interface des Mega-8 und sicher auch das des Mega16 kann 
durchaus auch weniger als 8(9) Bits ausgeben. Du kannst die Übertragung 
z.B. nach 4 Bits abbrechen durch Abschalten des SPI. Und dann wieder 
Einschalten und ein neues Byte losschicken.
Kannst du hier sehen:
Beitrag "AVR ASCII Video Terminal  - 40 x 25  - BAS Signal"

Die Zeichen sind 6 Pixel breit und lückenlos.
Es ist ein 5x7 Zeichensatz.

Gruß Jan

von Christian B. (casandro)


Lesenswert?

Hmm, gut, dann gingen also doch 8 Pixel pro Zeichen. Mir geht es darum, 
dass ich eine Anzeige mit 320x240 Pixeln habe und darauf 40 Zeichen pro 
Zeile darstellen möchte. Eventuell 40x15 Zeichen mit einer schönen 8x16 
Schriftart.

von Benedikt K. (benedikt)


Lesenswert?

Die 8 Zeichen funktionieren nicht so richtig, man bekommt nach jedem 
Schiebevorgang eine Lücke, und zwar aus folgendem Grund:
Sagen wird mal man schaltet das SPI nach 16 Takten aus, und anschließend 
wieder ein, dann hat man 2 Tajte für das aus und einschalten benötigt.
Man benötigt also immer 2*n+2 Takte, egal ob mit oder ohen Ausschalten. 
Man kann so 6+1 Pixel darstellen, erhält aber nach dem 6. Pixel dann 
eine Lücke von 1 Pixel.
Das einzige was funktioniert: Das Interface nach 7 Takte ausschalten, 
und den 8. Pixel per Software auf den Port legen.

von Stephan H. (stephan-)


Lesenswert?

Jungs, macht doch das SPI zu Fuß ...
dann könnt Ihr die Zeichen ausgeben wie Ihr wollt.
4 Bit , 8 Bit , 9 Bit oder 21 Bit.
So schwer isses ja nich

von Benedikt K. (benedikt)


Lesenswert?

@stephan
Wenn du in der Lage bist ein Programm zu schreiben, dass jeden 2. CPU 
Takt ein Bit an einen Port legt, gleichzeitig noch alle 16Takte ein Byte 
aus dem RAM läd, dann dieses als Offset benutzt und so ein Byte aus dem 
Flash läd, ohne dass die Datenausgabe jeden 2. Takt unterbrochen wird, 
dann kannst du es  so machen. Wir können das aber nicht...

von Joerg W. (joergwolfram)


Lesenswert?

Wenn alle Pixel gleich breit sein sollen, braucht man 4 Takte je Pixel, 
braucht man nur reine Textdarstellung, kann man das lpm in den dunklen 
Zwischenraum legen und braucht nur 3 Takte je Pixel. Wenn man auch noch 
das  Laden aus dem RAM in den Zwischenraum legt, braucht man zwar nur 2 
Takte je Pixel, die Abstände sind aber dann so groß, dass mehrzeiliger 
Text nicht mehr angenehm lesbar ist.

von Stefan (Gast)


Lesenswert?

@ Benedikt

Ist zwar leicht offtopic, aber mich interessiert, wie man die 
CPU-Belastung ermitteln kann bzw. wie du auf 60%/40% gekommen bist. 
Kannst du da etwas drauf eingehen?

von Stefan (Gast)


Lesenswert?

Add: Andere sollen natürlich auch antworten ;-)

von Christian B. (casandro)


Lesenswert?

Stephan Henning wrote:
> Jungs, macht doch das SPI zu Fuß ...

So mach es ich im Moment. Das funktioniert recht gut. Man bräuchte 
jedoch 3 Taktzyklen pro Pixel um perfekte Pixel auszugeben. Meine Lösung 
braucht 17 Taktzyklen für 8 Pixel.

Der Vorteil an der SPI-Lösung ist aber, dass man sehr viele freie 
Taktzyklen hat. Man kann wirklich was machen und nicht nur einen Wert 
aus dem Speicher laden. In diesen Taktzyklen kann man Dinge wie Farbe 
unterbringen, oder auch andere Effekte.

von Joerg W. (joergwolfram)


Lesenswert?

Zum (ungefähren) Messen der CPU-Belastung ist es am einfachsten, zu 
Beginn der Interrupt-Routine einen Pin auf 1 zu setzen und vor dem RETI 
wieder zu löschen. Mit einem einfachen Vielfachinstrument die Spannung 
am Pin messen und mit 20 multiplizieren...

von Benedikt K. (benedikt)


Lesenswert?

Das mit dem Pin ist die einfachste Möglichkeit, so messe ich es auch 
meistens. In diesem Fall habe ich aber gerechnet:
Pro Bildzeile werden 45us lang Daten ausgegeben, das macht etwa  70% 
Aulastung.
Von den 312,5 verfügbaren Bildzeilen werden nur etwa 250 genutzt.  Das 
macht 20% nahezu komplette Freizeit für den uC (bis auf dem HSync). Dazu 
kommen nochmal die 30% Freizeit während der Bildausgabe. Macht also 
etwas über 40% Freizeit für den uC. Demzufolge hat der uC etwa 60% 
Auslastung.

von Stefan (Gast)


Lesenswert?

Vielen Dank!

Die 20 haben mich etwas stutzig gemacht. Die kommen von /5V *100% nach 
dem PWM-Prinzip (http://www.mikrocontroller.net/articles/PWM)

von Björn W. (bwieck)


Angehängte Dateien:

Lesenswert?

Hallo Benedikt

Wirklich super dein Videogenerator,
Leider für mich als Anfänger etwas sparsam dokumentiert ;)

Ich habe noch ein Carriage Return Funktion mit Reingebastelt.

von Björn W. (bwieck)


Angehängte Dateien:

Lesenswert?

Ups... Habe eine Verzweigung falsch geschrieben...

Hier die korrigierte Fassung

Grüße
Björn

von Björn W. (bwieck)


Angehängte Dateien:

Lesenswert?

noch ein paar Bugfixes..

Und die Cursorposition ist jetzt Sichtbar :)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Da ich leider gerade keinen Mega8 zur Hand hab das ganze aber doch mal 
gern Probieren wollte, mal meine Frage, was muss man tun um das ganze 
für den Mega16 anzupassen?

von Christian B. (casandro)


Lesenswert?

Läubi Mail@laeubi.de wrote:
> was muss man tun um das ganze
> für den Mega16 anzupassen?

Wahrscheinlich sehr wenig. Du musst nur bedenken, dass der die Pins wo 
anders hat.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ja also seh ich das richtig das nur die SPI Pins wichtig sind, der Rest 
halt Variabel? Weil zwei pins sind ja zusammengeschltet und mir ist 
nicht ganz klar ob da ein belibiger Pin genommen werden kann.

von Benedikt K. (benedikt)


Lesenswert?

Nur das SPI ist fest, SS sollte noch auf Ausgang stehen, der rest ist 
variabel.

von Björn W. (bwieck)


Angehängte Dateien:

Lesenswert?

Letzter Stand:
Das ganze ist jetzt ein brauchbarer Bildschirmeditor geworden.
Die Cursortasten werden jetzt auch abgefragt (VT100)
Weitere kleine Bugfixes und Optimierungen
Die Zeilen sind fast alle kommentiert

Danke Dir Benedikt, für dieses Projekt. Das ist zum Assemblerlernen für 
mich genau das richtige :)

Was ich noch plane:


Scrolling

Senden des Bildspeichers über UART (Hardcopy)

Befehlsinterpreter um die Ausgänge von Port B zu steuern oder den ADC 
auszulesen (...naja muss ich noch viel lernen)

Portierung auf Mega16

Grüße
Björn

von Christian B. (casandro)


Lesenswert?

Björn Wieck wrote:
> Was ich noch plane:

> Scrolling

Das mache ich über Zeiger, die auf die einzellnen Zeilen zeigen, dadurch 
muss ich nur wenige Bytes rumschieben.

> Senden des Bildspeichers über UART (Hardcopy)
>
> Befehlsinterpreter um die Ausgänge von Port B zu steuern oder den ADC
> auszulesen (...naja muss ich noch viel lernen)

Da gibts Forth Compiler für den ATMega 16.
Die laufen dann direkt auf der Kiste.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Habs jezt mal "portiert"...
Leider ist das Ergbniss nicht so überzeugend, frage liegt das an mir 
oder mag meine TVKarte das nicht so?

Habe im Quellcode aus tvtext.zip nur folgendes geändert:
;PortB
.equ   DOUT  =3
.equ   Sync  =5
.equ   MOSI  =5
.equ   MISO  =6
.equ   SCK  =7
Ansosnten mich an den Schaltplan gehalten, auser das ich nen 16mhz 
Ozilator benutze. (CLK FUses 0000 beim Mega16)

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Bild vergessen...

von Christian B. (casandro)


Lesenswert?

Läubi Mail@laeubi.de wrote:
> Habs jezt mal "portiert"...
> Leider ist das Ergbniss nicht so überzeugend, frage liegt das an mir
> oder mag meine TVKarte das nicht so?

Ich glaube dein Timing ist falsch.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Naja ich hab ja sosnt nix verändert an der Schaltung :(
Deswegen frag ich ja ob meine "portierung" so in Ordnung ist?

von Christian B. (casandro)


Lesenswert?

OK, dann überprüf das Bild mal mit einem normalen Videomonitor. Ist da 
das Problem auch so? TV-Karten sind in der Regel nicht wirklich für das 
geeignet. Du kannst aber auch probieren die TV-Karte bewusst auf PAL 
einzustellen.

Eigentlich sollte das Timing sich nicht durch die Portierung ändern. Die 
Controller sind sehr ähnlich.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Habe leider keinen Fernsehe... Habs mal an den Vidorecorder gehängt und 
dann über Antennenausgang auf die TVKarte... selbes Problem :(

von Benedikt K. (benedikt)


Lesenswert?

Wenn du Sync und MOSI auf den selben Pin legst ist das kein Wunder...

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ach ja schreiben ist schwer, dafür siehts jezt so aus.
immerhin schonmal nen Fortschritt... hab nochmal überprüft obs auf 
Externen Ozilator gestellt ist sieht in Ordnung aus... hm..

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

hab mal alle rjmp durch jmp ersezt... hat jezt leider auch nix bewirkt

von Benedikt K. (benedikt)


Lesenswert?

Beschreib mal die Schaltung die du verwendest hast (an welchem Pin hängt 
was und schreib nochmal die Belegung von PortB in der Software.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Okay.

- Mega16 mit normaler Beschaltung und 16Mhz Quarzozilator
- Softwareänderung
 ;PortB
 .equ   DOUT  =3
 .equ   Sync  =4
 .equ   MOSI  =5
 .equ   MISO  =6
 .equ   SCK  =7
- Hardware:
 Ein Chinchkabel zum Videorecorder AV-In
 ein 100 Ohm zwischen GND und Signal
 330 Ohm von Pin6 (PB5 MOSI) zum Signal
 1k Ohm von Pin5 (PB4 SS) zum Signal
 eine Brücke von Pin4 (PB3) zu PB5

Alles noch son bischen zusammengebastelt aufm Lochraster.

von Björn W. (bwieck)


Lesenswert?

Anscheinend sind der Mega8 und der Mega16 im Timing doch 
unterschiedlich.
Ich habe jetzt mal das ganze in einen Meag16 geflasht
Pinbelegung und .def wie bei Läubi und das Bild ist stark verzerrt und 
läuft durch...

Muss mal an den Widerständen experimentieren. Eventuell liegts ja daran

Grüße
Björn

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Vieleicht hab ich beim konvertieren auch einfach blödsinn gemacht oder 
irgenwas nicht beachtet BAS ist leider nicht mein Gebiet :-\

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Kann es ggf an den Timern liegen?
Wobei ja beide Timer1 bei Mega8 und Mega16 gleich sind (zumindest macht 
es den Anschein)

Ich hab sowieso nochmal zwei fragen zum code:

ldi temp, (1<<WGM12)|1 ;10bit PWM bei 16MHz: 15,625kHz

Sezt das nicht temp auf 0xFF ??

ldi temp, (1<<SPE)|(1<<MSTR)|(1<<CPHA)  ;fclk/2 Schiebetakt
out SPCR, temp          ;Enable SPI Slave, Interrupt
sbi SPSR, SPI2X

Ist der Kommentar bezgl des Interupts falsch?
Weil ja für SPI Interupt garkein Vektor exitiert!

von Christian B. (casandro)


Lesenswert?

Also, wenn ich mir das Bild noch einmal anschaue, glaube ich eher, dass 
irgendwie deine TV-Karte nicht richtig mit dem Signal zurechtkommt. Hast 
Du denn nicht irgendwo ein echtes Fernsehgerät?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Habs wie gesagt mal am Videorecorder gehabt --> selbes resultat, nur 
damit kann ich nicht so leicht ne Bildschirmphoto machen ;)
Björn Wieck hat ja das selbe Problem etwas weiter oben festgestellt, ein 
"echtes" Fernsehgerät besitze ich lieder nicht.

von Christian B. (casandro)


Lesenswert?

Ob das Signal durch den Videorekorder durch geht oder nicht, ist (fast) 
völlig irrelevant. Der macht nichts mit dem Signal. Vielleicht stimmen 
auch deine Pegel nicht. Bist Du sicher, dass deine Widerstände stimmen? 
Schalte mal in einem kleinen Testprogramm einfach einen Port ein und 
miss dann die Spannungen. Dabei sollte natürlich das Gerät noch 
angeschlossen sein.

Dann schalte deine TV-Karte fest auf PAL.

von Björn W. (bwieck)


Lesenswert?

Ich kann mir eigentlich nur vorstellen das es am Timing des Mega16 
liegt.
Ich habe mit exakt den gleichen Widerständen am Mega8 direkt auf einem 
Videomonitor (alter C64 Monitor) ein glasklares Bild...
Die Ausgangspegel sind ja eh bei beiden AVR´s gleich.

Desweiteren läuft mit dem Mega16 bei mir das Bild neben den Verzerrungen 
durch was direkt auf einen falschen VSync hinweist.

Könnte es was mit dem JTAG-Interface zu tun haben ?


Grüße
Björn

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

JTAG muss aus sein, sollte aber trozdem nicht das Shiftregsiter 
beinflussen, das liegt ja alles auf  PortB.
Und der Videorecorder Sezt das Signal doch um auf Antenne also ich glaub 
nicht das der das PAL Signal direkt auf den Antenneausgang schleift.
Und wie björn doch shcon erwähnte Mega8 --> Geht, Mega16 --> geht nicht. 
Frage ist halt warum! Und die WIderstände hab ich so wie oben im 
Schaltplan angegeben gewählt.

von Björn W. (bwieck)


Lesenswert?

Ich werde heute abend mal mit dem Oszilloskop nachschauen wie das Timing 
zwischen den beiden Megas aussieht. Die Ergebnisse mit Bildern stelle 
ich dann allerdings in den "µC & Elektronik" Bereich. Dort passt es 
besser.

Grüße
Björn

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Super! Ich schau dan da mal rein, werde auch nochmal ein bsichen mit dem 
Programm rumspielen ob sich was tut.

von Björn W. (bwieck)


Lesenswert?

Hallo Läubi,

Ich bin noch nicht dazu gekommen zu messen, allerdings habe ich mal auf 
die schnelle was anderes probiert:

Ich habe mal von PortB auf PortD umgeschwenkt weil wie bei Mega8 dann 
DOUT und SYNC an OC1A und OC1B liegen. MOSI kann ich so natürlich nicht 
benutzen und das hat dann zur Folge das ich keine Zeichenausgabe mehr 
habe weil die Pixeldaten für die Zeichengenerierung aus dem SPI 
Schieberegister kommen.
Benedikt möge hier was dazu sagen wenn ich falsch liege.

Aber was ich damit erreicht habe: Das Bild ist absolut Stabil und die 
Füllpixel werden richtig angezeigt. Das sollte Beleg genug sein um zu 
behaupten das das Timing am PortB des Mega16 anders ist.
Jetzt muss ich eigentlich nur noch einen Weg finden um MOSI wieder mit 
ins Boot zu bekommen und dabei die IRQ-Routine von Benedikt nicht 
allzusehr zu verbiegen (sonst passt das Timing auch nicht mehr).

Grüße
Björn

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Hallo Björn,

Danke für deine Mühen. Vieleicht weiß Bendikt ja auch wo man das Timing 
auf die Mega16 werte anpassen kann?
Ich hatte auch shcon etwas rumgepielt aber nur mit dem Ergebniss das es 
garnichtmehr ging :(
Oder man versucht deine Konfiguration und nimmt nur noch das MISO dazu?
Merkwürdig find ichs allerdings schon irgenwie...

von Christian B. (casandro)


Lesenswert?

Was ich jetzt eigentlich ganz naiv immer noch nicht verstehe. Wozu sind 
die Füllpixel gut? Wäre es denn nicht einfacher einfach dunkle Zeichen 
auf hellem Grund darzustellen und den SPI in den leeren Bildbereichen 
einfach auszuschalten?

von Benedikt K. (benedikt)


Lesenswert?

Wenn ich dazukomme probiere ich das ganze heute mal mit einem mega16 
aus.

Die Ausgabe von schwarzen auf weisen Zeichen wäre einfacher. Mir gefällt 
das aber nicht, und es ist nicht allzu schonend für den TV wenn er die 
ganze Zeit volles weiß darstellen soll.

von Christian B. (casandro)


Lesenswert?

Dem Fernsehgerät ist es ziemlich egal, wie Du die Zeichen darstellst, 
nur bewegen sollte sich halt was :)

von Christian B. (casandro)


Lesenswert?

Björn Wieck wrote:

> Ich habe mal von PortB auf PortD umgeschwenkt weil wie bei Mega8 dann

> Aber was ich damit erreicht habe: Das Bild ist absolut Stabil und die
> Füllpixel werden richtig angezeigt. Das sollte Beleg genug sein um zu
> behaupten das das Timing am PortB des Mega16 anders ist.

Moment, wenn das Fernsehgerät nicht richtig synchronisiert bedeutet dass 
noch längst nicht, dass da irgendwelches Timing von Ports falsch ist. 
Ich meine ein Port ist ein ziemlich einfaches Gebilde, das nicht einfach 
so Pulse zeitlich verschieben kann. Nach Deiner Beschreibung erscheint 
es mir viel wahrscheinlicher, dass Du deinen Port B einfach geschossen 
hast. Das geht ziemlich schnell und ist mir auch schon passiert. 
Seltsamerweise war das bei mir auch Port B.

von Benedikt K. (benedikt)


Angehängte Dateien:

Lesenswert?

Christian Berger wrote:
> Dem Fernsehgerät ist es ziemlich egal, wie Du die Zeichen darstellst,
> nur bewegen sollte sich halt was :)

Und genau das ist das Problem: Die Füllpixel sind immer an der selben 
Stelle und brennen daher ein !


So, hier die Software für mega16 und mega 8 (define ganz oben).
Das Problem lag am Sync Signal. Ich hatte nicht mehr daran gedacht, dass 
ich dieses per Hardware mittels OCR1B erzeuge. Beim mega16 muss man Sync 
daher an PD4 abholen.

von Christian B. (casandro)


Lesenswert?

Benedikt K. wrote:

> Und genau das ist das Problem: Die Füllpixel sind immer an der selben
> Stelle und brennen daher ein !

Theoretisch ja, aber in der Praxis sind die Bildröhren jedoch so 
ungenau, dass diese Füllpixel immer an anderen Stellen sind. Schau Dir 
nur mal einen Fernsehsender mit Logo an. Das Logo bewegt sich mit 
wechselnder Bildhelligkeit. Nebenbei ist das Einbrennen heute kaum mehr 
ein Problem. Es wird nur dann ein Problem, wenn Du über Tage hinweg ohne 
Unterbrechung präzise das gleiche Bild darstellst.

> So, hier die Software für mega16 und mega 8 (define ganz oben).
> Das Problem lag am Sync Signal. Ich hatte nicht mehr daran gedacht, dass
> ich dieses per Hardware mittels OCR1B erzeuge. Beim mega16 muss man Sync
> daher an PD4 abholen.

Ohh, an das habe ich auch schon gedacht, der Fehler erschien mir aber zu 
simpel. :)

von Björn W. (bwieck)


Lesenswert?

Benedikt K. wrote:

> So, hier die Software für mega16 und mega 8 (define ganz oben).
> Das Problem lag am Sync Signal. Ich hatte nicht mehr daran gedacht, dass
> ich dieses per Hardware mittels OCR1B erzeuge. Beim mega16 muss man Sync
> daher an PD4 abholen.


Jaa, genau sowas habe ich auch schon vermutet und deswegen mal testweise 
PortD (eben wegen OCR1) benutzt...

Danke für den Code.

Grüße
Björn

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

SUPER! Probier ich gleich nachm Einkaufen mal aus :)

von Läubi .. (laeubi) Benutzerseite


Angehängte Dateien:

Lesenswert?

ES GEHT!!! Super danke für die Mühen, das rockt echt :)
Sieht zwra auf dem capture etwas verauscht aus, aber das ist wohl weil 
ich nur ein halbbild digitalisieren.
Aufjedenfall ist das Bild stabil und lesbar.

von Christian B. (casandro)


Lesenswert?

Läubi Mail@laeubi.de wrote:
> Sieht zwra auf dem capture etwas verauscht aus, aber das ist wohl weil
> ich nur ein halbbild digitalisieren.

Nein, das liegt daran, dass dein Computer meint, da sei ein Farbsignal 
und somit versucht ein nicht-existentes Farbsignal zu demodulieren. Ich 
tippe mal darauf, dass Deine Karte auf SECAM steht. Stell die auf PAL 
und probier es erneut.

von Sigint 112 (sigint)


Lesenswert?

Hallo zusammen,
  erstmal ein RIESEN Lob an alle aktiven Programmierer. Die Bilder sehen 
ja echt super aus... ich hoffe das Programm bald selbst testen zu 
können.
Was ich echt unglaublich finde ist die geringe Codemenge... der meiste 
Speicher wird ja vom CGROM belegt. Nun zu meiner Frage (ich traue mich 
kaum zu fragen):
  Wäre es denkbar, daß der interne 8MHz Taktgeber vom Tiny2313 genau 
genug für das Programm ist? Wenn ich das richtig gesehen habe (ich hab 
nur kurz in die Datenblätter geschaut) dann sind die Timer1 bei beiden 
Controllern identisch, oder?
Wenn ich also das CGROM etwas kürzen würde, dann sollte mit anpassung 
des Timings das Programm doch auch mit einem Tiny2313 mit internem Takt 
laufen.
Leider kenn ich mich mit Videosignalen nicht gut aus und hoffe ihr könnt 
mir ein paar kurze Tipps geben, wo ich einen Denkfehler habe... oder ob 
das eventuell doch geht.
Schonmal Vielen Dank und


Gruß,
  SIGINT

von Christian B. (casandro)


Lesenswert?

Sigint 112 wrote:

> Wenn ich also das CGROM etwas kürzen würde, dann sollte mit anpassung
> des Timings das Programm doch auch mit einem Tiny2313 mit internem Takt
> laufen.

Hmm, erstmal gingen da nur 20 Zeichen pro Zeile bei 8 MHz. Die sollte 
man aber machen können. Der Tiny2313 hat aber leider keinen SPI.
http://www.atmel.com/dyn/products/product_card.asp?part_id=3229
Allerdings sollte man den USI auch so nutzen können. Das größere Problem 
ist, dass Du nur 128 Bytes an RAM hast. Das kannst du aber mit 
geschickteren Befehlen prinzipiell auch noch machen.

Übrigens ich habe vor mal etwas mit dem ATtiny 11 zu spielen. Das ist 
ein kleines Teil. :)

von Benedikt K. (benedikt)


Lesenswert?

Ich würde den tiny11 nicht verwenden: Der tiny25/45/85 ist der größe 
8pinner mit vielen Features. Der tiny11 dagegen hat nichtmal ISP...

Mit dem tiny85 mit 512Bytes RAM und PLL (also 16MHz internem Takt) kann 
man mit ein paar Tricks sicher auch was schönes machen. Zumindest für 
30x15 Zeichen sollte der reichen. Allerdings bringt eine Textdarstellung 
nicht wirklich viel, da es kein Inteface gibt mit dem man den Text da 
reinbekommt. Nur der ADC wäre als Eingang brauchbar. Aber das wär doch 
mal was: Ein TV-Oszilloskop das nur aus einem 8Pin AVR und ein paar 
Widerständen besteht.

Die Timer sind übrigends nicht wirklich gleich: Selbst zwischen mega8 
und mega16 gibt es Unterschiede bei den Timern: Laut Datenblatt wird 
beim einen bei PWM der Pin beim maximalen Wert gesetzt, beim anderen 
dagegen beim minimalen. Bemerkbar macht sich der eine Takt aber nicht.

von Christian B. (casandro)


Lesenswert?

Ja, aber die sind relativ teuer. Der Tiny11 kostet halt nur 60 cent. Das 
kann ich mir selbst als Student noch leisten. Ich habe es gerade 
durchgespielt für 2x4 "7-Segment"-Anzeigen auf dem Bildschirm sollte der 
völlig reichen.

Und so etwas wie serielle Schnittstellen kann man auch so nebenher 
emulieren. :)

Auf dem 85ger geht wahrscheinlich dein Trick mit der PWM nicht so 
elegant. Der hat nur 2 8Bit Timer.

Um ein Osziloskopbild auszugeben bräuchte man wohl etwa 7 Taktzyklen pro 
Pixel. (wenn man das Bild nicht um 90 Grad dreht) Der Code wäre etwa so:

LD r1,X+  ;Wert für aktuelle Spalte holen 2
CP r1,r2  ;Mit Wert für Zeile vergleichen
LD r3,r4  ;r4 enthält Farbe für ungleich
Skip_if_equal  ;Zu faul Befehl zu suchen, evtl breq oder sowas
LD r3,r5  ;Farbe für gleich
OUT ,r3

Das schreibst du dann entweder 100 mal rein, oder benutzt eine Schleife.

von Sigint 112 (sigint)


Lesenswert?

@Christian:
   Uiii, hab ganz übersehen, daß der Tiny kein SPI hat... aber laut 
AVR319 kann man den USI als SPI nutzen. (könnte also gehen)
Das der Tiny etwas wenig RAM hat ist klar... ich wollte auch nur 4 
Zeilen a 20 Zeichen darstellen. Ich werd mich dann irgendwann mal mit 
dem Code auseinandersetzen und schauen,ob ich das irgendwie abgeändert 
bekomme.
Bei Fragen weiss ich ja, wo ich mich melden kann ;)

@Benedikt:
  Das mit dem Oszilloskop mit nem 8pin AVR würde mir echt gefallen... da 
könnte man echt schöne Spielerreien mit machen :)))

Gruß,
  SIGINT

von Benedikt K. (benedikt)


Lesenswert?

Ich hab das Oszi mal programmiert. In der kurzen Version besteht es aus 
etwa 100Befehlen (200Bytes) und hat 80x256 Pixel Auflösung.
In der schnellen Version sind 120x256 Pixel Auflösung möglich, der 
tiny25 ist  nahezu voll.
Das ganze funktioniert eigentlich wunderbar, Samplerate ist 15,625kHz, 
allerdings werden eben nur die Samplepunkte dargestellt, aber nicht die 
Linien dazwischen, was bei Frequenzen >1kHz etwas komisch aussieht.

von Christian B. (casandro)


Lesenswert?

Benedikt K. wrote:
> Das ganze funktioniert eigentlich wunderbar, Samplerate ist 15,625kHz,
> allerdings werden eben nur die Samplepunkte dargestellt, aber nicht die
> Linien dazwischen, was bei Frequenzen >1kHz etwas komisch aussieht.

Also zumindest mit den ATMegas sollte man locker die vollen 666 kHz 
Abtastrate schaffen. Eventuell kannst Du einfach mehr Abtasten als Du 
benötigst und dann darin den Triggerwert finden.

von Benedikt K. (benedikt)


Lesenswert?

Christian Berger wrote:
> Also zumindest mit den ATMegas sollte man locker die vollen 666 kHz
> Abtastrate schaffen.

666kHz Samplerate und gleichzeitig ein TV Bild erzeugen ?
Wie das ?

von Christian B. (casandro)


Lesenswert?

Benedikt K. wrote:
> 666kHz Samplerate und gleichzeitig ein TV Bild erzeugen ?
> Wie das ?

Du tastest einfach während der Bereiche des Bildes ab, in denen Du kein 
Bild ausgibst. Die Synchronimpulse werden sowieso durch die PWM 
generiert, nur die aktuelle Zeile müsstest Du anders zählen. (z.Bsp. 2. 
Timer)

Alternativ kannst Du auch etwas weniger Abtastrate erreichen, wenn Du 
bei deinen NOPs im Bildaufbau abtastest.

von Benedikt K. (benedikt)


Lesenswert?

Aber wie willst mit dem ADC vom AVR 666kS/s erreichen ?

von Christian B. (casandro)


Lesenswert?

Benedikt K. wrote:
> Aber wie willst mit dem ADC vom AVR 666kS/s erreichen ?

Das ist, soweit wie ich gehört habe, die maximale Samplingrate, die er 
kann. Allerdings wird er dabei ungenau, so dass Du die 10 Bit nicht mehr 
nutzen kannst.

von Benedikt K. (benedikt)


Lesenswert?

Bei 666kHz kann man die Messwerte eigentlich wegwerfen. 8bit sind bis 
etwa 50kHz möglich.

von Christian B. (casandro)


Lesenswert?

Hmm, ich hab vor das eventuell mal auszuprobieren. Ein Videoeingang für 
den Rechner wäre schon geil. :)

von Benedikt K. (benedikt)


Lesenswert?

Ein Videosignal digitalisieren wird nicht so ganz funktionieren. Mit 
einem ADS830 (recht günstig bei Reichelt) ist das ganze aber möglich. 
Die Schwachstelle ist nur die Verarbeitung der 15Mbyte/s.

Den ADC eines AVRs nutzte ich meist nur bis etwa 30-40kHz. Darüber nimmt 
die Qualität schnell ab. Bei >100kHz Samplerate sieht ein Sinus schon 
stark verzerrt aus.

von Christian B. (casandro)


Lesenswert?

Ich will ja keine perfekten QCIF Bilder haben. Mir würde schon das 
reichen, was der SPI gleichzeitig mit der Bildausgabe einlesen kann.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Mal ne Frage angenommen man hätte nen AVR mit "unendlich" viel SRAM 
welche Grafikauflösung könnte man da ereichen mit diesem AUfbau hat da 
jemand ne ungefähre übersicht? Also das man halt richtige Pixelgrafiken 
darstellen würde anstelle nur Characters, soweit ich das mitbekommen hab 
ist das ja aufgrund des geringen SRAMS des Mega8/16 nicht anders möglich 
(aber der mega32 hätte ja bspw schonmal 2k SRAM)

von Christian B. (casandro)


Lesenswert?

Also ohne Tricks wie dass Du direkt eine Leitung vom RAM zum DA-Wandler 
legst kannst Du etwa 320 Pixel pro Zeile darstellen, maximal. Mit 
externen Schieberegister gingen bis hin zu 1704, da wäre aber auch ein 
VGA-Ausgang mit etwa 800 Pixeln möglich. Das alles sind natürlich nur 
grobe Richtwerte.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Ich mein die einfach version mit den drei Widerständen und dem internem 
SPI

von Christian B. (casandro)


Lesenswert?

In der einfachen Version sind 320 Pixel pro Zeile möglich. Da hast Du 
aber kleine Zwischenräume nach allen 8 Pixeln. Mit etwas mehr Aufwand 
kann man die aber auch rausbekommen. An Zeilen kannst Du so viel machen, 
wie dein Monitor kann. Das sind 288 sichtbare Zeilen in der Gerber Norm, 
doppelt so viel wenn Du die Zeilenverflechtung ausnutzt.

von Benedikt K. (benedikt)


Lesenswert?

Christian Berger wrote:
> In der einfachen Version sind 320 Pixel pro Zeile möglich.
Nein:
Es sind 8MHz Schiebetakt möglich. Bei 54µs pro Zeile macht das 432 Pixel 
pro Zeile. Den 9. Pixel müsste man per Software nachliefern, das müsste 
auch funktionieren, wenn man für 9Pixel 2Bytes reserviert.
Wenn man ein volles Interlaced Bild erstellt, macht das 432x576 Pixel 
die theoretisch mit einem mega8515 und externem SRAM möglich sind.
Wenn man den AVR übertaktet natürlich mehr.

In diesem Fall würde ich aber zu einem ARM mit 32kByte internem RAM 
greifen.

von Christian B. (casandro)


Lesenswert?

Naja, theoretisch könnte man auch mehr als die 54 µs nehmen. So genau 
sind die ja nicht definiert, bzw es hält sich sowieso niemand daran. :)
Mit den 8MHz Schiebetakt hast Du natürlich recht.

Aber, und jetzt kommts, man muss ja die Zeichen nicht unbedingt durch 
Schieben darstellen. :) In Spezialfällen kann man tadsächlich einen 
Pixel pro Taktzyklus machen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Frage ist halt wieviel so ein ARM kostet und ob er noch lötfreundlich 
verfügbar ist (SOIC o.ä) bei ARM kenn ich mich leider so überhauptnicht 
aus.
Meine "Idee" war halt einfach das man eine AVR+Externes SRAM hernimmt 
der sich nur um die Darstellung auf dem TVMonitor kümmert, und halt wie 
bei dir per UART oder I²C neue Daten erhält. Halt im Prinzip eine "TV 
Grafikkarte" für µC ;)

von Sigint 112 (sigint)


Lesenswert?

@Läubi:
  Ich hab mich noch nicht mit ARMs beschäfftigt... aber schon mal ein 
paar Unterlagen durchgeschaut. Preislich sind die ARM7 meiner Meinung 
nach schwer zu schlagen: Bei Reichelt gibts die für ein paar Euronen. 
(LPC2119 für etwas mehr als 10Euronen) Was soll man zum Thema Leistung 
sagen: 60MHz, 128kiB Flash, 16kiB SRAM, mehr als genug IO, jede Menge 
Features... das einzige Problem ist bei den ARM immer das Gehäuse: 
LQFP-64 ... dafür muss man erstmal die Platine herstellen können. Löten 
dürfte mit einem SMD-Lötkolben noch gerade so gehen. Wenn es den ARM7 
Kern im DIL gehäuse gäbe wäre ich schon längst zum ARM gewechselt. 
Immerhin gibts dafür auch Linux ;)

@Benedikt:
  Mir wären 320x288 schon ausreichend... leider scheitert es bei kleinen 
AVRs immer am Speicher. Leider besitzen nur bestimmte AVR ein externes 
Speicherinterface.
Noch ne andere Frage: Hast du ein paar Screenshots von deinem 
AVR-TV-Oszilloskop... mich würde es interessieren, inwiefern das Teil 
brauchbar für Audio-Visualisierung ist.
Und noch eine Idee:  Wäre es nicht auch machbar eine FFT mit deinen 
Routinen zu verknüpfen und ein einfaches Audio-Spektrum 
darzustellen?!?!?
Eine FFT hat ja schon jemand mit dem ATmega8 realsisiert:
http://elm-chan.org/works/akilcd/report_e.html

Gruß,
  SIGINT

von Benedikt K. (benedikt)


Lesenswert?

Christian Berger wrote:
> Naja, theoretisch könnte man auch mehr als die 54 µs nehmen. So genau
> sind die ja nicht definiert, bzw es hält sich sowieso niemand daran. :)

Doch: Die sind definiert. Und zwar als sichtbarer Bildbereich. Wenn man 
die Zeit vergrößert, dann sieht man nichts mehr. Wobei aufgrund von 
Overscan die meisten TVs nur etwa 45-50µs darstellen.


Zum Thema ARM: Ich habe schonmal damit gespielt. Als DSP Ersatz taugen 
die nicht wirklich, und für IO Ansteuerung sind die auch gerade mal 2-3x 
schneller als AVRs, obwohl die mit 70MHz laufen. Aber als CPU für 
komplexere Aufgaben sind die wunderbar zu gebrauchen. Dank dem Sendefifo 
bei der SPI Schnittstelle kann man wunderbar hochauflösende TV Bilder 
erzeugen. Das 0,5mm Raster läst sich noch einigermaßen löten und ätzen. 
Mit etwas Übung ist das zu schaffen.

@sigint
Mit 2x mega8 habe ich das ganze schon gemacht:
Ein mega8 arbeitet als TV Controller und erzeugt 40 Balken mit 0-256 
Pixel Höhe, der zweite macht die FFT und schiebt die 40Bytes pro Paket 
an den anderen AVR rüber.
Als Audioscope ist das ganze nur für Frequenzen <1kHz brauchbar, 
ansonsten kann man aufgrund der vielen verstreuten Punke die Linie nicht 
mehr erkennen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Benedikt K. wrote:
> pro Zeile. Den 9. Pixel müsste man per Software nachliefern, das müsste
> auch funktionieren, wenn man für 9Pixel 2Bytes reserviert.
Also meinst du das man zwei bytes per SPI rauschiebt, aber beim zweiten 
byte nur das erste bit sezt?


von Benedikt K. (benedikt)


Lesenswert?

Nicht ganz:
Das erste Byte ganz normal per SPI raus, vom zweiten das erste Bit per 
Software an einen anderen Pin und dann umschalten. Eben so wie ich es 
bisher mache, nur dass das 9.Bit dann eben einen sinnvollen Inhalt hat 
(statt schwarz bisher). Das 9.Bit dient nur dazu, um das Problem mit den 
18 Takten pro Byte von der SPI Schnittstelle zu umgehen.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

ah okay :)
Wenn ich im März mal wieder nen bischen Zeit hab wollt ich nämlich mal 
mit dem mega8515 und externem SRAM rumspielen, mal gucken ob ich das 
hinkriege ohne das alles explodiert :P

von Ulrich P. (uprinz)


Lesenswert?

Hi!

Wollte mich nur mal bedanken für diese niedliche Schaltung. Funktioniert 
hier perfekt an einem widescreen LCD mit CVBS Eingang. Mit geänderten 
Parametern laufen nun 45x29 Zeichen über den Bildschirm. Basis ist ein 
Mega32.

Aber an der Ausgangsstufe muss ich noch feilen. Ich denke, dass ein 
OpAmp da nicht schaden kann. Eine Schwebung von 1.5V auf einem Signal, 
dass nur ca. 1Vss haben sollte gefällt mir noch nicht so ganz. Aber ich 
habe auch nicht alle Widerstände passend da. Werde das mal noch 
optimnieren.

Gruß, Ulrich

von Benedikt K. (benedikt)


Lesenswert?

Schwebung ?

von Christian B. (casandro)


Lesenswert?

Schwebung?

Bist Du sicher, dass Du die Masse korrekt angeschlossen hast und dass 
dein Oszi auf DC steht?

von Ulrich P. (uprinz)


Angehängte Dateien:

Lesenswert?

Hihi...

Also, damit ihr mie glauibt, was ich sage und damit Ihr auch wisst, dass 
ich mit einem Oszi umgehen kann, hier mal ein Dump vom Oszi...

Aber ich habe auch das Problem, dass das LCD eine recht große Last am 
CVBS Ausgang ist. Ich kann nicht mit 75R oder 100R terminieren, da ich 
dann kein Bild mehr habe. Ein TV habe ich aber nicht getestet.

Aber ich mach mal weiter, ich muss das ganze nämlich auf eine andere 
Bildquelle aufsynchronisieren und dann beide Signale mischen. Ein 
Mischerbaustein kommt aber nicht in Frage, da diese alle nacheinander 
abgekündigt werden.

Gruß, Ulrich

von Ulrich P. (uprinz)


Angehängte Dateien:

Lesenswert?

So, hier mal ein Nachtrag.

Das LCD ist der Verursacher aller Probleme. Ich werde da wohl einen 
Buffer OP einsetzen müssen, wenn ich damit weiter machen möchte. An 47R 
( passende 75 oder 100R hatte ich gerade nicht zur Hand) und kein 
Monitor drann, dann sieht das Ganze erheblich besser aus.

Gruß, Ulrich

von Benedikt K. (benedikt)


Lesenswert?

Kann es sein, dass du Offset meinst ???

Wenn der LCD TV meint, dass er unbedingt ein Offset braucht ist das 
egal. Ein kleines DC Offset am Videoanschluss ist zulässig. Immerhin 
erzeugt der TV den Offset.
Die Terminierung ist übrigends OK. Wenn du nachrechnest, dann kommst du 
auf etwa 71Ohm, was nahe genug 75Ohm liegt (mit dem Innenwiderstand der 
Ports kommt man auf ziemlich genau 75Ohm.)

von Christian B. (casandro)


Lesenswert?

Ulrich P. wrote:

> Aber ich habe auch das Problem, dass das LCD eine recht große Last am
> CVBS Ausgang ist. Ich kann nicht mit 75R oder 100R terminieren, da ich
> dann kein Bild mehr habe. Ein TV habe ich aber nicht getestet.

75 Ohm sind ganz normal, die hat auch jedes (korrekte) Fernsehgerät. 
Einen Bufferverstärker brauchst Du da noch lange nicht.

von Thomas M. (thmo83)


Lesenswert?

Hallo zusammen,

ich habe den AVR-Videogenerator aufgebaut und mich würde interessieren 
warum die Baudrate-Variable 250000 hat? Ich habe sie auf 9600 erniedrigt 
dann habe ich erst eine Verbindung via RS232 bekommen. Gibt es bei der 
Software spezielle Steuerzeichen für z.B. Bildschirmlöschen, neue Zeile 
beginnen, etc.?
Und wie ist die RS232-Schnittstelle eingestellt in bezug auf Parity, 
...?

Gruß Thomas

von Ulrich P. (uprinz)


Lesenswert?

Hi!

Also die Baudrate hat bei mir in allen Bereichen funktioniert. Nur an 
einem USB-Seriell Dongle ging 250kB nicht. Habe es aus 
Kompatibilitätsgründen mit anderen Entwicklungskits auf 57600 Baud 
laufen. Schau mal, ob Deine Quarzeinstellungen, also die Fuses korrekt 
gesetzt sind.

Ich bin mir nicht mehr sicher, da ich einige dieser Zeichengeneratoren 
ausprobiert habe, aber ich glaube dieser hier hatte noch keine 
speziellen Steuerzeichen. Hatte da selber mal angefangen, das zu 
implementieren.

Leider auf einen anderen AVR, und an einem 16:9 LCD und ohne Kommentare, 
also wenn Du das haben willst, dann kann ich das hier hochladen.

Gruß, Ulrich

von Thomas M. (thmo83)


Lesenswert?

Hallo,
Achso dann hätte ich da noch lange probieren können... Die 
RS232-Verbindung war nach der Baudrate-Änderung kein Problem, ich wollte 
einfach mal den Bildschirm löschen usw. wie ich das bei anderen gesehen 
Programme habe und habe mich gewundert warum nichts passiert.

Wenn das ein Programm für den Mega16 ist, wäre das super dann müßte ich 
nichts am Quellcode ändern und könnts gleich ausprobieren. Wenn du's 
hochladen könntest wäre ich dir dankbar.

Gruß Thomas

von Ulrich P. (uprinz)


Angehängte Dateien:

Lesenswert?

Hi!

Ist nur ein Anfang, habe ein paar ESCape-Sequenzen eingefügt. Sollt mal 
ANSII Standard werden. Ist leider nicht viel dokumentiert, da aus 
Zeitmangel auf Pause gesetzt. Im Übrigen habe ich es auf einem ATmega32 
laufen, solltest das aber mit wenigen Handgriffen für einen ATmega16 zum 
laufen bringen.

Gruß, Ulrich

von valdo (Gast)


Lesenswert?

Hallo!
Ich weiß, daß du wirst miteinbezogen in das Projekt amForth…
Antwort: Du kannst PC AT Kayboard Treiber hinzufügen?

von Ulrich P. (uprinz)


Lesenswert?

Hi!

Ich habe momentan leider überhaupt keine Zeit und die Änderungen waren 
nur eine kleine Studie um herauszufinden, ob es sich für ein Amateurfunk 
TV-Relay als Text-Einblendung in ein vorhandenes Video-Signal eignet. In 
einigen Wochen kann ich mich damit noch einmal beschäftigen.

As I think that your question was software-translated I'll answer in 
english too...
Actually I don't have any time at all for that. Initially it was only a 
trial to find out if the given solution can be used for an amateur radio 
tv relay for text overlay on a given video signal. I need a few weeks to 
get back to this project again.

Grüße / regards
Ulrich

von Casandro (Gast)


Lesenswert?

Also ich habe mir schonmal überlegt da was mit AMforth zu machen, bin da 
aber noch nicht weitergekommen.

von Ulrich P. (uprinz)


Lesenswert?

Die Software muss/sollte in Assembler geschrieben werden, da das Timing 
für das Video-Signal in Software realisiert ist. Natürlich kann man den 
logistischen Teil, also Zeichensteuerung, ESC-Sequenz-Erkennung u.s.w. 
in C oder einer anderen Sprache gemacht werden. Aber das ATmega ist mit 
dem Video-Timing schon sehr ausgelastet und jeder Overhead, und sei er 
noch so klein, der durch eine Hochsprache dazu kommen kann, ist störend.

Ich habe die einfachen Sequenzen aber hier auch in C gemacht. Es war nur 
ein Test auf Verwendbarkeit und scheiterte an nicht vorhandener Zeit. In 
meinem Fall ist es nämlich so, dass das Video-Signal auf das einer 
Camera synchronisiert werden muss, in das der Text das eingeblendet 
wird. Fällt die Camera aus, muss das Modul das Signal eigenständig 
erzeugen.

Gängige TV-Text Chips laufen leider aus oder sind jetzt schon nur noch 
als Altware zu bekommen. Einige noch lieferbare Chips können nicht aktiv 
ein Videosignal erzeugen, andere nur RGB aber kein CVBS. Es ist auch 
kein Wunder, da diese Funktion in die restlichen Bausteine eines 
TV-Chipsets hineingewandert ist. Die Zeiten als TV-Text noch als teures 
Zusatzmodul verkauft wurde sind vorbei.

Zielsetzung war ein TV-Text-Modul, dass nicht aus speziellen Chips 
besteht und daher leicht nachgebaut und auch modifiziert werden kann. 
Eine Lösung auf Basis eines ATmegas wäre da ideal gewesen. Ich hatte 
aber noch keine Zeit einen Sync auf ein bestehendes CVBS Signal 
hinzuzufügen.

Gruß, Ulrich

von Christian B. (casandro)


Lesenswert?

Naja, wenn Du "hochauflösenden Text", sprich 40x25 machen willst, musst 
Du den Controller per Genlock an das Videosignal anpassen.

Dazu erzeugst Du aus dem horizontalen Synchronsignal 16 MHz, in dem Du 
es um den Faktor 1024 erhöhst. Ein PLL macht das relativ einfach.
Dadurch ist sichergestellt, dass jede Zeile genau 1024 Taktzyklen 
dauert. Dein Controller läuft dann phasenstarr mit dem Videosignal.
Der Fehler des Zeitablaufes ist dann fest und verändert sich nicht mehr. 
Dein Bild wäre schon stabil, nur auf der falschen Stelle.

Mit einem Chip wie dem LM1881 kannst Du relativ einfach die Komponenten 
des Synchronsignals trennen. Ein Signal, welches einmal pro Zeile 
auftritt (z.Bsp  'Burst'-Ausgang des LM1881) führst Du dann an den 
Controller. Hat dieser die Möglichkeit einen Timerwert bei einem 
Ereigniss auf einem externen Pin festzuhalten so nutze die. Du wirst 
dann feststellen, wo, im Verhältniss zu deinem Timer, der Sync-Puls des 
externen Videosignals ist. Somit kannst Du gelegentlich deinen 
Zeitablauf abgleichen.

Zu guter Letzt kannst Du noch ein V-Sync Signal bei jedem Bildwechsel in 
den Controller einspeisen, so dass er auch weiß, wann er ein neues Bild 
anfangen soll.

Prinzipiell kannst Du auch den PLL softwaregestützt machen, aber ich 
weiß nicht, wie gut das geht.

Wenn Du nur grobe Einblendungen machen möchtest, so kannst Du auch den 
PLL komplett weglassen und einfach einmal pro Zeile einen externen 
Interrupt einspeisen. Dann hast Du jedoch bis zu 5 Taktzyklen Jitter. 
(etwa 2 Pixel)

Willst Du Farbe machen, so müsstest Du einen zweiten PLL bauen, welcher 
unabhängig läuft und sich auf den Farbburst einklinkt. Dann kannst Du 
das Ausgangssignal Phasenschieben und AM-Modulieren und ganz einfach 
reinschalten. Das ist jedoch nochmal eine Runde schwieriger.

von JanB (Gast)


Lesenswert?

>Dann hast Du jedoch bis zu 5 Taktzyklen Jitter.

Ich habs probiert mit einem LM1881 aber ohne PLL.
Einfach Vsync und Hsync auf zwei ext.INTs gegeben.
Wenn du die Int-Latenzzeit rausrechnest kannst du den Jitter
auf 1 Taktzyklus (62,5ns)drücken.
Aber auch diese kleine Zeitabweichung sieht man noch recht deutlich.
Die Zeichen wirken unruhig und besonders an senkrechten Linien und 
Flanken treten sich bewegende "Treppenstufen" auf.

Gruß Jan

von vado (Gast)


Angehängte Dateien:

Lesenswert?

Hi!

It is difficult to use remaining 60% CPU resource for
processing PC Keyboard?

For people that do!
http://www.tvterminal.de/index.html

von Christian B. (casandro)


Lesenswert?

Well the main problem is how to connect the keyboard to the device. I 
have done experiments with my own code and it works over the serial port 
with an interrupt handler.

Probably the best way would be to use the otherwise unused I2C Port 
(also called Two Wire Interface or something) for the keyboard and check 
the keyboard buffer after every line. This way the display would not be 
disturbed by another interrupt handler.
Obviously the main problem is implementing a state machine for all the 
keyboard states. I am not yet sure how to do that efficiently.

von vado (Gast)


Angehängte Dateien:

Lesenswert?

They probably do with SPI,
but the video generating software.

uCPU clearly ATmega8! ! !

von Christian B. (casandro)


Lesenswert?

That might be, althought I somehow doubt it's the ATMega8.

von vado (Gast)


Angehängte Dateien:

Lesenswert?

As proof!

The TVT-MOBI-2 is an ATMEL(R) ATMEGA8 Microcontroller, pre-programmed 
with
a Demo-Software. Together with a few passive components it enables you 
to use a normal TV set (with PAL-compatible Video input) as a serial 
display !
Monochrome Text Display of 50 characters by 18 lines plus Status Line on 
your TV-Set.
Barchart Graphics Display with up to 72 bars for data visualization
in Realtime (up to 38 frames per second in 36-bar-mode !)
Many VT-100 compatible Escape Sequences

von Christian B. (casandro)


Lesenswert?

OK, OK. So it might be an ATMega8.

Still we could do it better :)

von Eberhardt Mungolei (Gast)


Lesenswert?

Hi,

ich habe den Code auf den Atmega88 portiert (Registerzugriffe und 
Bezeichnungen angepasst). Allerdings fehlt jetzt jedes 2. Zeichen... 
Wenn man Register Y beim Beschreiben des Initialisierungs-Screens 
(DDRAM) ein zweites mal erhöht... so etwa:
1
ldi temp, 32
2
clrloop:
3
  st Y+, temp
4
  adiw YL, 1
5
  inc temp
6
  ldi temp2, high(XSize*YSize+DDRAM)
7
  cpi YL, low(XSize*YSize+DDRAM)
8
  cpc YH, temp2
9
  brne clrloop


dann passt die Ausgabe - aber natürlich wird die Hälfte vom Puffer 
verschwendet. Warum?

Außerdem lässt sich der Code leider nicht mit dem AVR Studio debuggen. 
Der IRQ sollte ja alle 64µs aufgerufen werden, im Debugger gibt's aber 
mindestens 3 verkehrte Zeiten & gelegentlich einen ungültigen Opcode 
beim ijmp - warum? (auch auf dem Mega-8)

noch als Tipp für andere Porter:
Das erste "out DDRB, spiaus" in hloop löschen - sonst hat man einen 
schwarzen Strich durch jeden Buchstaben.

Danke!

von Christian B. (casandro)


Lesenswert?

Vielleicht schreibst Du zu früh in den SPI. Wenn Du einen Befehl 
rauslöschst musst Du natürlich entsprechend viele NOPs einfügen.

Und Debugger sind sowieso nur was für Weicheier. :)

von Eberhardt Mungolei (Gast)


Lesenswert?

hm Problem gelöst... war eigentlich ganz einfach:
1
;sbi SPSR, SPI2X
2
in temp, SPSR
3
ori temp, (1<<SPI2X)
4
out SPSR, temp
statt in und out lds and sts verwendet :-/ jetzt sind die Buchstaben 
auch viel schöner :)

von Christian B. (casandro)


Lesenswert?

Schön :)

Ich hab mir schon mal überlegt, ob ich nicht mal was mit einem externen 
Schieberegister mache. Dadurch würde das noch einmal doppelt so schnell 
werden. 80 Zeichen pro Zeile wären dann möglich.

von Benedikt K. (benedikt)


Lesenswert?

Dann benötigt man aber einen größeren µC mit mehr Pins und mehr RAM. Mit 
einem etwas größeren ARM µC mit 32kByte RAM sind lückenlose 512x256 
Pixel möglich...
Das einzige Problem: Den kann man nicht mal schnell auf Lochraster 
aufbauen.

von Christian B. (casandro)


Lesenswert?

Naja, ein ATMega32 würde schon reichen.

ARMs sind da natürlich die Königsklasse. Man müsste nur für die mal eine 
Art DOS schreiben. So als eine Art Minimalbetriebssystem bei dem man 
auch zur Laufzeit Programme nachladen kann.

von Rob Turbo (Gast)


Lesenswert?

320x240 8bit colour ist also moglich

von Ulrich P. (uprinz)


Lesenswert?

Ein DOS auf den ARM...

Wenn man das zu Ende spinnt, dann könnte man in den ARM doch einen 6502 
Emulator programmieren und käme dann Schritt für Schritt zu einem 
'Single-Chip' XT oder Apple ][. Fügt man doch noch ein wenig externe 
Logik hinzu, sollte auch ein C64 kein Problem sein, oder?

Gruß, Ulrich

von Hannes L. (hannes)


Lesenswert?

Ulrich P. wrote:
> Ein DOS auf den ARM...
>
> Wenn man das zu Ende spinnt, dann könnte man in den ARM doch einen 6502
> Emulator programmieren und käme dann Schritt für Schritt zu einem
> 'Single-Chip' XT oder Apple ][. Fügt man doch noch ein wenig externe
> Logik hinzu, sollte auch ein C64 kein Problem sein, oder?

Gibt es den C64-Nachbau nicht schon für'n Appel und'n Ei in einem 
Joystick integriert? Ich denke, ich habe mal sowas für um die 30 Taler 
gesehen.


Zurück zum Thema des Threads:
Benedikt, ich danke Dir für Deine Vorlage!!

Ich konnte danach sehr preiswert einen OSD-Generator für Amateur-TV 
bauen, der Ident-Text in das laufende Videobild einblendet. Im Sinne der 
Lesbarkeit habe ich die Textmenge auf 10 Zeilen zu 32 Zeichen reduziert 
und die Zeichenhöhe, sowie die Zeichen- und Zeilenabstände erhöht. Es 
wird in einer Außenstation des ATV-Relais DB0WTB zum Einsatz kommen, 
wobei die Texte von einem DTMF-gesteuerten Quellenumschalter (Tiny2313) 
geliefert werden (das hätte in den Mega8 auch noch mit reingepasst, war 
aber bereits vor der OSD-Idee fertig aufgebaut und in Betrieb genommen).

...

von Casandro (Gast)


Lesenswert?

Ja, einen C64-Emulator könnte man machen, nur die Graphik kriegt man 
halt nicht so einfach hin.

Ich würde eher einen Z80-Emulator machen, und dann CP/M drauf laufen 
lassen.

von Christian B. (casandro)


Lesenswert?

Was hat eigentlich der Code für eine Lizenz? Ich würde den gerne mit 
GPL-Code mischen.

von Detlev T. (detlevt)


Lesenswert?

Hallo Leute,

das Projekt gefällt mir, insbesondere wegen seiner Einfachheit, sehr 
gut. Allerdings kann ich es nicht 1:1 übernehmen, deswegen habe ich 
versucht zu verstehen, wie das alles gemacht wird. An einem Punkt 
scheitere ich aber: Der Erzeugung der vertikalen Synchronisierung.
1
handle_VSync:
2
  inc Y_Cnt        ;Zeilenzähler erhöhen
3
  cpi Y_Cnt, VSStart    ;Beginn VSync ?
4
  breq VSyncstart  
5
  cpi Y_Cnt, BPStart    ;Ende VSync ?
6
  breq VSyncende  
7
  cpi Y_Cnt, BildStart  ;Bildende ?
8
  brsh Bildbeginn  
9
  rjmp exit_int
10
11
VSyncstart:
12
  ldi tempi, (1<<COM1B1)|(0<<COM1B0)|(1<<WGM11)|(1<<WGM10)
13
  out TCCR1A, tempi    ;VSync Start: Sync Impulse High aktiv
14
  rjmp exit_int
15
16
VSyncende:
17
  ldi tempi, (1<<COM1B1)|(1<<COM1B0)|(1<<WGM11)|(1<<WGM10)
18
  out TCCR1A, tempi    ;VSync Ende: Sync Impulse Low aktiv
19
  rjmp exit_int
20
21
Bildbeginn:
22
  clr Y_Cnt
23
  ldi XL, low(DDRAM)
24
  ldi XH, high(DDRAM)
25
  rjmp exit_int
Bei VSyncstart und VSyncende werden aus meiner Sicht der gleiche Wert in 
TCCR1A geschrieben, der zudem identisch mit dem Wert ist, der schon seit 
der Initialisierung dort steht. Wo und wie wird die vertikale 
Synchronisation da überhaupt ausgelöst? Wo sind die Vor- und 
Nachtrabanten, wo die Unterscheidung von erstem und zweitem Halbbild?

Kann mir da jemand bitte die Tomaten von den Augen nehmen? Danke.

Gruß, DetlevT

von Joerg W. (joergwolfram)


Lesenswert?

Während des VSYNC wird die Polarität des HSYNC über das COM1B0 Bit 
geändert. Die beiden Halbbilder sind identisch, Trabanten werden nicht 
generiert. Der TV kommt aber trotzdem damit klar.

Jörg

von Detlev T. (detlevt)


Lesenswert?

Hallo Joerg,

stimmt, diese "komische" Null (0<<COM1B0) hatte ich übersehen.

Danke, DetlevT

von Detlev T. (detlevt)


Lesenswert?

Ich habe noch eine (blöde?) Frage. In der Initialisierung wird das Input 
Capture Register mit 1024 geladen:
1
ldi temp, high(1024)      ;Timer Reloadwert
2
out ICR1H, temp
3
ldi temp, low(1024)      ;Timer Reloadwert
4
out ICR1L, temp
Ich vermute, das wurde einmal genutzt, um den TOP-Wert von TIMER1 zu 
definieren. Das scheint mir aber gar nicht (mehr) nötig, weil allein 
schon durch das Setzen von WGM13-WGM10 = 0111 der TOP-Wert auf 0x03ff 
gesetzt wird. (10-Bit PWM)

Ich will das ICR für einen anderen Zweck nutzen, das kann ich dann doch 
wohl machen, oder?

Danke schon einmal für die Antwort,

DetlevT

von Joerg W. (joergwolfram)


Lesenswert?

Ich kenne den restlichen Code nicht, aber wenn 10Bit PWM eingestellt ist 
braucht man das ICR Register nicht. Allerdings lässt es sich nur dann 
beschreiben, wenn es über WGM13-WGM10 als TOP-Value definiert ist, 
ansonsten lässt es sich nur lesen.

Jörg

von Detlev T. (detlevt)


Lesenswert?

Hallo Joerg Wolfram,

danke für deine Antworten. Jetzt habe ich das Gefühl, das Ganze zu 
durchschauen. Eigentlich müsste es auch möglich sein, ein ordentliches 
PAL-Signal zu generieren. Es gibt ja auch ein 9-Bit-PWM-Modus für die 
halbe Zeilenlänge und die negative Flanke ist bei PAL immer an der 
gleichen Stelle (Bei TCNT=0). Man müsste dann also "nur" noch OCR1B 
passend manipulieren (statt simpler Invertierung, die das Signal zudem 
verschiebt) um der Norm zu entsprechen.

Ich muss dazu noch einmal genau das Datenblatt lesen. Mal sehen, wann 
ich Zeit dafür finde. ;)

Gruß, DetlevT

von Nils ‫. (n-regen)


Lesenswert?

Wäre es auch möglich, ein schon vorhandenes SYNC-Signal zu nutzen, um 
die Zeichen über ein anderes Bild drüberzulegen?

Und nach welchem Prinzip sind eigentlich die Zeichen im Zeichenarray 
definiert? Also, welches Byte beeinflusst da welchen Teil von welchem 
Zeichen?

von Christian B. (casandro)


Lesenswert?

a) Ja, Du müsstest das Synchronsignal, zum Beispiel, mit einem LM1881 
abtrennen und dann an jedem Zeilenanfang einen Interrupt auslösen. Du 
müsstest dann beispielsweise per "Capture Compare" den genauen Zeitpunkt 
bestimmen.

b) Das Format ist grob gesagt so: Die Zeichen sind 8x8 Pixel groß. Alle 
Pixel in einer Zeile sind in einem Byte. Jedes Zeichen hat 8 Bytes, und 
die werden zweckmäßig im Speicher angeordnet.

von Hannes L. (hannes)


Lesenswert?

Nils ‫‪ schrieb:
> Wäre es auch möglich, ein schon vorhandenes SYNC-Signal zu nutzen, um
> die Zeichen über ein anderes Bild drüberzulegen?

Beitrag "Re: Texteinblendung in ein FBAS Signal"
Beitrag "Re: Texteinblendung in ein FBAS Signal"
Beitrag "Re: Texteinblendung in ein FBAS Signal"
Beitrag "Re: LM1881 BASCOM"

>
> Und nach welchem Prinzip sind eigentlich die Zeichen im Zeichenarray
> definiert?

Jedes Zeichen besteht ja aus 8 Bytes zu 8 Pixel.
Der Zeichensatz hat 256 Zeichen.
Da man das Bild zeilenweise braucht, enthält jede der 8 Flash-Pages eine 
Pixelzeile für alle 256 Zeichen.

> Also, welches Byte beeinflusst da welchen Teil von welchem
> Zeichen?

In ZH steht die Pixelzeile der Schrift (+ Offset, da der Zeichensatz ja 
nicht ab Adresse 0 beginnen kann).
Über ZL adressiert man das Bitmuster zum Zeichen.

Dies hat den Vorteil, dass man mit ZH die Pixelzeile adressiert und mit 
ZL das Zeichen.

Wenn z.B. die Pixelzeile 2 (Zählweise 0-7) der Schrift dran ist, 
adressiert man ZL auf Zeichensatzbeginn + 2. Dann liest man das 
darzustellende Zeichen (ASCII-Code) aus dem RAM direkt in das Register 
ZL, und kann mit LPM sofort das Bitmuster der Pixelzeile 2 des Zeichens 
auslesen und an SPI zum bitweisen Herausschieben übergeben.

Mit jeder anderen Anordnung des Zeichensatzes wäre der Zugriff 
komplizierter.

...

von Detlev T. (detlevt)


Lesenswert?

Benedikt K. schrieb:
> Das SPI Interface braucht leider 18 Takte. Schreibt man das Byte zu
> früh, wird es ignoriert.

Mir ist in einem Datenblatt da etwas aufgefallen, was mir persönlich 
leider zwar gar nichts nützt, aber vielleicht ja einem anderen.

Die neuen "großen" ATMEGAs (164A und folgende) haben zwei USARTs, die 
sich auch im SPI-(Master-)-Mode betreiben lassen. Mit UBRRn=0 laufen sie 
ebenfalls mit halbem Systemtakt. Wenn ich da nicht etwas grundsätzlich 
missverstanden habe, sind diese auch im SPI-Mode "double buffered". Das 
heißt, man kann schon das nächste Byte schreiben wenn das vorhergehende 
noch gesendet wird. Damit müsste man die Ausgabe eines Bytes in 16 
Takten ohne irgendwelche Klimmzüge machen können.

Außerdem sind diese Controller bis 20MHz spezifiziert, so dass man noch 
mehr Zeichen auf eine Zeile quetschen könnte.

Gruß, DetlevT

von Christian B. (casandro)


Lesenswert?

Man kann auch einfach den SPI abschalten und wieder einschalten, dann 
gehen auch weniger Pixel pro Zeichen. Mit 5 Pixeln pro Zeichen könnte 
man sogar 80 Zeichen pro Zeile machen.

von Detlev T. (detlevt)


Lesenswert?

Hallo Christian,

80 Zeichen auf einem Fernseher mit seiner geringen Bandbreite wären wohl 
doch zu viel.

Die Diskussion mit dem An- und Ab-Schalten hatten wir weiter oben ja 
schon. Das ändert nichts an dem Problemen, dass man nicht die volle 
Kontrolle über alle Pixel hat und dass der Ausgang zwischen zwei Bytes 
auf high geht.  Das könnte mit der USART als SPI eben anders sein.

Ich habe noch folgende Ideen zur Erweiterung/Weiterentwicklung für 
dieses doch sehr gute Konzept:

1.) Man könnte den Controller mit 25.175MHz (notfalls auch 25MHz) 
übertakten. Das sind 25%, das müssten die meisten Exemplare (bei 25°C) 
mitmachen. Wenn die USART-Lösung funktioniert bekommt man damit 320 
Pixel und damit auch 40 Zeichen auf einen Standard-VGA-Monitor.

2.) Mit einem 74HC157 (4-fach 2 zu 1 Multiplexer) und einem 8-Bit Port 
(z.B. PORTC) kann man Farbe ins Spiel bringen. Der 74HC157 schaltet - 
gesteuert von MOSI - jeweils vier Bits um (Vorder- und 
Hintergrundfarbe). Definiert man MOSI=high als "Hintergrund" entfällt 
auch das Problem mit dem High-Signal zwischen den zwei Bytes und man 
muss da nichts mehr mit dem zweiten Pin korrigieren. Im (doppelt so 
großen) Bildschirmspeicher wären dann nacheinander immer zwei Bytes pro 
Zeichen. Eins für Farbe und eins für das Zeichen selbst. Mit einem 
zusätzlichen Register color für die Farbe könnte der Code dann IMO so 
aussehen:
1
.equ XSize    =80  ;Bildgröße in X Richtung in Nibbles
2
3
hloop:          ;Loop für 1 Zeile
4
  ld ZL, X+      ;ASCII aus RAM lesen  2
5
  lpm tempi, Z      ;Byte aus CGROM lesen  3
6
  ld  color, X+             ;Farbe lesen            1
7
  out SPDR, tempi      ;Byte ausgeben    1
8
  out PORTC, color    ;Farbe ausgeben   1
Am Ende der Zeile muss man dann noch 0x00 in PORTC schreiben, damit man 
den Schwarz-Pegel erhält. Die Beschaltung für einen Farb-"DAC" findet 
man bei Jörgs Chipbasic-Projekt,

Gruß, DetlevT

von Christian B. (casandro)


Lesenswert?

Detlev T. schrieb:
> Hallo Christian,
>
> 80 Zeichen auf einem Fernseher mit seiner geringen Bandbreite wären wohl
> doch zu viel.

Ein berühmter niederländischer Unterhaltungselektronikhersteller wirbt 
schon seit den frühen 1990ger Jahren damit, 2000 Zeichen darstellen zu 
können.

> Die Diskussion mit dem An- und Ab-Schalten hatten wir weiter oben ja
> schon. Das ändert nichts an dem Problemen, dass man nicht die volle
> Kontrolle über alle Pixel hat und dass der Ausgang zwischen zwei Bytes
> auf high geht.  Das könnte mit der USART als SPI eben anders sein.

Kann die mit 0 Start und 0 Stoppbit arbeiten? Das wäre der springende 
Punkt. An sonsten lässt ja ein ausgeschaleter SPI ja die Normalbelegung 
des Ports durch. Und die kann man steuern.

von Detlev T. (detlevt)


Lesenswert?

Christian Berger schrieb:
> Kann die mit 0 Start und 0 Stoppbit arbeiten? Das wäre der springende
> Punkt. An sonsten lässt ja ein ausgeschaleter SPI ja die Normalbelegung
> des Ports durch. Und die kann man steuern.

Das verstehst du falsch. In dieser Konfiguration ist die Hardware kein 
UART, sondern eine ganz normale SPI-Schnittstelle. Also nix, was Start- 
oder Stopp-Bits hätte.

von Christian B. (casandro)


Lesenswert?

Detlev T. schrieb:

> Also nix, was Start-
> oder Stopp-Bits hätte.

Ahh, grad auch im Datenblatt gesehen.

Die Idee mit der Farbe finde ich persönlich eher merkwürdig und 
umständlich.
Ich würde den Controller auf der 6-fachen Farbunterträgerfrequenz 
(26,60171250 MHz) laufen lassen, und dann einfach den SPI-Ausgang 
verwenden.

Du hättest dann Pixeltrippel für die Farbe. Das ist zwar nicht RGB, 
sollte aber trotzdem brauchbar sein.
Will man eher gute Farbe haben, so speichert man im RAM für jedes 
Pixeltrippel einen Wert. Man schlägt diesen Wert im Flash-ROM nach und 
gewinnt 3 Bits für die Ausgabe. Im Flash-ROM wären dann 2 kleine 
Tabellen die den Farbpalettenwert für gerade und ungerade Zeilen 
enthalten. Da hätte man dann ungefähr 160 Pixel pro Zeile.

Hat man 3840 Bytes zur Verfügung, so könnte man beispielsweise 5 Pixel 
in einem Byte kodieren. Dabei bestimmen die 5 niederwertigsten Bits den 
Eintrag der Tabelle, und die 3 hochwertigsten Bits welche Tabelle 
verwendet wird. Die Tabelle hätte dann 8*2 Einträge und würde noch in 
das RAM passen. Dann hätte man 8 Kombinationen von 2 Farben für jeweils 
8 Pixel bei 160*120

Im Prinzip kann man auch mit Einzelpixeln arbeiten, dann wird das mit 
den Tabellen aber komplizierter.

Man könnte das sogar noch weiter spinnen und die Taktfrequenz noch 
extern verdoppeln und als Träger für das Bildsignal nutzen. Das wäre 
dann etwas unter Kanal 3. :)

von Detlev T. (detlevt)


Lesenswert?

Hallo Christian,

so auf Anhieb verstehe ich nicht, was du da vorschlägst. Ich sehe aber, 
dass du viel mehr RAM und ein stark übertakteten Controller brauchst um 
einmal gerade 160x120 Pixel zu erreichen.

Grafik finde ich für diesen Zweck ohnehin nicht für zweckmäßig. Warum 
soll man mit viel Mühe (und RAM) ein grafisches Display programmieren, 
dass man dann im Hauptprogramm wieder mit viel Mühe mit den Pixeln für 
Buchstaben füllen muss? Da finde ich die Idee von Benedikt viel besser: 
einfach ein Byte ins RAM schreiben - und schwupps ist das Zeichen auf 
dem Bildschirm.

Mit meiner Idee könnte man dann noch jedem Zeichen eine Vorder- und 
Hintergrundfarbe aus insgesamt 16 möglichen Farben zuordnen. Man muss 
dann aber über SCART gehen, via BAS gibt es natürlich nur grau in grau.

Na mal schauen, wann ich Zeit und Lust habe, das umzusetzen.

Gruß, DetlevT

von Christian B. (casandro)


Lesenswert?

Naja, ein Textmodus geht da natürlich auch. Du hättest dann 20 Zeichen 
pro Zeile mit 8 Vorder- und Hintergrundfarben. (mehr mit Tricks) Der 
große Vorteil ist halt, dass man direkt ein FBAS Signal bekommt und 
keine aufwändige externe Hardware mehr braucht. (Dein Multiplexer 
benötigt mindestens 9 Verbindungen zur MCU! Da muss man schon sehr 
motiviert sein, so viel zu löten)

Kann man den SPI um einen Taktzyklus verschieben, so könnte man auf 40 
Zeichen pro Zeile damit machen, allerdings mit eingeschränkten Farben. 
Das muss ich mir aber noch weiter überlegen.

Hypothetisch könnte man auch "Sub-Nyquist" Abtastung verwenden. Dann 
würde auch eine niedrigere Taktfrequenz reichen.

von Sven K. (oog)


Angehängte Dateien:

Lesenswert?

Es ist faszinierend, welch hohe Bildqualität und Stabilität mit dieser 
Software erreicht wird. Vielen Dank an Benedikt dafür.

Um auch weniger Zeichen Bildschirmfüllend darzustellen, habe ich das 
Programm etwas erweitert. Es gibt jetzt auch die Möglichkeit der 
Grafikdarstellung.

Hier eine Übersicht der Erweiterungen:

* Zeilenumruch mit EOL-Zeichen ermöglicht die speichersparende 
Textdarstellung (siehe Screenshot vmode0 mit 44x34 Zeichen, die sonst 
nicht mehr in die 1KB des ATmega8 passen.)

* Variabler Zeilenabstand zur Verbesserung der Lesbarkeit (Screenshot 
vmode4 mit 40x20 Zeichen).

* Abstand zwischen den Zeichen (Screenshot vmode7 mit 
bildschirmfüllenden 32x24 Zeichen)

* Doppelt breite Zeichen (Screenshot vmode9 mit 20x16 Zeichen)

* Grafik mit 80*64 Punkten ohne/mit Raster. Das Raster erzeugt eine 
LCD-Matrix ähnliche Darstellung (Screenshot gfxmode1 und 2).

* Grafik mit 88x72 und 96x80 Punkten (Screenshot gfxmode6).

* Speicherung der im Interrupt genutzten Register im RAM. Das 
Hauptprogramm kann alle Register frei nutzen.

Zur Demonstration habe ich einige Parametersätze definiert (vmode, 
gfxmode), die leicht erweitert werden können.

Ich hoffe, das Programm enthält keine Fehler mehr. Getestet habe ich mit 
einem ATmega8. Die Screenshots wurden mit einem Video-Grabber erstellt, 
zeigen also das echte Videosignal.

Hinweis zum Bildformat: Das verwendete JPG belegt nur etwa 50% Speicher 
gegenüber dem PNG-Format.

von funker (Gast)


Lesenswert?

hallo, sieht ja gut aus.

wo bekomme ich jetzt den assembler her um das mal umzusetzen?

gruss

von funker (Gast)


Lesenswert?

Hmm... habe den ASM vom Avrstudio genommen.
Es entsteht aber keine hex sondern nur eine obj.
Wie stelle ich eine hex her oder ein bin?

Gruss

von Sven K. (oog)


Lesenswert?

funker schrieb:
> Wie stelle ich eine hex her oder ein bin?

Ich verwende ebenfalls AVR Studio und gehe so vor:

Neues Projekt anlegen.
Project Type: Atmel AVR Assembler
Debug platform: AVR Simulator
Device: ATmega8

Nach dem Assemblieren (F7) liegt im Projektverzeichnis eine hex-Datei 
mit dem Projektnamen, also z.B. Testprojekt.hex.

Grüße.

von Sven K. (oog)


Angehängte Dateien:

Lesenswert?

Es gibt einige neue Erweiterungen.

Optimierung für kleine LCD Monitore mit 234 Bildzeilen:
Insbesondere für den Betrieb mit kleinen 7" LCD Monitoren wurde eine 
Option zur doppelten Zeilenausgabe eingebaut, da die Monitore aufgrund 
der niedrigen Auflösung einige Zeilen des Bildes verschlucken können.

Neu ist auch ein doppelt hoher Zeichensatz (8x16 Pixel), von dem es auch 
eine Version mit invertierten Zeichen gibt. Dann ist der Zeichenvorrat 
allerdings auf 128 Zeichen beschränkt.

Die Video-Modes vmode_12 - vmode_18 demonstrieren die neuen 
Möglichkeiten.

Der Modus mit 20x8 Zeichen eignet sich für Anzeigen, die aus größerer 
Entfernung noch lesbar sein sollen.

Eine Anmerkung zu den Screenshots:

vmode12:
 40x16 Zeichen mit neuem 8x16 Pixel Zeichensatz

vmode12i:
 40x16 Zeichen mit neuem 8x16 Pixel Zeichensatz, der inverse Darstellung 
unterstützt.

vmode14 und vmode16:
 20x12 Zeichen Darstellung, einmal mit 8x16 Zeichensatz, einmal mit 8x8 
Zeichensatz und doppelter Zeilenausgabe

vmode17:
 20x8 Zeichen, gute Lesbarkeit auf Entfernung.

von jack (Gast)


Lesenswert?

Hallo! Wie man Schrift 10x4?

von jack (Gast)


Lesenswert?

Hat nicht jemand wissen?
Wie ändert man die Auflösung von 10x4 Zeichen?

von Info (Gast)


Lesenswert?

Leider habe ich von Assembler überhaupt keine Ahnung.

Ich versuche, die Dezimal-Ziffern des Bytes "frame" (nicht "frames", wie 
im Header beschrieben) in den Bildspeicher zu schreiben (Tutorial: 
(http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Dezimal_ausgeben).

Dazu habe ich versucht, mir Z an der passenden Stelle der Textausgabe zu 
merken, etwa:
1
  rcall print
2
  .db   "Frame: ",0
3
4
  mov r20, r30
5
  mov r22, r31
6
7
  rcall print
8
  .db   "mehr Text",0

An diese Stelle im Speicher soll der aktuelle Zähler geschrieben werden, 
vermutlich am besten in der main loop:
1
Mainloop:
2
3
4
  sbic  UCSRA, RXC ;Daten im UART Puffer ? 
5
  rcall rxuart
6
7
  mov YL, r20
8
  mov YH, r22
9
10
11
; ouput "frame" counter
12
           ldi   temp2, frame     ; das Register temp1 frei machen
13
                                  ; abzählen wieviele Hunderter
14
                                  ; in der Zahl enthalten sind
15
;** Hunderter ** 
16
           ldi   temp, '0'-1     ; temp1 mit ASCII '0'-1 vorladen
17
lcd_number_1:
18
           inc   temp            ; ASCII erhöhen (somit ist nach dem ersten
19
                                  ; Durchlauf eine '0' in temp1)
20
           subi  temp2, 100       ; 100 abziehen
21
           brcc  lcd_number_1     ; ist dadurch kein Unterlauf entstanden?
22
                                  ; nein, dann zurück zu lcd_number_1
23
           subi  temp2, -100      ; 100 wieder dazuzählen, da die
24
                                  ; vorherhgehende Schleife 100 zuviel
25
                                  ; abgezogen hat
26
           st    Y+, temp
27
 
28
;** Zehner  **
29
           ldi   temp, '0'-1     ; temp1 mit ASCII '0'-1 vorladen
30
lcd_number_2:
31
           inc   temp            ; ASCII erhöhen (somit ist nach dem ersten
32
                                  ; Durchlauf eine '0' in temp1)
33
           subi  temp2, 10        ; 10 abziehen
34
           brcc  lcd_number_2     ; ist dadurch kein Unterlauf enstanden?
35
                                  ; nein, dann zurück zu lcd_number_2
36
           subi  temp2, -10       ; 10 wieder dazuzählen, da die
37
                                  ; vorherhgehende Schleife 10 zuviel
38
                                  ; abgezogen hat
39
           st    Y+, temp
40
 
41
;** Einer **        
42
           ldi   temp, '0'       ; die Zahl in temp2 ist jetzt im Bereich
43
           add   temp, temp2     ; 0 bis 9. Einfach nur den ASCII Code für
44
        st    Y+, temp
45
46
  rjmp  Mainloop

Da haut aber wohl etwas mit den Adressen nicht hin, ich sehe nix.
Eine Möglichkeit, die Adresse für die 100er Stelle mit Offset anzugeben, 
wäre schön, dann kann der vorhandene Text nämlich einfach überschrieben 
werden.

von Info (Gast)


Lesenswert?

oh, z und y verwechselt, das kann schonmal vorkommen...
schreibe ich r30 u r31 zurueck, gibt es kein videosignal, d.h. 
bildschirm zeigt nix.

von Info (Gast)


Lesenswert?

Also, dank kbuchegg in 
Beitrag "Re: Fragen zu AVR ASseMbler Z-Pointer" konnte ich die 
Fehler finden. Mein Plan war gar nicht so falsch.

Ich habe in meinem Versuch sowohl die Pointer verwechselt Z / Y als auch 
ihre Register 
(http://www.avr-asm-tutorial.net/avr_en/beginner/REGISTER.html#Pointer).

Info schrieb:
>   mov r20, r30
>   mov r22, r31

>   mov YL, r20
>   mov YH, r22


Es wird ja für print Y genutzt. Adresse im Bildschirm-RAM nach einigen 
"print"s sichern:
1
mov r20, r28
2
mov r22, r29

Und wieder nach Y laden:
1
mov r28, r20
2
mov r29, r22

Das ist offenbar synonym zu
1
mov yl, r20
2
mov yh, r22


Ich hatte also eine falsche Adresse erwischt.

Mit der richtigen Adresse steht dann schon eine Zahl auf dem Schirm.. 
aber es ist nicht der Zähler.

Aus "ldi   temp2, frame" mithilfe von 
http://www.atmel.com/webdoc/avrassembler/avrassembler.wb_LDS.html "lds 
temp2, frame".

Damit läuft der Zähler auf dem Schirm.

Den Offset 8 für die Ausgabeposition in der nächsten Zeile nach dem 
print-Befehl addiert man auf den Y Pointer mit
1
adiw yl, 8

von Ulrich P. (uprinz)


Lesenswert?

Manchmal ist es echt begeisternd, welch ein Leben im Verborgenen so ein 
Thread hier führen kann. Da denkt man an nix besonderes und plötzlich 
hat man eine eMail im Postfach, dass da jemand auf einen längst 
vergessenen Thread geantwortet hat.

Spannend ist aber auch, dass Leute im Jahr 2014 immer noch Interesse an 
einem simplen S/W Terminal haben. Wo doch heute jedes und alles mit 
Touch und bunt auf dem Handy erledigt.

Vor kurzem ist mir der Thread schon mal in Erinnerung gerufen worden, 
weil ich mich mit Kollegen darüber unterhalten hatte, welche Bildschirme 
sie an ihren Heim-Servern haben. Ich hatte das 2007 beschriebene Display 
mit der um ein paar ANSI-ESC Kommandos erweiterten Software ein paar 
Jahre als "Monitor" an einem Gra-Ka losen Debian Linux als Home-Server 
laufen.

Je nach Wetter werde ich eines meiner CVBS LCDs ausbudddeln und mal 
einen AVR dran hängen. Es lebe das Steckbrett!

Gruß
Ulrich

von Bernhard S. (bernhard)


Lesenswert?

@Benedikt
@alle

mit einem kleinen Trik konnte ich die Rechenleistung noch weiter 
steigern.

Bevor eine TV-Zeile gesendet wird, wird sie auf Daten geprüft (in der 
Wartezeit der hinteren Schwarzschulter), liegen keine Daten vor, dann 
wird unverzüglich der Interrupt wieder verlassen.

Beitrag "TV BILD AVR BAS FBAS VOLLGRAFIK 320x256 Kreise Linien Punkte ASCII Assembler Atmega1284P"

Bernhard

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.