PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : umsetzen für win-avr



pebisoft
30.01.2005, 08:43
hallo, kann einer mal dieses program umsetzen in winavr. es soll zeichen mit dem avr auf dem bildschirm darstellen (fbas). da wenig c-code drin ist (das meiste sind zeichen ),müsste es eigentlich für einen c-pro. nicht schwer sein. es ist für viele interessant.
:


//video gen
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor

#include <Mega163.h>
#include <stdio.h>

//cycles = 63.625 * 8 Note NTSC is 63.55
//but this line duration makes each frame exactly 1/60 sec
//which is nice for keeping a realtime clock
#define lineTime 509

#define begin {
#define end }
#define ScreenTop 30
#define ScreenBot 230
#define T0reload 256-60

//NOTE that the first line of CHARs must be in registers!
char syncON, syncOFF, v1, v2, v3, v4, v5, v6, v7, v8;
int i,LineCount, time;
char ballx, bally, dx, dy;
char screen[800], t, ts[10], temp;

flash char bitmap[13][8]={
//0
0b00000000,
0b00111000,
0b01000100,
0b01000100,
0b01000100,
0b01000100,
0b01000100,
0b00111000,
//1
0b00000000,
0b00010000,
0b00110000,
0b01010000,
0b00010000,
0b00010000,
0b00010000,
0b01111100,
//2
0b00000000,
0b00011100,
0b00100010,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00111110,
//3
0b00000000,
0b00011100,
0b00100010,
0b00000010,
0b00011100,
0b00000010,
0b00100010,
0b00011100,
//4
0b00000000,
0b00001110,
0b00010010,
0b00100010,
0b00111111,
0b00000010,
0b00000010,
0b00000010,
//5
0b00000000,
0b00111100,
0b00100000,
0b00100000,
0b00011100,
0b00000010,
0b00000010,
0b00111100,
//6
0b00000000,
0b00010000,
0b00100000,
0b00100000,
0b00111100,
0b00100010,
0b00100010,
0b00011100,
//7
0b00000000,
0b00111111,
0b00000001,
0b00000001,
0b00000010,
0b00000010,
0b00000100,
0b00000100,
//8
0b00000000,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
//9
0b00000000,
0b00011110,
0b00100001,
0b00100001,
0b00011110,
0b00000001,
0b00000001,
0b00000010,
//C
0b00000000,
0b00011110,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00100000,
0b00011110,
//U
0b00000000,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b01000010,
0b00111100,
//E
0b00000000,
0b00111111,
0b00100000,
0b00100000,
0b00111111,
0b00100000,
0b00100000,
0b00111111};


//This is the sync generator. It MUST be entered from
//sleep mode to get accurate timing of the sync pulses
//At 8 MHz, all of the sync logic fits in the 5 uSec sync
//pulse
interrupt [TIM1_COMPA] void t1_cmpA(void)
begin
//start the Horizontal sync pulse
PORTD = syncON;
//count timer 0 at 1/usec
TCNT0=0;
//update the curent scanline number
LineCount ++ ;
//begin inverted (Vertical) synch after line 247
if (LineCount==248)
begin
syncON = 0b00100000;
syncOFF = 0;
end
//back to regular sync after line 250
if (LineCount==251)
begin
syncON = 0;
syncOFF = 0b00100000;
end
//start new frame after line 262
if (LineCount==263)
begin
LineCount = 1;
end
//end sync pulse
PORTD = syncOFF;
end

// put a character on the screen
// x-cood must be on divisible by 8 x position
void video_putchar(char x, char y, char c)
begin
i=((int)x>>3) + ((int)y<<3) ;
screen[i] = bitmap[c][0];
screen[i+8] = bitmap[c][1];
screen[i+16] = bitmap[c][2];
screen[i+24] = bitmap[c][3];
screen[i+32] = bitmap[c][4];
screen[i+40] = bitmap[c][5];
screen[i+48] = bitmap[c][6];
screen[i+56] = bitmap[c][7];
end

// set up the ports and timers
void main(void)
begin
//init timer 1 to generate sync
OCR1A = lineTime; //One NTSC line
TCCR1B = 9; //full speed; clear-on-match
TCCR1A = 0x00; //turn off pwm and oc lines
TIMSK = 0x10; //enable interrupt T1 cmp

//init ports
DDRD = 0xf0; //video out and switches
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor

//init timer 0 to 1/uSec
TCCR0 = 2;

//initialize synch constants
LineCount = 1;
syncON = 0b00000000;
syncOFF = 0b00100000;

//side lines
for (i=0;i<799;i=i+8)
begin
screen[i]=0b10000000;
screen[i+7]=0b00000001;
end
//top line & bottom lines
for (i=0;i<8;i++)
begin
screen[i]=0b11111111;
screen[i+792]=0b11111111;
screen[i+88]=0b11111111;
screen[i+712]=0b11111111;
end

//initial ball to middle of screen
ballx=32;
bally=50;
dx = 1;
dy = 2;
//The following odd construction
//sets exactly one bit at the x,y location
i=((int)ballx>>3) + ((int)bally<<3) ;
screen[i] = 1<<(7-(ballx & 0x7)) ;

//init software timer
t=0;
time=0;

//enable sleep mode
MCUCR = 0b01000000;
#asm ("sei");

//The following loop executes once/video line during lines
//1-230, then does all of the frame end processing
while(1)
begin

//precompute pixel index for next line
if (LineCount<ScreenBot && LineCount>=ScreenTop)
begin
//left-shift 3 would be individual lines
// <<2 means line-double the pixels
//The 0xfff8 truncates the odd line bit
i=(LineCount-ScreenTop)<<2 & 0xfff8;;

end

//stall here until next line starts
//sleep enable; mode=idle
//use sleep to make entry into sync ISR uniform time

#asm ("sleep");

//Put code here to execute once/line
//During the active portion of a line;
//--TCNT1 goes from about 130 to about 480
//--Usable lines 1 to about 240

if (LineCount<ScreenBot && LineCount>ScreenTop)
begin
//load the pixels into registers
v1 = screen[i];
v2 = screen[i+1];
v3 = screen[i+2];
v4 = screen[i+3];
v5 = screen[i+4];
v6 = screen[i+5];
v7 = screen[i+6];
v8 = screen[i+7];

//now blast them out to the screen
PORTD.6=v1 & 0b10000000;
PORTD.6=v1 & 0b01000000;
PORTD.6=v1 & 0b00100000;
PORTD.6=v1 & 0b00010000;
PORTD.6=v1 & 0b00001000;
PORTD.6=v1 & 0b00000100;
PORTD.6=v1 & 0b00000010;
PORTD.6=v1 & 0b00000001;

PORTD.6=v2 & 0b10000000;
PORTD.6=v2 & 0b01000000;
PORTD.6=v2 & 0b00100000;
PORTD.6=v2 & 0b00010000;
PORTD.6=v2 & 0b00001000;
PORTD.6=v2 & 0b00000100;
PORTD.6=v2 & 0b00000010;
PORTD.6=v2 & 0b00000001;

PORTD.6=v3 & 0b10000000;
PORTD.6=v3 & 0b01000000;
PORTD.6=v3 & 0b00100000;
PORTD.6=v3 & 0b00010000;
PORTD.6=v3 & 0b00001000;
PORTD.6=v3 & 0b00000100;
PORTD.6=v3 & 0b00000010;
PORTD.6=v3 & 0b00000001;

PORTD.6=v4 & 0b10000000;
PORTD.6=v4 & 0b01000000;
PORTD.6=v4 & 0b00100000;
PORTD.6=v4 & 0b00010000;
PORTD.6=v4 & 0b00001000;
PORTD.6=v4 & 0b00000100;
PORTD.6=v4 & 0b00000010;
PORTD.6=v4 & 0b00000001;

PORTD.6=v5 & 0b10000000;
PORTD.6=v5 & 0b01000000;
PORTD.6=v5 & 0b00100000;
PORTD.6=v5 & 0b00010000;
PORTD.6=v5 & 0b00001000;
PORTD.6=v5 & 0b00000100;
PORTD.6=v5 & 0b00000010;
PORTD.6=v5 & 0b00000001;

PORTD.6=v6 & 0b10000000;
PORTD.6=v6 & 0b01000000;
PORTD.6=v6 & 0b00100000;
PORTD.6=v6 & 0b00010000;
PORTD.6=v6 & 0b00001000;
PORTD.6=v6 & 0b00000100;
PORTD.6=v6 & 0b00000010;
PORTD.6=v6 & 0b00000001;

PORTD.6=v7 & 0b10000000;
PORTD.6=v7 & 0b01000000;
PORTD.6=v7 & 0b00100000;
PORTD.6=v7 & 0b00010000;
PORTD.6=v7 & 0b00001000;
PORTD.6=v7 & 0b00000100;
PORTD.6=v7 & 0b00000010;
PORTD.6=v7 & 0b00000001;

PORTD.6=v8 & 0b10000000;
PORTD.6=v8 & 0b01000000;
PORTD.6=v8 & 0b00100000;
PORTD.6=v8 & 0b00010000;
PORTD.6=v8 & 0b00001000;
PORTD.6=v8 & 0b00000100;
PORTD.6=v8 & 0b00000010;
PORTD.6=v8 & 0b00000001;

PORTD.6=0 ;
end

//The following code executes during the vertical blanking
//Code here can be as long as 63 uSec/line
//For a total of 30 lines x 63.5 uSec/line x 8 cycles/uSec
// Every 60 uSec or so, you should insert a "sleep"
//command so that the timer 1 ISR happens at a regular interval,
//but it may not matter to most TVs

if (LineCount==231)
begin
//erase old ball
i=((int)ballx>>3) + ((int)bally<<3) ;
temp = screen[i];
screen[i] = temp ^ (1<<(7-(ballx & 0x7)));

//get new x
ballx = ballx + dx ;
if (ballx>61) dx = -1;
if (ballx<2) dx = 1;
//if (PIND.0==0) dx=dx*2;

//get new y
bally = bally + dy ;
if (bally>86) dy = -1;
if (bally<14) dy = 1;
//if (PIND.1==0) dy=dy*2;

// write new ball
i=((int)ballx>>3) + ((int)bally<<3) ;
temp = screen[i];
screen[i] = temp | (1<<(7-(ballx & 0x7)));

// #asm ("sleep");

if (t++ > 59)
begin
t=0;
time++;

//Print "CU-ECE476"
video_putchar(0,2,10);
video_putchar(1*8,2,11);
video_putchar(2*8,2,12);
video_putchar(3*8,2,10);
video_putchar(4*8,2,12);
video_putchar(5*8,2,4);
video_putchar(6*8,2,7);
video_putchar(7*8,2,6);
//make a dash
i=(16>>3) + (6<<3) ;
screen[i] = screen[i] | 1<<(7-(16 & 0x7)) ;

//print the time
sprintf(ts,"%05i",time);
video_putchar(0,90,ts[0]-0x30);
video_putchar(1*8,90,ts[1]-0x30);
video_putchar(2*8,90,ts[2]-0x30);
video_putchar(3*8,90,ts[3]-0x30);
video_putchar(4*8,90,ts[4]-0x30);
end


end

end //while
end //main


mfg pebisoft

PicNick
30.01.2005, 15:43
Hi, pebi ! Richtige Begeisterung löst der Thread ja scheinbar nicht aus. Ich hab mir das mal Interessehalber angeschaut und den Winavr gefragt, was er davon hält.
Im Prinzip sieht er ja kaum syntaktische Probleme, is ja schließlich auch C. Wieso brauchst du Hilfe ?
Wo hast du das her ? Für (von) welchen Compiler is das ?

Zur Sache: Hast du das Zeugs schon mal laufen gesehen ? Und wie sieht das aus ? Die Sequenz, wo er die Pixeln rausbläst, kommt mir, (je nach "1" oder "0") unregelmäßig vor, müßt man noch genau behirnen.

Wo ich als ungeübter WInAvr und Atmel unsicher bin, ist die Einstellung des Timers und wie er (welchen) Sleep mode einsetzt, damit das ganze funzt.
Ein voller ASCII-Zeichengenerator würde halt ganz schön Platz brauchen,
da sollt man einen externen EPROM schießen.
laß hören ! mfg robert

pebisoft
30.01.2005, 17:31
hallo, diese programm läuft auf einem meg163 und stellt ein video-signal in der fbas-form dar. also fbas-signale (buchstaben) mit einem avr auf dem bildschirm darstellen/anzeigen. habe ich aus einem englischen forum. das fernsehbild war im forum zusehen, weis aber nicht mehr welches es ist.
da ich im bascom-forum ähnliches mit dem avr16 schon dargestellt und veröffentlicht habe (album,persönliche galerie/pebisoft) interessiert mich diese umsetzung. diese lässt sich eigentlich nur in asm darstellen, wenn es auch mit winavr ginge käme mir das entgegen.
das signal d5/d6 läuft je über einen widerstand und wird nach dem widerstand wieder zusammgeführt zum eingang fbas und als bild dargestellt.
mfg pebisoft

PicNick
30.01.2005, 18:05
Alles klar, (erinnert mich an die ZX81 Zeit)
Es sind ja folgende Dinge zu tun
1 das eigentliche Spiel, oder was das Werkel halt tun soll.
2 das Vorbereiten der nächsten Zeile
3 und dann halt das eigentliche rausshiften der s/w Pixel nach dem horz.Sync
Prinzipiell macht der C das Ganze um nix schlechter als der Assembler, (er läßt sich ja in die Karten gucken) grad', daß man im Assembler ein paar (wenige) Dinge etwas mehr auf den Zweck zuschneidern und dadurch optimieren kann.
bei 1 u. 2 bist du in eine höheren Sprache sicher in Summe besser dran, da krachen dir sonst die Finger.
3 ist zeitkritisch und wahrscheinlich mit inline assembler gut zu unterstützen.
Konkret: ich häng mal das, was ich hab, hier rein. is ja egal, übersetzen kann man es zumindest flagfrei, die Logik hab ich nicht überprüft, ich würde das sicher anders lösen, ich kenn mich ja.
Wenn du dich mit WinAvr auskennst, den Timer richtig aufsetzen kannst du wahrscheinlich eh besser.
Ob die Zeiten hint und vorn auch reichen, hab ich nicht nachgerechnet.
egal, schau mal rein mfg robert

Kjion
30.01.2005, 18:13
@PicNick

Wenn dein WinAVR da nicht meckert ists aber komisch. Ich hab mal angefangen das ganze umzusetzen, allerdings gibts da ein Problem:

PORTD.6=v5 & 0b10000000;
PORTD.6=v5 & 0b01000000;
PORTD.6=v5 & 0b00100000;
PORTD.6=v5 & 0b00010000;
PORTD.6=v5 & 0b00001000;
PORTD.6=v5 & 0b00000100;
PORTD.6=v5 & 0b00000010;
PORTD.6=v5 & 0b00000001;

Wie Zeitkritisch sind diese Dinger ?? Bzw. wie schaut der Assemblercode der dazu generiert wird aus. Das muss man nämlich in WinAVR anders lösen. Ansonsten ist aber kein Problem, musste eingentlich nicht viel ändern...

MfG Kjion

PicNick
30.01.2005, 18:24
Wo hast du das her ? fbas.c ?
Du hast recht, da weigert er sich.
Um den erzeugten asm code zu überprüfen, hab ich eine für diese Formulierung passende struktur reingeschrieben (muster). Aber im Asm Code hab ich gesehen, is auch nicht besser (bzw. gleich) als der dann in fbas.c
Schleifen-konstrukte in jeglicher Form sind wesenrlich mieser, der Spaghetti-Code schaut saumäßig aus, is aber am schnellsten.
mfg robert

Kjion
30.01.2005, 18:29
;-)
Ich war nur zu spät mit dem posten, hatte deinen letzten Beitrag noch gar nicht gesehen. Es bezog sich auf die ursprüngliche Variante...

Der Code von dir sieht schon wesentlich besser aus...

MfG Kjion

pebisoft
30.01.2005, 19:33
hallo, vielen dank für die mühe, die übersetzung in winavr läuft 100%.
das bild ist noch nicht da. werde weiter dran arbeiten.
mfg pebisoft

pebisoft
30.01.2005, 19:40
hallo, ich habe am 15.1 schon einmal die frage gestellt mit einem programm für den atmega32, dieses müsste funktionell gehen.
kannst du das mal prüfen. ich glaube dieses für den m132 hat total andere zeiten für die sync.
mfg pebisoft

PicNick
31.01.2005, 07:16
Hi, pebi !
Ich muß mir das Programm funktionell einmal reinziehen und kann dann hoffentlich ein bißchen gescheiter mitreden.
Ich hab da das RNBFRA1.2-Board, muß mal schauen, ob ich da eine Teststellung für Video ohne Lötkolben hinkriege.
Dann kann ich auch mit dem Oszi u. Monitor mal gucken, was da eigentlich rauskommt.
Ich hätt mir wohl doch den ZX oder den Spectrum aufheben sollen.
mfg robert

pebisoft
31.01.2005, 10:57
hallo, das wäre nett. ich bin zur zeit in einer sackgasse zwischen c und asm. mir wäre c lieber. ich könnte mir vorstellen, die vorurteile abzubauen wenn ich auch erfolge sehe. da ich die in letzter zeit nicht hatte (i2c,lcd, srf04, sharp, compassmodul i2c, pwm-motor), habe ich mehr in bascom prgrammiert. ich hoffe das ich evtl einmal die kurve zu c (winavr) bekomme. übrigens, die anschlüsse für die antenne (fbas) werden einfach über widerstände an die vorgegebenen pins angeschlossen und am ausgang gemeinsam der fbas-leitung zugeführt. ohne löten. ich habe ein muster in "persönliche galerien, pebisoft".
es ist eigentlich keine zauberei. nur der c-code ist nicht einfach.
ich feue mich auf das ergebnis, vielen dank für die mühe.
mfg pebisoft

PicNick
31.01.2005, 11:54
Zwischenbericht:
Ich mach (versuche) grad eine Translation MEGA163 --> MEGA32
ein paar Weisheiten schon gefunden, klar daß das nicht geht.
Dann muß man schauen NTSC --> PAL, kann aber sein, daß das für s/w garnicht so tragisch ist, der Farbträger is uns ja eh wurst.
Vielleicht finden wir ja noch einen TV-Guru, der einen RGB->Fbas Mixer macht.
Asm <> C :
Ich persönlich hab' mit Assembler begonnen für die unmöglichsten Kisten.
Da mußte man oft noch einem Einser auf den Schädel hauen, damit er ein Nuller wird.
Wenn man dann aber ein bißchen sauberen Code schreiben will, mit Speicherstrukturen und sauberen Function-Calls, die man nach einem halben Jahr wenigstens selbst noch nachvollziehen kann, sieht man, daß einem C eigentlich genau da viel Arbeit abnimmt, ohne einzuschränken, auch ohne inline assembler. Ich find', C ist im Grunde nix als ein Assembler in Hochdeutsch. Im Gegensatz zu wirklichen Hochsprachen setzt er eh alles 1:1 auf assembler um, man muß ihm halt auf die Finger schauen, kann man ja.
Als Assemblerprogrammierer muß (und kann) einem halt klar sein, was man dem Kerl mit locker abgesetzten standard-calls antut.
Also schreib mal ein for-next schleifchen und schau dir das Assembler Produkt an. Wenn man ehrlich ist, kann man's meist kaum besser assemblen. Man muß ihm halt helfen und statt C = A * 8 --> C = A << 3 hinschreiben, klar, woher soll er das wissen.
mfg derweil robert

pebisoft
31.01.2005, 12:18
hallo, vielen dank für deinen zwischenbericht.
mfg pebisoft

PicNick
31.01.2005, 13:30
Translate die Nächste:
Ich hab halt versucht, mega163/mega32 umzusetzten, schau'n wir mal.

Ich hab nicht durchschaut, warum er den Timer0 setzt (1*10^-6)sec
(prescale 8 )

Die Zahl 509 ist ausschlaggebend für die Zeit/Zeile und ergibt bei 8MHZ dzt 63.625 microSec (NTSC). Pal is ja etwas länger, da konnt man was anderes probieren, aber schau erst mal, ob sich überhaupt was bewegt.

Was er will is klar: Timer1 auf Match/Compare damit er jede Zeile einmal interrupted, da schickt er dann den Zeilen sync (neg) am Bildende steigt er um auf Frame-sync. Durch den Interrrupt weckt er MAIN aus dem Sleep , der dann seine Pixeln runterrattert und hoffentlich innerhalb der Zeile auch fertig wird. In der horz. Austastlücke und außerhalb des sichtbaren bereiches bastelt er seinen Zeichen zusammen und zählt die Frames. bei >59 (NTSC hat 2*30 Frames) is eine Sekunde rum, das zeigt er dann her. den Ball pickt er dzt. irgendwo hin, der sollt sich nicht bewegen, is auch nur ein Template.
Wie gesagt, schau mal, ob der Fernseher überhaupt irgendwie reagiert.
mfg robert

EDIT PS: vielleicht muß man doch TCCR1B = 9 schreiben , hol's der Geier, ausprobieren

pebisoft
31.01.2005, 17:09
hallo, vielen dank. das programm wird übersetzt mit winavr.
es ist schon etwas auf dem bildeschirm zu erkennen.
ich muss jetzt, wie du gesagst hast ein bisschen mit dem timer
jonglieren. vielen dank noch einmal.
mfg pebisoft

PicNick
31.01.2005, 17:56
Das freut mich mehr, als du denkst.
Ich hätt ja nicht gewettet drauf.
Du läßt ja gelegentlich hören, wie's läuft ?
:) Wird das eine neue Funktion auf deinem Küchenbrett ? :)
mfg robert

pebisoft
31.01.2005, 18:20
hallo, in "album,persönliche galerie, pebisoft" habe ich die erste version
von winavr reingestellt. vielen dank für den ersten erfolg.
"tccr1b" habe ich auf 2 gestellt.
mfg pebisoft

PicNick
31.01.2005, 18:46
Mit der Synchronisation hat's was. Vielleicht wird er mit der Zeile nicht "in-time" fertig.
Versuch: es scheint wichtig zu sein v1-v8 in registern zu haben.
versuch vielleicht einmal (aus der Doku)

register unsigned char v1 asm ("r3");
.....
register unsigned char v8 asm ("r10");

vielleicht bringt das was mfg

pebisoft
01.02.2005, 08:22
hallo, habe die register eingesetzt. das bild hat sich ein bisschen geändert aber nicht wesentlich. gibt es beim timer vielleicht ungereimtheiten beim runterrasseln.
mfg pebisoft

PicNick
01.02.2005, 08:49
Ja, am Timing dürft's liegen. Ich würd mal alles Brimborium Zechengenerator etc, auskommentieren und nur einen senkrechten Strich fix encoded türken, damit man einmal das Bild stabil hinkriegt. Dann erst wieder step-by-step ausbauen.
Er beschreibt ja beim Original ganz schön detailliert, wie er sich langsam mit trial-and error hingehantelt hat, werd das nochmal genau lesen
Wie gesagt, muß mal schauen, wie ich mir eine Teststellung zusammenstricken kann. Vor allem einen geeigneten Monitor muß ich finden, gar nicht so einfach vor lauter VGA Schirmen. Vielleicht geht's über den Video-rekorder, mal sehen. mfg robert

pebisoft
01.02.2005, 16:56
hallo, ich möchte mit winavr ein experiment machen, natürlich mit deiner hilfe,
weil ich in c "noch nicht" weiterkomme.
für eine bildzeile braucht der strahl 0,000064 sec.
für den rücklauf 0,000012 sec.
bleiben für den sichtbaren strahl 0,000054 sec.
ich möchte jetzt 10 zeilen schreiben, die bei 0,000020 anfangen
und bei 0,000030 aufhören. in dieser zeit muss der pind5 mit 300ohm
an die antenne geführt werden (hellgrau).
von 0,000000 bis 0,000019 und von 0,000031 bis 0,000054 mit 1kohm
mit pind4 an die antenne geführt werden(schwarz). normal müsste ungefähr in
der mitte ein senkrechter (natürlich wahrscheinlich ein bisschen gezackt)
von 10 zeilen länge ein hellgrauer balken zu sehen sein.
könntest du mir das einmal schreiben, ich glaube diesen grundstock
könnte man weiterentwickeln. wichtig ist , das man erst einmal begreift
wie man den elektronenstrahl beeinflussen kann.
hardware : atmega8 oder 16 mit 8mhz.
mfg pebisoft

pebisoft
01.02.2005, 17:43
hallo, habe ich einen denkfehler gemacht?
wie wird eigentlich die sync des elektronenstrahls
zum avr gesendet, oder andersherum, bei den jetzigen programmen,
wo liegt die syncabtastung damit der avr richtig anfangen pro zeile.
oder ist es zufall wann der avr senden muss (0,7v) für den hellgrauen punkt.
mfg pebisoft

PicNick
01.02.2005, 18:52
Klar, minimalistisch fangen wir an, damit wir das in den Griff kriegen.
Ich fang' mal an und schau, wieweit ich komm und stell das rein.
Sync: Wie du richtig sagst, eine Zeile dauert von links nach rechts 64 uS.
alle 64 uS gibts den Interrupt. Der zieht für 5 uS den Sync-Pin (5) runter.
Das ist das Zeichen für den TV, mit einer neuen Zeile anzufangen.
dann muß eine kurze (hab's jetzt nicht im Kopf) Pause sein (Schwarz-Schulter)
Und dann werden die S/w Pixel rausgeschossen, was halt geht.
Schnell->schmales Bild / langsam->breiter
dann wartet das Programm auf den nächten 64uS Interrupt (sleep)

Oben und unten am Bild werden die Sync-Signale umgedreht, das is für die Bildsynchronisation.

Der Abstand Sync <> erster Bildpunkt is nicht so heikel, das kann man bei einem Monitor z.B. nachstellen (Bild mehr rechts/mehr links)
ebenso wie Bild rauf/runter und auch die sichtbare Breite

Das Beispiel ist halt für NTSC gemacht, die haben nur 525 Zeilen (wir haben 625), da müssen wir basteln, sonst läuft das Bild vertikal durch.

Gut, ich fang mal an. mfg robert

PicNick
01.02.2005, 19:37
Soderla. Beta release 0.nix
Ist noch für Mega32 , ich brauch erst das Sheet vom Mega8, daß ich mitreden kann
Die Zeilen hab ich für PAL angepaßt
theoretisch macht das programm nix als einen weißen Strich mittig (circa)

Setz dir den Helm auf und ab die Post. bis morgen mfg robert
(Ändere, was du magst, ich hab eh eine Kopie)

pebisoft
01.02.2005, 20:01
hallo, vielen dank für die hilfe.
mfg pebisoft

pebisoft
01.02.2005, 21:33
hallo, der bildschirm ging von weiss auf schwarz innerhalb
von 2sec. danach habe ich "case 160", "case 314", "case348" von
oben nach unten neu gesetzt. das bild ist im album,persönliche galerie, pebisoft.
mfg pebisoft

PicNick
02.02.2005, 08:30
Guten Morgen
Du meinst die "select" in der Interruptroutine ?
Das Bild ist, so wie es ist, stabil ?
Scheint nicht ganz weiß zu sein, aber das ist kein Problem, müßt man sich die Addierschaltung anschauen.
Ich fürcht' nur, der Balken ist für die Logik zu breit.
Prüfung:
lösch mal von den Zeilen
PORTD |= 0x40; // white
alle, bis auf eine, dann muß der Balken schmäler werden (ein Pixel) und man sieht, ob er auch wirklich innerhalb einer Zeile fertig wird.
man hört, mfg robert

pebisoft
02.02.2005, 09:33
hallo, habe heute gerade gelesen, das das deutsche
forschungswirken ins ausland verlagert wird.
ich hoffe , das man mit diesem avr-projekt (video mit avr 16/32)
hier in deutschland wieder zeigt ,das es auch im inland
noch ein knowhow gibt. es ist eine interessante sache wenn man die
fernsehelektronik (bilddarstellung) mit einfachen mitteln (avr16/32)
vermitteln kann. ich kann mich noch drab erinnern, das ich mir vor 25 jahren
mal einen elektronkikasten gekauft habe (sau teuer) mit einer kleinen
bildröhre um das darzustellen woran ihr gerade forscht. diese versuche waren damals
noch sehr mickrig. was ihr heut macht ist eien tolle sache. man lernt c und gleichzeitig
bekommt man einen sehr guten einblick in die bildübertragungs- und darstellungstechnik
mit einem einfachen avr16/32 für ca 6 euro.
vielleicht könnt ihr damit einen neuen innovations-elektronik-kasten entwickeln.
mfg pebisoft

pebisoft
02.02.2005, 09:51
hallo, die helligkeit des balken wird
durch den widerstand bestimmt der vor dem antenneneingang liegt.
die graustufen/schwarz/weiss werden von 0,3v bis 1v geregelt.
je nachdem über welchen pin die daten geschickt werden kann man verschiedene
grautöne erzeugen, es kommt auch auf die einstellung des fernsehers an.
bei 0v bis 0,2v wird der elektrodenstrahl dunkel, für den rücklauf (sync-pin).
ich habe jetzt mal alle herausgenommen (weiss/schwarz), trotzdem erscheint der balken
unverändert.
mfg pebisoft


//video gen
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor


#include <inttypes.h>
#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

// cycles = 63.625 * 8 Note NTSC is 63.55
// but this line duration makes each frame exactly 1/60 sec
// which is nice for keeping a realtime clock

#define lineTime 509 // Timer1 Match Value (8 MHz /1 --> 0.000000125 s/cyc
// * 509 ---> 0,000063625 s

//#define ScreenTop 30 // first visible line
//#define ScreenBot 230 // last visible line

#define ScreenTop 100 // first BAR line
#define ScreenBot 150 // last BAR line

//NOTE that the first line of CHARs must be in registers!
char syncON, syncOFF;
//char v1, v2, v3, v4, v5, v6, v7, v8;
register unsigned char v1 asm ("r3");
register unsigned char v2 asm ("r4");
register unsigned char v3 asm ("r5");
register unsigned char v4 asm ("r6");
register unsigned char v5 asm ("r7");
register unsigned char v6 asm ("r8");
register unsigned char v7 asm ("r9");
register unsigned char v8 asm ("r10");

unsigned char bMask;
int i,LineCount, time;
char screen[800], t, ts[10], temp;


// ---------------------------------------------------------------------
//This is the sync generator. It MUST be entered from
//sleep mode to get accurate timing of the sync pulses
//At 8 MHz, all of the sync logic fits in the 5 uSec sync
//pulse
//interrupt [TIM1_COMPA] void t1_cmpA(void)
// ---------------------------------------------------------------------
//SIGNAL (SIG_OVERFLOW1)
SIGNAL (SIG_OUTPUT_COMPARE1A)
{
PORTD = syncON; //start the Horizontal sync pulse
TCNT0 = 0; //count timer 0 at 1/usec
LineCount++ ; //update the curent scanline number
switch (LineCount)
{
// case 295: //inverted (Vertical) synch after line 247 NTSC
case 160: //inverted (Vertical) synch after line 295 PAL
syncON = 0b00100000;
syncOFF = 0;
break;
// case 299: //back to regular sync after line 250 NTSC
case 314: //back to regular sync after line 299 PAL
syncON = 0;
syncOFF = 0b00100000;
break;
// case 313: //start new frame after line 262 NTSC
case 348: //start new frame after line 313 PAL
LineCount = 1;
break;
default: break;
}
PORTD = syncOFF; // sync pulse
}

// ---------------------------------------------------------------------
// set up the ports and timers M A I N
// ---------------------------------------------------------------------
int main(void)
{
//init timer 1 to generate sync
OCR1A = lineTime; //One NTSC line (509)
TCCR1B = 9; //full speed; clear-on-match MEGA163
TCCR1A = 0x00; //turn off pwm and oc lines
TIMSK = 0x10; //enable interrupt T1 cmp

//init ports
DDRD = 0xf0; //video out and switches
//D.5 is sync:1000 ohm + diode to 75 ohm resistor
//D.6 is video:330 ohm + diode to 75 ohm resistor

//init timer 0 to 1/uSec 1 MHZ
TCCR0 = 2;

//initialize synch constants
LineCount = 1;
syncON = 0b00000000;
syncOFF = 0b00100000;

//init software timer
t = 0;
time = 0;

//enable sleep mode
MCUCR = 0b10000000;
//#asm ("sei");
sei();

//The following loop executes once/video line during lines
//1-230, then does all of the frame } processing
while(1)
{

// stall here until next line starts
// sleep enable; mode=idle
// use sleep to make entry into sync ISR uniform time

asm volatile ("sleep");

if ((LineCount < ScreenBot) && (LineCount > ScreenTop))
{

//Balken zeichnen


}
} //while
return(0);
} //main

mfg pebisoft

PicNick
02.02.2005, 10:00
Also das mit dem Timing müßen wir erstmal hinkriegen und das kriegen wir auch hin.
Ich werd' mich, hoffentlich heute, hinsetzen und die ganze Sache mal labormäßig durchchecken. Ich mag's nicht, sinnlos an irgendwelchen Werten rumzuschrauben, ob's vielleicht besser oder schlechter wird und nicht wissen, warum.
Ich selbst hab nur PIC 877 und mega32, aber ich denk' doch, daß es sich dann problemlos auf den Mega8/16 umsetzen läßt.
bis dann , Pebi, mfg robert

pebisoft
02.02.2005, 11:12
hallo, habe ein bild in album,persönliche galerie, pebisoft
von bascom reingestellt.
der mega32 hat im wesentliche nur den speicherunterschied und ist sonst compatibel. ich habe den mega32 auch bei mir angeschlossen mit 8mhz.
er zeigt die gleichen bilder wie der meg16.
mfg pebisoft

$regfile = "m16def.dat"
$crystal = 8000000

Enable Interrupts

Config Pinb.0 = Output

Portb.0 = 0 ' 330 ohm widerstand

Do
Toggle Portb.0
Loop

PicNick
02.02.2005, 19:55
Hi, Pebi,
kaum macht man's richtig, geht's auch schon. Im Anhang die Balkenversion.
Der Balken ist etwas schmal, eigentlich ein Würfel.
Das ist deswegen, weil wir ja dzt. beim Pixel setzen keine Wenn und Aber haben, das heißt, wir sind zu schnell, aber das war von vornherein klar.
Weiters hab ich auf zwei andere Pins umsteigen müssen (nix frei bei mir)
im Programm sind PORTC.4 (Sync) u. PORTC.5 (Video)

Du mußt also PORTC auf PORTD unschreiben und umdefinieren:

#define synONE 0x10 // syn PICNICK
#define synNUL 0x00 // syn PICNICK
#define VIDONE 0x20 // VIdeo PICNICK

#define synONE 0x20 // syn PEBISOFT
#define synNUL 0x00 // syn PEBISOFT
#define VIDONE 0x40 // VIdeo PEBISOFT

ich hoff, du komst damit zurecht.
Mit dem Zählern mußt ich tricksen, so wie's is, stimmt's

Noch was: Ich hab die Dioden ersatzlos gestrichen

Viel Spaß, sieht gut aus, ruhig und stabil. mfg robert

pebisoft
03.02.2005, 07:31
hallo, vielen dank.
bei mir läuft es noch nicht so richtig. wenn ich in der case-schleife die 3 werte ändere, komme ich soweit, das ein halber bildschirm weiss ist und der andere schwarz über der ganzen breite, auch wenn ich die ganzen ports-weiss und schwarz total herausnehme (balken zeichnen) bleibt der bildschirm genauso. auf portd brauche ich nicht umschreiben weil die portc noch frei sind. kannst du mir anhand deines beispieles noch einmal die verantwortlichen zeilen erklären. vielen dank. irgendwie habe ich mich jetzt verzettelt mit der einfachstne art der darstellung von reaktionen auf dem bildschirm.
mfg pebisoft

PicNick
03.02.2005, 09:01
Guten Morgen !
Nein, diese Zahlen mußt du lassen, die stimmen so.
Das Programm ist so, wie's is, getestet auf RNBFRA 1.2-Board mit Mega32 mit 8MHZ.
Anschluß auf TV-Gerät mit SCART und Übergangsstecker auf FBAS rein/raus. KEINE DIODEN 330Ohm Video, 1k Sync, ~70Ohm Anpassung.
Ausgang mit Oszi gecheckt, der passt so.
Ich werd das Programm jetzt nochmal deutlicher kommentieren und dann wieder reinstellen. DAS MUSS AUCH BEI DIR SO GEHEN, überhaupt, wenn du eh meine Ports auch nehmen kannst.
mfg

PicNick
03.02.2005, 11:43
So, Pebi, ein bißchen besser dokumentiert. Am Abend werd' ich es auch nochmal testen, aber wie gesagt, beim 8MHZ (irgendwelche Fuses ?)
stimmt das Timing haargenau
PS Der Mega8 haut nur 1K SRAM. Sollt sich zwar ausgehen, aber denk dran, wenn irgendwas spinnt.
mfg robert

pebisoft
03.02.2005, 17:19
hallo, habe wieder ein bild reingestellt. es zieht der stark zur seite und wandert schnell, aber es ist schon ein musterbalken zu erkennen.
ich habe den mega16 und den mega32, sram reicht vollkommen aus. fusebit sind normal so, das alle pinc auf out oder in geschaltet werden können. wie machen die anderen das?
mfg pebisoft

PicNick
03.02.2005, 18:06
Wichtig ist, daß er wirklich mit dem Quartz auf 8MHZ arbeitet, sonst hätten wir keine Chance.
Ich dreh jetzt mal am Programm ein bißchen rum, ob ich deinen Bildfehler provozieren kann, schaut nach vertikal-Sync aus.
Hast du die Dioden rausgenommen ? Beim Video wär's ja irgendwie noch ok, aber ich hab mir überlegt, wie denn der mit der Sperr-Diode den Sync Impuls auf Low legen will. Ich rühr mich. mfg robert

PicNick
03.02.2005, 19:10
*seufz* ich schaff es nicht, ein ähnliches Bild wie im Album zu produzieren. nur wenn ich
die +- Leitung zum TV vertausche, wird es wild
und wenn ich den Sync in der Interrupt routine NICHT umdrehe (case 295)
wird das Bild grauslich.
Ich stell diesmal alle files (Mega32) rein, samt make, hex etc.
](*,) Ich glaub, da hat's was mit dem (analogen) TV-Anschluß ](*,)
Er empfängt KEINE sync impulse, so wie's aussieht.
Wenn du dann in der Not Wahnsinnswerte reinstellst, find er dann irgendwas, was er für den Sync hält, das täuscht aber.
Dioden oder nicht, ist egal, hab's probiert.
*ratlos* mfg robert

pebisoft
06.02.2005, 18:00
hallo, habe deine 3 programme auf dem avr8L mit 8mhz durchgeführt. bilder sind optimal . siehe "album,pers. galerie, pebisoft". ich hatte vorher den avr8515 mit 8mhz, den avr16/32 mit 8mhz genommen und da waren die verzerrungen der bilder sehr stark und teilweise nicht zu erkennen.
schaffts du es evtl noch einmal für den avr16/32 mit internen 8mhz.
vielleicht ist es nur eine timerfrage. die timer müssten im avr16 und 32 gleich sein, halt nur der speicher ist grösser flash , eeprom und sram.
vielen dank
mfg pebisoft

PicNick
06.02.2005, 18:34
Hi, Pebi !
Nachdem in den AVR-Video-Charts der Limit ja schon recht hoch liegt, hab ich versucht, die Möglichkeiten des reinen C ohne Asm auszuloten.

Dazu mußte ich die Ports verändern:
Video kommt nun auf PinC.7 (RN-Bus 25)
Sync auf PinB.0 (RN-Bus 29)
PortC ist nun als Output NICHT mehr zu verwenden.

dafür geht die Sache flotter, der Stand ist dzt. 128 x 112 Pixel.
das sind bei 8*8 Zeichen 16 x 14

Probiers erst einmal auf dem avr8L, vielleicht geht's ja.

Dann muß man sehen, wo bei den AVRs nun die Unterschiede herkommen
Sicher liegt's am Timing, aber wo ?

Ich versuch mich schlau zu machen mfg robert

pebisoft
06.02.2005, 20:22
hallo, der avr8l hat den pinc7 nicht. kannst du dich noch einmal wiederholen mit der pinbelegung. danke
mfg pebisoft

PicNick
07.02.2005, 09:32
Oh je., Dann muß man das PortC mit PortD austauschen.
den Sync auf PortB.0 sollt man eigentlich lassen können.
DDRC = 0x90 --> DDRD = 0x80
und Editor replace PORTC --> PORTD
versuch's mal. mfg robert

pebisoft
07.02.2005, 10:20
hallo, deine leistung ist schon beachtlich.
(nicht dein letztes programm sondern das zweite was du sauber erklärt hast.)
(avr8l mit 8mhz intern). habe folgendes gesetzt:
"define Bar_top 0"
"define Bar_top 290"
pixel von 65-73 dazu gesetzt.
und die verzögerungsschleife herausgenommen If "ix".
es sind jetzt 290 zeilen und 74 pixel.
wenn ich jetzt die pixelzahl erhöhe, fängt das bild an zu laufen und man merkt,
das der timer nicht mehr mitkommt.
das neue bild ist in "album,persönliche galerie, pebisoft".
mir fehlt nur der zusammnehang der zeilen zu den zahlen (pixel ) dieaufgelistet sind hinsichtlich der abbildung.
mfg pebisoft

PicNick
07.02.2005, 10:59
Hi,
Wirklich heikel ist das Zeugs in der Interrupt-Routine. Wenn die mal alle 64 uS aufgerufen wird und auch nicht länger ist wie im Beispiel, paßt die Synchronisation. Wichtig sind folgende Zahlen


NTSC PAL
1 1 WICHTIG normaler Sync (5 uS Puls 0.3V auf 0V)
~ sichtbarer Bereich
~ ende sichtbarer Bereich
248 295 WICHTIG verkehrter Sync (5 uS Puls 0V auf 0.3V)
( wird der Sync da NICHT umgedreht, läuft das Bild vertikal)
251 299 WICHTIG normaler Sync
( wird der Sync da NICHT normalisiert, läuft das Bild vertikal)
263 313 WICHTIG Bottom Line -> back to top 1/50 sec

Wenn du in main() erstmal garnix machst, muß das Bild schön stehen (is zwar schwarz, aber es laufe keine Streifen durch)
An den Zeilenzahlen 295 - 313 kann man nicht viel drehen, das PAL-System is nun mal so und das schafft der AVR eigentlich locker. ( mit 8MHZ) das sichtbare Bereich ist da variabler, da kann man nach Geschmack rumschrauben.
Horizontal: nach dem SLEEP müssen ca 6 uS schwarz bleiben, in der Zeit richtet man sich die folgende Zeilenpixel her.
frühere Punkte früher sieht man sowieso nicht.
Aber dann geht es um die Wurst. je schneller der Code, desto mehr horizontale Pixel kriegt man in ca 50 uS raus, dann sollt' man wieder beim SLEEP sein. Braucht man zu lange, werden die Pixel seltsam, aber das Bild sollt stehenbleiben, da ja der Sync im Interrupt auf jeden Fall drankommt.

Ich war natürlich feig', ich hab die Syncimpule und die Pegel erst mit dem Oszi gecheckt, da war's leichter. mfg robert

pebisoft
07.02.2005, 11:20
deine letzt änderung funktioniert nicht . wenn du jetzt das programm als sprunbrett nehmen würdest, was ich jetzt ausprobiert habe, war dein zweites mit deinem ausführlichen erklärungen und dem "linecount der nicht zu finden ist"
die schwarzen balken, die bei mir im bild sind und auch so aussehen als wenn sie zum programm gehören, sollen die da nicht rein, soll die ganze fläche etwa weiss sein???
mfg pebisoft

PicNick
07.02.2005, 11:23
Das mit dem verschwundenen Linecount is schon klar. Der C legt Wert auf die definition als "volatile", steht aber eh in der Beschreibung. mfg

pebisoft
09.02.2005, 19:28
hallo, das testbild ist das ein weisser block, oder so wie in meiner abbildung ein streifenbild.
mfg pebisoft