Generera VGA med PIC

Berätta om dina pågående projekt.
willmans
Inlägg: 254
Blev medlem: 11 april 2006, 13:56:20
Ort: Solna

Generera VGA med PIC

Inlägg av willmans »

Hej, jag börjar med att säga att det här inte kommer bli något så när coolt som Craft som alla borde ha sett vid det här laget. Målet är att få ut lite olika färger på en skärm med VGA anslutning, i slutändan kanske någon bild eller text.
Hårdvaran som jag använder är PIC16F887 med 20MHz kristall.
Eftersom PIC:en går på 20MHz tar varje instruktion 0.2us.

Lite om VGA:
VGA upplösning ligger på 640x480 @ 60Hz.
VGA kräver fem signaler, R, G, B samt horisontal synk och vertikal synk.
Nivåerna på färgsignalerna ligger på 0.7V där 0.7V är högst intensitet och 0V är lägst.
Hsynk och Vsynk är TTL nivåer och aktivt låga.
Vsynk signalen pulsas varje gång man når botten av en frame.
Hsynk signalen pulsas vid slutet på varje rad med pixlar.

Bilden uppdateras 60 gånger per sekund vilket ger att varje frame tar
60Hz = 16 666.6667us eller ca 16.67ms
Hsynk klockan ligger på 31 469Hz per frame = 31.777us per line
Pixelklockan för VGA upplösning ligger på 25.175MHz, vid varje klockpuls så läggs nya analoga värden ut.
Därför måste vi dela 31.777 med 1/25.175, det ger oss 800 pixlar för varje linje. Tiden för varje pixel är 1/25.175 (pixelklockan) viket är 0.03972125us (redan nu ser ni att det blir omöjligt att generera 640 pixlar med en PIC).
Varje linje är lite mer än 640. Förklaringen är att det före och efter synkpulserna är det lite dötid då färgsingnalerna ligger på 0V, kallas horisontal- repektive vertikal blankning, samt att synkpulserna i sig tar lite tid, på CRT skärmar tar det tid för elektronstrålen att flytta sig till andra sidan eller från botten till toppen av skärmen.

Exakta tider ser ni här nedan

Kod: Markera allt

Horizonal Timing

Horizonal Dots              640        
Vertical Scan Lines         480
Horiz. Sync Polarity        NEG
A (us)                    31.77     Scanline time
B (us)                     3.77      Sync pulse lenght 
C (us)                     1.89      Back porch
D (us)                    25.17     Active video time
E (us)                     0.94      Front porch

         ______________________          ________
________|        VIDEO         |________| VIDEO (next line)
    |-C-|----------D-----------|-E-|
__   ______________________________   ___________
  |_|                              |_|
  |B|
  |---------------A----------------|

Vertical Timing

Horizonal Dots              640
Vertical Scan Lines         480
Vert. Sync Polarity         NEG      
Vertical Frequency         60Hz
O (ms)                    16.68     Total frame time
P (ms)                     0.06      Sync length
Q (ms)                     1.02      Back porch
R (ms)                    15.25     Active video time
S (ms)                     0.35      Front porch

         ______________________          ________
________|        VIDEO         |________|  VIDEO (next frame)
    |-Q-|----------R-----------|-S-|
__   ______________________________   ___________
  |_|                              |_|
  |P|
  |---------------O----------------|
Timingen är hämtad från en manual till en HP skärm

Timingen kan variera lite grann mellan olika grafikkort och skärmar, det är sånt man får ta när man kör analogt...

Omräknat till instruktionscykler för PIC:

Kod: Markera allt

Hsync
0        Hsync low,   0 cyc
3.8 us   Hsync high,  +19 cyc
1.8 us   back porch,  +9 cyc
25.2 us  video,       +126 cyc
1 us     front porch, +5 cyc
---       
31.8 us               159cyc


Vsync
0         Vsync low,   0 cyc
60 us     Vsync high,  +300 cyc
1020 us   back porch,  +5100 cyc
15250 us  video,       +76250 cyc
350 us    front porch, +1750 cyc
---
16680 us               83400 cyc
Som ni ser blir det knappast exakt med 20MHz PIC och endast 126 cykler under video tiden. Anta att man ska hämta värden från en array och lägga ut på färgsinalerna, det tar väl 7-8 instruktioner bara det. Det ger oss en effektiv upplösning på kanske 20 pixlar. Men något är det iallafall, t.ex en smilie :D

RGB signalern kopplar jag till var sin utgång på PIC:en. För att få RGB signalerna till rätt nivå sätter jag ett motstånd i serie med signalen och clampar ner till jord med en diod. Då får jag ca 0.7V ut som max.

Ett litet kopplingschema över det hela:
Bild

Tråden kommer uppdateras så fort jag fått klart den tidskritiska koden och har något att visa. Koden kommer vara en blandning C och inline assembler.
Nerre
Inlägg: 27195
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Generera VGA med PIC

Inlägg av Nerre »

Gissa varför alla datorer sen hedenhös har en separat del som hanterar grafiken? :-)

Fast det är ju bra sätt att lära sig.
Användarvisningsbild
JimmyAndersson
Inlägg: 26571
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Re: Generera VGA med PIC

Inlägg av JimmyAndersson »

Mycket bra genomgång av projektet. :tumupp: :tumupp:

Det här ska bli väldigt kul att följa!
Användarvisningsbild
anders_bzn
Inlägg: 5772
Blev medlem: 17 december 2008, 19:22:18
Ort: Kävlinge
Kontakt:

Re: Generera VGA med PIC

Inlägg av anders_bzn »

Borde inte dioderna sitta efter motstånden? Annars får PIC:en det lite tungt när du försöker sätta någon av pinnarna RED/GREEN/BLUE högre än 0,7V.
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Generera VGA med PIC

Inlägg av Icecap »

anders_bzn: Självklart ska de det!

Jag undrar mest över videominnet, det är knappast en anledning att göra ett VGA-signal när videominnet knappast räcker till något vidare. En upplösning på t.ex. 20 pixlar som nämns ger att upplösningen reelt blir 32 * 24 om vi antar att man anpassar den vertikala upplösningen till detta, det ger 768 punkter och om man räknar en pixel = 4 bit blir det ändå 384 bytes som videominne.

Nåväl, jag gillar utmaningen i att få till timingen och adresseringen, jag hade dock gjort en lite annorlunda videosteg som använde den sista bit'en som intensitet.
Användarvisningsbild
baron3d
EF Sponsor
Inlägg: 1353
Blev medlem: 1 oktober 2005, 23:58:43
Ort: Torestorp

Re: Generera VGA med PIC

Inlägg av baron3d »

Du skulle ju kunna använda en PIC32 med 128k RAM
Lite snabbare, lite mer minne.
Användarvisningsbild
rickardg
Inlägg: 195
Blev medlem: 5 november 2008, 07:37:09
Ort: Rönninge
Kontakt:

Re: Generera VGA med PIC

Inlägg av rickardg »

eller en PIC10F200, lite långsammare och mer utmaning 8) och utmaningen är väl enda anledningen till att göra det i mjukvara :wink:

ett alternativ är att sänka upplösningen, är lite lättare att generera 320x200 pixlar, varför köra en upplösning som du aldrig kan komma upp i eller utnyttja helt?

beroende på vad du ska göra finns det trix för att komma undan med lite minne, tex tiles. Ska man göra något riktigt optimerat kan man bygga upp bilden i kod och anpassa utseendet efter vad som funkar att göra, tex så som jag gjort i mitt SX-tetris där jag endast hade 136 bytes minne i processorn och kunde skapa ett tetrisspel som genererade en NTSC-färgvideosignal i mjukvara enligt liknande principer:

Bild
willmans
Inlägg: 254
Blev medlem: 11 april 2006, 13:56:20
Ort: Solna

Re: Generera VGA med PIC

Inlägg av willmans »

Kul att få så mycket feedback! En liten uppdatering.
Försökte att blanda C och assembler men det visade sig bli krångligare än att köra ren assembler. Har inte kodat ren assembler förut så jag fick lära mig MPLAB. Har inte satt in mig i simulatorn än men det kommer jag att behöva.
Det jag har fått till nu är en skakig bild. Timingen har jag inte fått till riktigt. Det jag ska göra nu är att sätta mig in i hur simulatorn i MPLAB fungerar så att jag kan få stabil timing på synksignalerna. Varje instruktion räknas!

Ang. diodkopplingen:
Schemat är felritat, med dioderna innan motstånden blir det kortslutning.

I skärmen sitter det 83ohm till jord från R, G, B signalerna, kollade upp det i en servicemanual. Det antar jag är impedansanpassning. Jag simulerade diodkopplingen i spice tillsammans med det motståndet i skärmen och då får jag inte 0.7V ut utan bara någon millivolt. Är det tänkt att det ska bli så?
Nu när jag testar på labbplattan använder jag istället ett 470ohms motstånd i serie med färgsignalen och det skapar en spännigsdelare med motståndet i skärmen. Får då ca 0.75V. En sak jag undrar nu är om signalerna ska vara 0.7V när de är kopplade med motståndet i skärmen eller utan att vara inkopplade?

Det här är vad jag fått fram på skärmen hittills. Jag testade först med en HP LCD-skärm och den visade bara svart bild.
Bild
Jag försöker rita ut ett rött X.

Det här säger skärmen om upplösning och synksignalerna:
Bild
67Hz Vsynk är helt tokigt men Hsynken stämmer ganska bra, den ska vara 31.7kHz.

Jag hade tänkt köra 20x15 pixlar med 3 bits upplösning, och en extra bit som går bort pga det ska vara jämnt antal bitar för att spara två pixlar i en byte. Det tar 150byte ram, PIC'en har 368.

rickardg:
Väldigt intressant sida du har :), nu känns mitt projekt väldigt enkelt :lol: . Ska kolla igenom källkoden till dina spel!
Jag kör VGA upplösning för att datorskärmar inte klarar av lägre horisontal frekvens än ca 30kHz.
320 pixlar horisontalt ligger väl på ca 15kHz.
Användarvisningsbild
rickardg
Inlägg: 195
Blev medlem: 5 november 2008, 07:37:09
Ort: Rönninge
Kontakt:

Re: Generera VGA med PIC

Inlägg av rickardg »

Det gamla VGA-videoläget "13h", som användes flitigt i början på 90-talet, hade 320x200 upplösning (och 256 färger), har för mig att uppdateringsfrekvensen låg på 60Hz, det läget borde skärmar ha stöd för men jag har inte testat på någon ny skärm så det kanske inte funkar på nya skärmar(?)
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Re: Generera VGA med PIC

Inlägg av BEEP »

"Jag testade först med en HP LCD-skärm och den visade bara svart bild."
Jag tror att du ska koppla 5 volt till pinne nr 9 i VGA kontakten.
Användarvisningsbild
MiaM
Inlägg: 12838
Blev medlem: 6 maj 2009, 22:19:19

Re: Generera VGA med PIC

Inlägg av MiaM »

rickardg skrev:Det gamla VGA-videoläget "13h", som användes flitigt i början på 90-talet, hade 320x200 upplösning (och 256 färger), har för mig att uppdateringsfrekvensen låg på 60Hz, det läget borde skärmar ha stöd för men jag har inte testat på någon ny skärm så det kanske inte funkar på nya skärmar(?)
Ur skrämens perspektiv så kör det läget 400 pixels i Y-led. Grafikkortet visar varje rad två gånger.

Det intressanta är vad skärmen klarar att synka på, och då vad som är lägsta synkfrekvenser. Horisontalsynken är inte specad att funka under 31.5kHz, och med en given högsta "pixelklocka" från PIC'en så är upplösningen i X-led given. Om man vill ha lägre upplösning i Y-led så klarar väl många skärmar ofta att synka uppåt 100Hz, fast plattskärmar brukar väl tycka bäst om 60Hz, som också är minsta garanterat fungerande frekvensen för en vga-skärm.
Användarvisningsbild
rickardg
Inlägg: 195
Blev medlem: 5 november 2008, 07:37:09
Ort: Rönninge
Kontakt:

Re: Generera VGA med PIC

Inlägg av rickardg »

Ah, visste inte att de visade varje rad 2ggr men det är ju logiskt när du säger det, var ju väldigt "pixlig" grafik med tydliga fyrkanter som inte är möjliga med ett svep så klart, (antar att det var samma med CGA- och EGA-grafik där motsvarande lågupplösta "pixliga" grafiklägen fanns)
Användarvisningsbild
MiaM
Inlägg: 12838
Blev medlem: 6 maj 2009, 22:19:19

Re: Generera VGA med PIC

Inlägg av MiaM »

Nja, CGA/EGA körde inte dubbelscannat. CGA var verkligen alltid så usel att det bara var 200 linjer i Y-led. EGA-skärmar kunde växla H-synkfrekvens så att man fick antingen 200 eller 350 linjer i Y-led. Växlingen skedde dessutom normalt inte automatiskt styrt av synkfrekvens utan styrdes av polariteten på nån av synksignalerna (d.v.s. man "likriktade" synksignalen, fick man då nära 5V så var det ena synkfrekvensen, och nära 0V den andra...). Usch vad dåligt det var på den gamla onda tiden :) En ännu knäppare grej med EGA, som inte har nåt med den här tråden att göra egentligen, var det här med antal färger. CGA-skärmar klarade 16 färger, medan EGA-skärmar klarade 64 färger. För att en EGA-skärm skulle funka med ett CGA-grafikkort så var de konstruerade så att ingångarna funkade något olika i CGA- respektive EGA-läge. Det gjorde att med EGA-kort + EGA-skärm så kunde man använda en palett om 64 färger i lägena med 350 linjer, men bara 16 färger i 200-linjerslägena. :doh: :tumner: :shock:

Åsså fanns det folk på mitten av 80-talet som undrade varför Amiga-folket tyckte att PC sög :mrgreen:
Skriv svar