Hallo,
ich habe ein Video-Terminalprogramm für den AVR AtMega8-16
geschrieben.
Das Programm ist in Assembler geschieben.
Es erzeugt ein BAS-Signal und stellt auf einem Fernsehgerät mit Video-
oder Scarteingang 20 Zeilen mit je 40 Zeichen dar. Die ASCII-Zeichen
werden an den Mega8 über die serielle Schnittstelle (USART) gesendet.
Die Baudrate ist zwischen 300 und 19200 Baud einstellbar. Benötigt
werden ausser dem Mega8 mit 16-MHz Quarz und der üblichen Beschaltung
noch drei Widerstände und eine Diode. Ein Schaltplan befindet sich in
der angehängten ZIP-Datei.
Es werden 96 ASCII Zeichen und einige Steuerzeichen wie CR, LF, FF und
Zeichen zur Corsorpositionierung unterstützt.
Eine genauere Beschreibung der Terminalfunktionen findet ihr am Anfang
des Source-Codes (ASM-File).
In der ZIP-Datei befindet sich:
Der Source-Code des Programmes. (.ASM)
Das Hex-File, das man direkt in den Mega8 brennen kann. (.HEX)
Der Schaltplan für das Terminal. (.GIF)
Ein Bildschirmphoto (.jpg)
Viel Spaß mit dem Programm
Jan
Hallo Jan,
Super Projekt!!!
Du beschreitest den raffinierten Weg über das Hardware SPI-Interface,
schienbst ein Byte in's SPI und lässt anschließend die Harware für
Dich arbeiten und entlastest somit den µC, der dann in aller Ruhe
das nächste Datenbyte heranorganisieren kann ;)
Bernhard
Kann mich Bernhard nur anschließen, tolle Leistung. Es finden sich wohl
nur wenige die so ein Projekt durchstehen und dann noch
veröffentlichen.
Ich habe den source zwar nur überflogen, aber mir fallen zwei
Verbesserungsvorschläge auf:
1) Latenzzeit des Interrupts
Der Int tritt entweder während dem nop oder dem jump auf, demnach
müssten manche Einsprünge 62,5ns später passieren als andere. Und
62,5ns müßte man eigentlich im Bild sehen.
2) Vsync
bin mir nicht sicher aber ich glaube die Vsyncgenerierung passt nicht
ganz zu den genormten Vor-, Haupt- und Nachtrabantensignalen. Wird aber
nicht stören da "moderne" Fernseher hinsichtlich dieser Signale sehr
tolerant sind.
Grüße leo
Wenn man die Timerzeit so anpasst, dass der Interrupt immer zur selben
Seit eintritt, ist die Latenzzeit immer gleich groß. Das geht nur über
ausprobieren, macht in der Praxis aber kein Problem.
Bei mir musste ich alle Verzweigungen einzeln mit 0-2 nops abgleichen,
denn das ist die Zeit die bei Warteschleifen auftreten kann.
@leo
>>Und 62,5ns müßte man eigentlich im Bild sehen.
Das simmt, das würde man deutlich sehen.
Der Int tritt immer während des NOP auf.
Das wird erreicht durch "abgleichen" im Programm.
Die Stelle zum Abgleich ist am Anfang des HSYNC.
Wenn am Programm geändert wird, und das Bild wird griselig,
dann muss man ausprobieren ob dort 0 oder 1 oder 2 NOPs hinmüssen.
Zwei Versuche also maximal. Mehr als zwei NOPs kann nicht sein,
Drei NOPs ist wie keiner, wie modulo 2.
Der Vsync ist mit Vor- und Nachtrabanten im Halbzeilenabstand
weitgehend korrekt nachgebildet. Es findet aber keine
Halbbildumschaltung statt, deshalb gibt es auch keine halbe Zeile.
Trotzdem Danke für dein Interesse und deine Vorschläge !
Gruß Jan
@Jan
Man kann das nop-Problem auch durch eine SLEEP Anweisung umgehen.
Somit wird der Interrupt immer aus einer definierten Stellung heraus
gestartet ;)
LOOP:
sleep
...
...
rjmp LOOP
oder einem ext. Interrupt:
EXT_INT1:
SEI ; alle Interrupts wieder freigeben
SLEEP
....
reti
Bernhard
Hallo Bernhard,
>>Man kann das nop-Problem auch durch eine SLEEP Anweisung umgehen.
Hab ich anfangs versucht, brachte aber auch einen ziemlichen Jitter.
Ich hätte dann noch mit den verschiedenen Sleep-Modi des Mega-8
herumexperimentrieren müssen, aber da hatte ich es schon mit den NOPs
hingekriegt. Und das klappt ja auch problemlos. Wie schon beschrieben,
ich brauche nur an einer Stelle im Programm abzugleichen.
Bei einer Neuentwicklung würde ich den 16-Bit Timer benutzen,
und die Latenzzeit berechnen. Das finde ich persönlich am saubersten.
Gruß Jan
@Jan
>.... brachte aber auch einen ziemlichen Jitter.
Nur wo soll denn der Jitter hergekommen sein,
konntest Du die Ursache finden?
In meinem TV-Projekt war ich sogar so frech, dass ich die Interrupts
verschachtelte ("SEI + SLEEP")
http://www.mikrocontroller.net/forum/read-4-427581.html
SLEEP-Idle-Initialisierung:
; SLEEP-MODUS (Idle)
ldi temp, (1<<SE)|(0<<SM2)|(0<<SM1)|(0<<SM0)
out MCUCR, temp
Bernhard
Hallo,
Hier eine verbesserte Version des Programmes.
Es war noch ein dicker Bug in der Cursorpositionierung (Pos.0),
ein Vertauscher in der Beschreibung und die Grafiksymbole 1 - 15
sind nach 129 - 143 verschoben.
Gruß Jan
Hallo,
hier wieder eine neue Version des Programmes.
Gerry hat unermüdlich getestet und tatsächlich noch ein paar
Bugs aufgedeckt. Die sind jetzt auch korrigiert. Insbesonders ist
die Darstellungsqualität der Grafikzeichen verbessert worden.
Vielen Dank an Gerry, und ich hoffe, das jetzt alle Fehler beseitigt
sind.
Gruß Jan
Also ich habe bisher noch nichts in dem Forum geschrieben, aber diesmal
muß ich einfach meinen Respekt gegenüber Jan B. äussern!
Wirklich klasse Arbeit. Habe mir eben mal auf die schnelle dein
Video-Terminal zusammen gebastelt und deinen Source draufgespielt und
zack, Bild auf dem Fernseher. Ohne wenn und aber ;-)
Wirklich klasse Arbeit!
Liebe Grüße
Harry S.
Sorry das ich einen alten Thread nochmal zum Leben erwecke, aber ich bin
grad am nachbauen!
Ich hab die Schaltung soweit fertig, ABER bin mir nicht ganz siocher was
das Programmierinterface angeht.
Pin 17 (MOSI) wird ja in der Schaltung benutzt uns do über 710Ohm mit
Pin12 verbunden, mit 1150 Ohm mit GND.
Kann ich trotzdem den MOSI für den Programmiere einfach parallel nutzen
oder muss da ein Jumper oä rein?
Sooo,
nun bin ich fertig! Die erste selbst gelötete Platine und programmieren
haut hin.
ABER:
Ich seh kaum was am TV.
Das Bild ist dunkelgrau, unten und oben schwarze Balken.
Die Schrift die das Beispielprogramm das als Hex dabei war ausgibt zeigt
etwas Text an
AVR TV-Terminal ... und in der näcgsten Zeile was von 9600 Baud.
Das Problem ist die Schrift und nur ganz ganz schwer zu erkennen. Sie
ist kaum sichtbar, nur ein klein wenig dunkler als der Rest des
Bildschirms..
Was könnte den falsch sein?
Die Widerstände passen, die hab ich nachgemessen..
Nur beim 1k Widerstande mess ich je nachdem wierum ich meine Fühler
ranhalte entweder 1k oder 700 Ohm.. Ist aber definitiv ein 1k
Widerstand..
Hallo,
wenn du die Schrift dunkel auf hellem Grund siehst,
dann hast du in der Beschaltung irgendwas verkehrt gemacht.
Die Schrift muss weiss auf Schwarz sein, wie auf dem Screenshot.
Gruß Jan
Tolles Projekt!
Ich staune nur was man mit nur so wenig Hardware anstellen kann. Diese
Projekt kann ich vielleicht für mein eigenes verwenden. Mein 1987
erstellter Z8 Rechner macht leider nur 8 Zeilen mit 13 Zeichen. Mit
dieser Schaltung könnte ich die Bildschirmerzeugung enorm aufpeppen. Das
Problem ist vermutlich die Kopplung. Denn die serielle Schnittstelle
scheidet aus, sie ist belegt!
Viele Grüße Peter
Hallo Jan,
das dachte ich mir auch schon - wie gesagt ich hab alles nochmal
nachkontrolliert und nachgemessen.. bleibt nur noch die Diode - es ist
schon so das der schwarze Strich auf dem Bauteil den Strich auf dem
Symbol entspricht, oder?
Wenns das nicht is, kanns nur noch der komische Effekt mit dem 1k
Widerstand sein den ich oben beschrieben habe.
Ich werds morgen mal mit in die Arbeit nehmen und evtl mal per Oszi
ankucken - vielleicht bringt das Erkenntniss.
Über weitere Tipps wäre ich trotzdem dankbar.
hallo
hast du mir neulich eine email gesendet? ich hatte leider einen PC_crash
und alles ist weg. es ging um die kopplung meines "Z8" mit deinem modul.
viele grüße
PETER
Hallo, kann man deine Schaltung ganz einfach an den Antenneneingang
eines normalen Fernsehers anschliessen?
Mein TV (sehr alt) hat nämlich keinen anderen Eingang. Eine schnelle
Antwort wäre super :-)
MfG
Hallo Pawel,
nein, du kannst die Schaltung nicht direkt an einen Antenneneingang
anschliessen. Dazu müsstest du einen sog. HF-Modulator
dazwischenschalten.
Ja, sicher kann man das Programm modifizieren, so das es mit 15Mhz
läuft.
Die volle Auflösung wird dann wohl nicht mehr erreichbar sein.
Vielleicht noch 36x25 oder 38x25.
Allerdings lohnt sich der Aufwand kaum, wenn man bedenkt das ein 16MHz
Quarz bei Reichelt nur 24 Cents kostet.
Gruß Jan
Hallo Jan,
wirklich tolles Programm, funktioniert bei mir problemlos. Der einzige
Nachteil ist, dass es nicht schneller geht als mit 19200baud. Was mir
aufgefallen ist, dass nicht die main die Zeichen aus dem UART-Buffer
holt sondern die ISR beim VSync(wenn ich das richtig verstanden hab).
Kann man denn das Bearbeiten von Zeichen nicht in die main verlegen, um
größere Baudraten zu erhalten?
MfG Mark
Hi Mark,
Vielen Dank für dein Interesse und deine konstruktive Kritik.
die Zeichen werden beim H-Sync vom USART abgeholt und gepuffert. Damit
könnten bis zu 15625 Zeichen/sec empfangen werden, also ca. 150000baud.
Der Engpass liegt vielmehr in der Weiterverarbeitung der empfangenen
Zeichen. Besonders das Scrollen das Bildschirminhaltes kostet viel Zeit.
Hier müssen fast 2K Ram verschoben werden, bevor das nächste Zeichen
bearbeitet werden kann. Und der Empfangspuffer ist nur 16Byte groß, weil
bei 40x25 schon 1000 Bytes des 1K großen RAMs des Mega8 für den
Bildspeicher gebraucht werden.
Allerdings würde ich mit meinen jetzigen Kenntnissen das Programm völlig
anders aufbauen und könnte bestimmt mehr Geschwindigkeit rauskitzeln.
Naja, jedes fertige Programm ist im Grunde obsolet, hinterher könnte man
es immer besser...
Gruß Jan
Hallo Jan,
danke für Deine Antwort!
>Besonders das Scrollen das Bildschirminhaltes kostet viel Zeit.
Könnte man das nicht so machen, dass man die Zeilen scrollt, indem man
einen Zeiger auf die erste Zeile erzeugt und beim Scrollen um eine
Position weiter verschiebt? Dann müsste nur die freigewordene Zeile mit
Leerzeichen gefüllt werden, was deutlich weniger Zeit beansprucht als
das scrollen des ganzen RAMs.
>Und der Empfangspuffer ist nur 16Byte groß, weil>bei 40x25 schon 1000 Bytes des 1K großen RAMs des Mega8 für den>Bildspeicher gebraucht werden.
Würde es mit einem Mega32 besser gehen? Ich hab versucht, das Pogramm
auf den Mega32 umzuschreiben, bin jedoch mangels Kenntnissen des
Programmablaufs auf die Nase gefallen. MOSI liegt dort ja an PORTB.5 und
nicht PB3.
Aja, eine Frage noch: ist es ohne großen Aufwand möglich, das Programm
so umzuschreiben, dass es die Zeichen-Fonts aus dem RAM lädt und nicht
aus dem Flash? Beim Mega32 ist ja noch ein KB frei und da wäre ja
eigentlich Platz für mind. 125 Zeichen. Ziel des ganzen wäre dann, dass
man vor dem Programmstart ein beliebiges Font laden könnte, so dass man
auch einfache aber relativ hochauflösende Graphik(320x200) hinkriegt.
MfG Mark
Hi Mark,
du hast schon Recht, da könnte noch einiges verbessert werden an dem
Programm. Natürlich ginge das auch noch besser mit einem Mega32.
Besonders dessen 2k Ram wären interessant. Andererseits macht es mir
auch immer wieder Spaß zu sehen was mit dem "kleinen" Mega-8 so alles
möglich ist.
Ein ladbarer Fonts im Ram würde mit 128 Zeichen schon das gesamte
zusätzliche Ram eines Mega8 aufbrauchen, da halte ich es für sinnvoller
mehrere umschaltbare Fonts im Flash-Rom zu halten. Da ist Platz genug.
Es wäre auch denkbar, eigene Fonts zu laden und ins Flash zu brennen.
Die AVRs können sich
ja selbst im laufenden Betrieb programmieren. Hab ich aber noch nie
probiert.
Gruß Jan
Hallo,
>nur wie geht das mit den Steuerzeichen?
Du sendest die Steuerzeichen an das Terminal,
ganz normal wie die anderen Zeichen auch.
Eine Beschreibung zur Funktion der Steuerzeichen
findest du am Anfang des ASM-Datei.
Gruß Jan
Grüße zu dir von Ukraine!
Für dein ausgezeichnetes Projekt danke!
Verwenden es in Verbindung mit dem Kreation amforth
autonomes programmierbares System.
Es gibt Ausgaben und Ideen:
- Kannst du dem Entwurf PC an der Tastatur den hinzufügen
volles Videoterminal.
- möchten die Idee vorschlagen. den Entwurfgeweben schon hinzufügen
Attribute mit einen Kristallen für Farbe, blitzend Umstellung,…
Wirklich gutes Programm.
Anmerkungen:
Im BAS Signal gibt es doch eine negative Austastlücke. Ich kann in der
Schaltung keine neg. Spannung sehen. Darum hatte ich nicht erwartet, daß
man mit 3 Widerständen ein BAS Signal erzeugen kann, wo andere
Hersteller extra Chips für herstellen.
Reicht die Zeit aus, um in der horizontalen Lücke 2 Bytes zu
verarbeiten? Der Hardware UART hat 1 Byte Puffer und dann könnte man die
Übertragungsgeschwindigkeit verdoppeln.
Könnte man nicht beim Scrollen statt der Byteverschiebung eine
Adressverschiebung machen? Das würde dann wesentlich schneller gehen.
Ich habe in meinem Programm einen 256 Byte Software-Empfangspuffer, den
könnte man ja entsprechend erweitern. Ich verwende den Mega32, so daß
die Speichergröße kein Problem darstellen sollte.
Für eine prakt. Anwendung sehe ich nur eingeschränkte Möglichkeiten. Da,
wo Daten über die serielle Schnittstelle eingelesen werden können (PC),
ist meist auch ein Bildschirm vorhanden. Und ein PC hat meistens auch
einen TV Ausgang.
mfg
Hallo Wolfram,
dieser Thread und auch das Programm sind schon fast ein Jahr alt.
Klar habe ich mittlerweile einges verbessern können.
>Im BAS Signal gibt es doch eine negative Austastlücke.>Ich kann in der Schaltung keine neg. Spannung sehen...
Der neg. Sync-Impuls in der Austastlücke ist nur bezogen auf
den Schwarzpegel negativ. Der Schwarzpegel liegt bei 0,3V und
der Sync-Impuls liegt 0,3V niedriger also auf 0V (GND). Es wird also
für ein BAS-Signal keine neg. Spannung gebraucht.
>Könnte man nicht beim Scrollen statt der Byteverschiebung eine>Adressverschiebung machen?
Ist in einer neuen Version schon realisiert, Geschwindigkeitsgewinn
enorm.
Code ist auch noch einfacher. Also, hätte ich gleich so machen sollen.
>Reicht die Zeit aus, um in der horizontalen Lücke 2 Bytes zu>verarbeiten?
Die ankommenden Zeichen werden jetzt asynchron ausserhalb der
Videosignalerzeugung verarbeitet. Klappt jetzt mit bis zu 115000 Baud.
Getestet. Auch mit Scrollen im Text.
>Für eine prakt. Anwendung sehe ich nur eingeschränkte Möglichkeiten.
Sehe ich auch so. Dehalb habe ich es auch hier nicht weiter fortgeführt.
Es ist nur ein Experiment zu meinem persönlichen Vergnügen.
Um zu probieren was so geht mit einem Mega8...
Gruß Jan
Hallo Jan!
Tolles Projekt! Gibt es eine Möglichkeit anstatt eines PAL-Signals ein
NTSC-Signal zu erzeugen?
Ich denke man muss 'nur' etwas am Timing spielen. Aber wo?
Gruß, Phil
PhilW wrote:
> Hallo Jan!>> Tolles Projekt! Gibt es eine Möglichkeit anstatt eines PAL-Signals ein> NTSC-Signal zu erzeugen?> Ich denke man muss 'nur' etwas am Timing spielen. Aber wo?>> Gruß, Phil
Die Zeilenfrequenz ist ähnlich genug dass das laufen sollte. Du musst im
Prinzip nur die Anzahl der Zeilen um 50 reduzieren und es sollte laufen.
>Hey, prima. Endlich mal einer hier, der das auch mal benutzt .. !
Für nur eine Hand voll Euronen keinerlei Einschränkungen in Lagen, Pins,
Platinengröße - da kann man nicht meckern.
Bin aber gerade dabei mich in KiCad einzuarbeiten, das läuft dann auch
unter Linux und ist zudem ein "Opensource" Projekt.
Ich habe es auch mal versucht mit KiCad. Leider war es nicht so von
Erfolg gekrönt und noch etwas Buggy. Daher bleibe ich noch weiterhin bei
Sprint.
Aber vielleicht wirds ja was mit den nächsten Versionen von KiCad
Hallo, sorry, wenn ich diesen Thread mal wieder exhumiere... Hab die
Schaltung auf lochraster nachgebaut, und nen MAX232 mit integriert.
Leider erhalte ich mit der hier beschriebenen Beschaltung kein Bild, nur
ein paar Streifen flitschen über den Bildschirm. Wenn ich aber PIN 12
mit PIN 15 und PIN 16 verbinde dann gehts manchmal.
Kurioserweise scheint die Anwesenheit des MAX auch eine Rolle zuspielen,
ist der draussen gehts nicht, der MAX ist nur mit RXD, GND und +5V
verbunden
Klingt irgendwie alles nach Verdrahtungsfehler... hab aber alles schon
mehrfach überprüft. Es läuft dit 64-er version auf dem ATMega 8. Achso,
ist es egal welche der Quarz-Optionen ich wähle, hauptsache extern und
16 MHz?
MfG BC
@JanB
Finde das Projekt echt super kannst du dich mal bitte per Mail
bei mir melden hätte da einen Vorschlag zu machen ;)
Mail: thomas [at] heldt-web [punkt] de
Gruß
Thomas
Habs jetzt nochmal durchgetestet und bei mir muss PIN12 mit PIN 17
verbunden werden. Der 560 Ohm Widerstand ist komplett weg, nur dann hab
ich ein Bild. Die Diode ist auch gebrückt. Hat wer ne Erklärung dafür?
MfG BC
>> Tolles Projekt! Gibt es eine Möglichkeit anstatt eines PAL-Signals ein> NTSC-Signal zu erzeugen?> Ich denke man muss 'nur' etwas am Timing spielen. Aber wo?
so erst ma mein dank und respekt :):) top sache.
ich hab mich ma an das verstehen des codes gemacht und ihn etwas
erweitert und geändert. das ganze läuft jetzt erst ma auf nem ATMega32
so konnte ich den inputbuffer vergrößern und die register entlasten und
ich hab das ganze noch auf ne bus-schnittstelle umgeschreiben also 8 bit
datenbus und so is aber in den dokumenten beschrieben (wer lieber uart
haben will kann einfach den passenden teil im hsync aus dem original
nehmen, die initialiesireung kopieren und die funktionen mit
rückgabewert im term anpassen, aber das klingt nur nach viel arbeit).
mit dem bus lassen sich maximal 15KB pro sec übertragen (liegt am
interrupt) aber nach 256 Byte is halt der buffer voll.
Das ganze läuft stabil bis auf die erste pixel-zeile, die is ein bischen
verschwommen bzw schief.
wenn noch irgendwas unklar is könnt ihr mich ja anschreiben:
maltebrunn@web.de
mfg
Malte Brunn
Hallo. Auch wenn es bereits ein alter Thread ist: Ein tolles Ding.
Fand ich so gut, dass ich heute morgen die Version von Malte mit der
Version von Jan kombiniert habe. Dadurch kann auch beim Atmega32 die
serielle Schnittstelle verwendet werden.
Das Ergebnis ist im Anhang zusammen mit ein paar Bildern und dem
Quelltext. Das HEX-File kann direkt auf den Atmega32 gezogen werden. Die
Beschaltung ist die von Malte.
Grüße
Hallo,
gab es irgendwo die neuere Version von Jan mit verbessertem Scrollen ?
Soweit ich die verfuegbaren Quellen durchsehe sind diese noch auf dem
alten Stand.
Insgesamt ein super Projekt, lehrreich in Bezug auf Effizienz und
Optimierung.
Gruss
Werner
Ich habe diese Schaltung mal nachgebaut, und bin von deren Einfachheit
begeistert. Leider funktioniert das ganze nicht so wie ich mir das
vorstelle. Es reicht doch, einfach den gewünschten Text mit der
eingestellten Baudrate zu senden? Bei mir kommt kein Text, dafür jede
Menge Buchstabensalat und Leerzeichen. Ich verwende hterm + MAX232. Der
Starttext wird übrigens korrekt angezeigt. Kann mir jemand weiterhelfen?
Gruß,
Thorsten
Hallo Thorsten,
Frage: verwendest Du meine ATmega32 Adaption oder die Atmega8 Version?
Beim 32-er kann ich bestätigen, dass es mit einem Max232 (inkl.
Kondensatoren) korrekt funktioniert (vg. Screenshot). Wenn der Starttext
korrekt angezeigt wird, kann ich darauf schließen, dass Du Deine
Hardware (zumindest bis auf den Pegelwandler (weil es ja dort Probleme
geben könnte)) korrekt angeschlossen hast.
Grüße Niels
Was hast du in HTERM eingestellt? (ASC,DEC etc)
Ich erinnere mich, das das bei der aktuellen Version von HTERM ned so
richtig ging, desahlb verwende ich 0.65, versuchs mal damit..
Ich selbst habe - zugegeben nie die 8er Version in der Realität
ausprobiert. Sollte gar nichts funktionieren, dann kopiere aus meiner
32-Version den Teil des UARTS raus und setze diesen an geigneter Stelle
im 8er Text ein. Oder: Nimm einen 32er und ziehe das HEX-File auf den
Chip und probiere es dann noch mal.
Schade das der "optimierte" Code hier nie eingestellt wurde, hätte sowas
(einfaches) nämlich gern in meiner Haussteuerung, das ganze würde
nämlich einen extra PC zur Anzeige von Infos (Anruflisten, Alarme,
Temperatur etc pp) auf dem TV einsparen (der ja deutlich mehr Strom
braucht als ein Mega8).
Wär es ansonsten technisch möglich die Software so umzuschreiben das man
auf V/H-Sync von "aussen" reagiert (bzw. synchronisiert) und so zB. ins
laufende TV-Bild Text einblenden kann? Solche IC die soetwas per
Hardware erledigen sind leider endweder sehr schwer zu beschaffen (und
teuer) oder die verarbeiten nur reine RGB-Signale.
Ich habe das mal nachebaut, und hänge momentan beim selben Problem wie
Thorsten fest. Irgendwie habe ich das Gefühl, dass die Baudrate nicht
stimmt, obwohl ich im Terminalprogramm die eingestellt habe, die per
Jumper gesetzt ist und auch angezeigt wird. Eventuell, liegt es auch am
Interrupt zur Bilderzeugung, das der dem AVR die Ressourcen nimmt, und
somit keine Zeit zu Verarbeitung der UART-Daten hat. Ich programmiere in
C und habe daher kaum Assembler-Kentnisse. Wäre es möglich, dass sich
jemand mal den UART- und Interrupt-Teil ansieht?
Der UART:
1
;Init USART
2
;Baudratenjumper einlesen und auswerten
3
; und Baudrate anzeigen
4
;IO-Port lesen,
5
;Baudratenwerte aus Tabelle holen
6
in mpa,PIND
7
andi mpa,0b00011100 ;nur die Bits 2-4 interessieren
8
lsl mpa ;Tabellenzeile ist 8 Bytes lang
9
ldi ZH,HIGH(Baudtab<<1) ;auf Anfang der Tabelle
10
ldi ZL, LOW(Baudtab<<1)
11
add ZL,mpa ;Baudratennr. mal acht dazu
12
adc ZH,zero
13
lpm mpa,Z+ ;Baudratenwerte f¸r USART holen
14
lpm mpb,Z+
15
;USART Baudrate setzen
16
out UBRRH,mpb
17
out UBRRL,mpa
18
;Baudrate auf Screen anzeigen
19
ldi XH,HIGH(Charbuf+cpl*2);Position auf Bildschirm
20
ldi XL, LOW(Charbuf+cpl*2)
21
ldi mpb,6 ;6 Zeichen
22
baudl: lpm mpa,Z+ ; holen
23
st X+,mpa ; und im Charbuffer speichern
24
dec mpb
25
brne baudl
26
;USART einstellen und starten
27
baud2: ldi mpa,0x10 ;Receiver enable
28
out UCSRB,mpa
29
ldi mpa,0x86 ;8-Bit, 1 Stopbit, no Parity
30
out UCSRC,mpa
Der Interrupt:
1
nop ;Laufzeitausgleich
2
synclo ;Syncsignal Lo setzen
3
out tcnt0,t0rlv
4
in ssreg,SREG ;Statusreg retten
5
mov xhsi,XH ;X retten
6
mov xlsi,XL
7
8
ldi mpb,24 ;normale Hsynczeit
9
in mpa,UCSRA ;USART Status
10
andi mpa,0x80 ;Neuer Char da ?
11
breq hsync1 ;Nee
12
in mpa,UDR ;USART Data holen
13
ldi XH,HIGH(inbuf) ;X auf Start Input Buffer
14
ldi XL, LOW(inbuf)
15
add XL,ibupw ;Write-Pointer dazu
16
adc XH,zero
17
st X,mpa ;neuen Char ablegen
18
inc ibupw ;Pointer weitersetzen
19
ldi mpa,InBufSize-1;Pointer wraparound
20
and ibupw,mpa
21
subi mpb,4 ;Zeitausgleich f¸r Hsync
22
nop ; falls neuer Char da war
23
nop
24
hsync1: mov XH,xhsi ;Restore X
25
mov XL,xlsi
26
hsync2: dec mpb ;Restliche HSync-Zeit vertrˆdeln
27
brne hsync2
28
ijmp ;Ende Hsync
29
30
31
;Leerzeilen mit den Ausgleichsimpulsen
32
preq: synchi ;Syncsignal wieder auf HI
33
ldi mpa,144 ;1/2 Zeile abwarten
34
preqb: dec mpa
35
brne preqb
36
;Hsync Impuls auf 1/2 Zeile
37
cbi portd,6 ;Sync auf LO
38
ldi mpa,24
39
preqc: dec mpa
40
brne preqc
41
sbi portd,6 ;Sync zu¸ck auf HI
42
43
dec zz ;noch mehr Zeilen ?
44
brne preqd ;ja
45
ldi ZH,HIGH(vsync) ;danach kommt Vsync
46
ldi ZL,LOW(vsync)
47
ldi zz,vsyncl ;Anzahl setzen
48
preqd: endint ;das wars
49
50
51
52
;Vertical Sync
53
;damit f‰ngt jedes Bild an
54
vsync: ;1/2 Zeile minus HSync-Zeit abwarten, Sync bleibt noch LO
6512,5 schrieb:
> brne preqb> den befehl gibt es nicht. wer soen prog schrebt kann ncht mehr alle> haben.
wer so eine käse schreibt auch nicht.
"branch not equal" und das "label".
Kann sein, das es das beim 6512 nicht gibt.
Was mir dagegen noch unklar ist, warum sind Pin 15 und 17
zusammengeschalten?
Ernst
Wenn ich mich richtig entsinne, dann war das Low-Level bei 0,7Volt und
das Highlevel bei 1.0V. Beim Bildwechsel, dann wieder ein anderer Wert -
man ist das lange her - lege ich mich jetzt nich fest. Daher muss man
die Werte, jeweils über einen Widerstand geführt, zusammenlegen und
erhält das Gesamtsignal.
Jain, im Prinzip ja, nur wirst Du das nicht ganz sauber synchron
bekommen, da nicht jede Fernsehzeile genau 1024 Taktzyklen Deines
Quarzes lang ist.
Sprich Du wirst ein "Zittern" im Text haben von einem halben Pixel. Wenn
Du damit leben kannst, dann geht das, wenn nicht, dann musst Du deine
Taktfrequenz per PLL aus der Zeilenfrequenz erzeugen.
Probiern könnte es mann Ja.
Allerdings ist assembler nicht wirklich meine Sprache und wüsste gar
nicht wo ich Anfangen soll mit der synchronisation, könnte da mir jemand
bitte helfen?
Das ist tatsächlich etwas schwierig.
Die offensichtliche Lösung, einfach den Zeilenanfang auf einen Interrupt
zu geben, wird nicht wirklich funktionieren, da die Zeit zwischen
Interrupt und Ausführung der Interruptroutine stark schwankt.
Den Zeilenanfang bekommst Du beispielsweise über einen LM1881.
Was Du machen müsstest wäre es beispielsweise über eine externe Leitung
den Timer auf 0 zu setzen, oder den Wert des Timers zu speichern. Damit
weißt Du wann der Zeilenanfang war. Gleichzeitig kannst Du damit einen
Interrupt auslösen. Wenn der ausgeführt wird, schaust Du nach, auf
welchen Wert der Timer steht, und wie lange somit der Aufruf gedauert
hat. Das wertest Du, idealerweise, wie im Code oben über einen Sprung in
ein NOP-Feld aus.
mit nem PIC hab ich sowas mal gemacht. Geht auch ohne Zittern, so dass
das Bild 100% stabil steht. Weiß allerdings nicht mehr, ob ich die
Sourcen noch finde.
g_
Ja für den PIC gibts eine Lösung mit PLL die schon fertig ist. Wenn
Deine Pixel groß genug sind fällt das Zittern nicht auf. Wie schon
gesagt, das ist ein Taktzyklus.
Hallo,
da hat tatsächlich noch jemand diesen uralten Thread wieder ausgegraben.
Nee, nix für ungut, es freut mich ja, dass das Thema auch heute noch von
Interesse ist. :-)
Zur Frage:
Bastler schrieb:> Ist es möglich den Code umzuschreiben und umzubauen mit dem LM1881 das> man Text in ein vorhandenes Signal einblenden kann?
Klar geht das, hab ich damals (2006)auch schon probiert.
(Versuchsprogramm und -schaltung in Anhang.)
Das Programm wird durch die externe Syncronisation mit 1881 sogar noch
deutlich einfacher, weil der AVR des gesamte Videotiming nicht mehr
selbst erzeugen muss. Der Mega8 wartet nur auf den H-Sync oder V-Sync
auf zwei Interupt-Pins und haut demensprechend die Videodaten raus. In
dieser Versuchschaltung werden sie einfach mit Widerständen in das
externe Videosignal gemischt.
Funktioniert auch prima, aber wie Christan Berger weiter oben schon
völlig richtig anmerkt, gibt es einen Zeilenjitter von genau einem
Prozessortakt, also1/16MHz. Diesen Jitter sieht man leider ziemlich gut,
vor allem an senkrechten Kanten. Hier hat Christian auch schon einen
guten Lösungsvorschlag gemacht, nämlich den Prozessortakt per PLL aus
dem Zeilensyncsignal zu erzeugen. Da hab ich damals auch schon dran
gedacht. Aber ich hab es dann aufgegeben, weil eine PLL, die 16MHZ sehr
phasenstarr aus den H-Sync erzeugt, ist jedenfalls mit meinen
Kenntnissen, relativ aufwändig. Der eigentliche Charme der
AVR-Video-Schaltung, nämlich die Einfacheit und die geringe Anzahl von
Bauteilen ginge verloren. Da kann man gleich einen "echten" OSD-Baustein
nehmen.
Christian Berger schrieb:> Die offensichtliche Lösung, einfach den Zeilenanfang auf einen Interrupt> zu geben, wird nicht wirklich funktionieren, da die Zeit zwischen> Interrupt und Ausführung der Interruptroutine stark schwankt.
Kein Problem, wenn Du dafür sorgst, dass der AVR zum Interruptzeitpunkt
im Sleep-Modus ist, dann ist die Int-Latenz konstant und vorhersehbar.
Aber: Bis auf einen Prozessortakt, weil das externe Signal eben
irgendwann innerhalb des Taktes kommt.
Christian Berger schrieb:> externe Leitung> den Timer auf 0 zu setzen, oder den Wert des Timers zu speichern. Damit> weißt Du wann der Zeilenanfang war. Gleichzeitig kannst Du damit einen> Interrupt auslösen. Wenn der ausgeführt wird, schaust Du nach, auf> welchen Wert der Timer steht, und wie lange somit der Aufruf gedauert> hat.
Unnötig kompliziert, und löst das Problem nicht, du bräuchtest einen
Timer der viel schneller zählt, als der Prozessortakt.
g_ schrieb:> Hab damals sogar das Taktzyklus-Zittern rausbekommen.
Wie denn? Das würde mich wirklich mal interessieren.
Wäre schön, wenn Du da noch ein paar genauere Infos ausgraben könntest.
Also wie gesagt, Testprogramm + Schaltung im Anhang
Gruß Jan
Hallo Christian,
Christian Berger schrieb:> Naja, der Trick mit dem Sleep funktioniert nicht immer, nur dann wenn> das Hauptprogramm nicht lange läuft. Das wäre mir zu unzuverlässig.
Wenn das Hauptprogramm, wie in diesem Fall, so schön kurz und
übersichtlich ist, dann klappt das ganz sicher. :-)
mloop: sleep
rjmp mloop
Gruß Jan
Richtig, aber wenn man schon was einblendet, möchte man ja den Rest des
Controllers auch noch nutzen. :) Klar, dass kann man auch in die Zeilen
ISR einbauen, aber will man das immer?
>> Hab damals sogar das Taktzyklus-Zittern rausbekommen.>Wie denn? Das würde mich wirklich mal interessieren.
Es war ein PIC, der mit einem externen RC Oszillator betrieben wurde.
Der Zeilenimpuls hat den RC Oszillator dann entladen, also gezielt auf
Phase 0° gesetzt.
Hier hab ich das bei einem ähnlichen Projekt, aber ohne µC gemacht:
http://sebulli.com/Logomat/index.html
Da der PIC (im Gegensatz zum Atmega) jedoch einen Systemtakt pro 4
Oszillatortakte macht, hab ich noch einen Flipflop hinzugefügt.
Die Software setzt kurz vor dem erwartenden Zeilensync einen Port, der
daraufhin den RC Oszillator stoppt. Also ähnlich einem Sleep.
Der Zeilensyncimpuls startet diesen wieder. Mit Phase 0°.
War damals ein Projekt, um die Uhrzeit einzublenden.
gerd
Auch eine schöne Lösung, aber hier ist die mit PLL.
http://dt.prohosting.com/pic/vidclock.html
U4 könnte man sich sparen, da die Taktteilung durch 1024 auch der
Mikrocontroller machen kann.
Hallo zusammen,
Auch von mir Respekt Respekt!
Ich war auf der Suche um in ATV, (ATV= AmateurTeleVision), also
Amateurfunk Fernsehen, über einen Mischer zbs. mein Rufzeichen und
Standort Info´s über meinen Sender zu schicken...
Ich werde mir die Schaltung(en) mal aufbauen und Testen,
selbstverständlich werde ich dann auch auch hier darüber Berichten..
Vielen Dank für den Thread und den Autor(en)
Bis dann 73s de Norby aus dem Sauerland
Da der Meister tatsächlich 6 Jahre später nochmal in diesem Thread
geantwortet hat, versuche ich auch nochmal mein Glück:
Erst einmal mehr als Respekt für dieses kleine Stück einfacher Technik.
Alles aufgebaut und funktioniert super. Bei mir läuft die
vidterm64-Version mit Mega 8-16 als eine Art Grafikkarte in einer
8Bit-Konsole auf Basis eines ATMega32 als Mainboard. Wird ein
Xmas-Geschenk für die Freundin.
Meine Frage: Mit jedem neuen Zeichen das ich Drucken lasse, flackert bei
mir das Bild kurz. Ich nehme an, hier schreibt der Mega den neuen
Bildschirminhalt in den Speicher. Kann man dieses Flackern irgendwie
umgehen? Du hattest ja mal geschrieben, dass der Code nochmal
überarbeitet wurde.
Sorry für vielleicht hohle Fragen. Ich beschäftige mich erst seit einem
1/2 Jahr mit der ATMega-Materie als Autodidakt und programmiere in C.
Danke für Deine Antwort.
Nee, flackern darf da nichts.
Das Schreiben in den Bildspeicher geschieht transparent im Hintergrund.
(gleich am Anfang im Abschnitt hsync)
Da muss etwas mit deiner Schaltung nicht stimmen.
Gruß Jan
>Die offensichtliche Lösung, einfach den Zeilenanfang auf einen Interrupt>zu geben, wird nicht wirklich funktionieren, da die Zeit zwischen>Interrupt und Ausführung der Interruptroutine stark schwankt.
Wenn man den Atmega vorher in den Sleep Mode schickt, dann wird die
Ausführungszeit konstant, siehe
http://www.batsocks.co.uk/readme/art_SerialVideo_3.htm
Darko schrieb:> Wenn man den Atmega vorher in den Sleep Mode schickt, dann wird die> Ausführungszeit konstant, siehe> http://www.batsocks.co.uk/readme/art_SerialVideo_3.htm
Ja, aber man kann dann quasi nichts mehr neben der Videoausgabe machen.
Da ist die einfache Lösung über den Timerwert abzufragen und in ein
NOP-Feld zu springen schon besser.
hello everybody
i made this circuit "avrovrl" and i have connected with usart
now how i write a character to screen
i want write a character on middle of screen
please help me!
http://s5.picofile.com/file/8120331426/DSC00064.jpg
in "avrovrl1.asm"
.EQu RandOben = 60 ;Oberer Rand
.EQU RandLinks = 45 ;Linker Rand
"RandOben" means upper Margin
"Randlinks" means left Margin
What do you have to change to write in the middle of the screen?
Any Ideas? :)
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang