Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Assembler VGA Clock generieren

Dieses Thema im Forum "Hardware" wurde erstellt von TommyB, 21. März 2018.

  1. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Hiho,

    Problem kurz geschildert:
    Ich brauche einen VGA Grafikkartensimulator.

    Warum ist einfach. Es soll ein alter Monitor recycelt werden. Gebrochenes TFT, ist aber egal, weil es nur um die Leuchtfläche dahinter geht.
    Blöd dabei #1: Die Hintergrundbeleuchtung ist eng mit dem Controller verbunden, einfach Spannung anlegen fällt also flach.
    Blöd dabei #2: Es funktioniert zwar alles, aber der Monitor geht nach einiger Zeit in den Standby, weil kein Signal.

    Soweit ich gelesen habe müssen HSync und VSync erstellt werden und 5V angelegt werden. Anzeige ist ja egal, wird eh nichts angezeigt werden, also R, G und B auf 0.

    Jetzt bin ich auf dieses Projekt gestoßen. Klingt vielversprechend, auch wenn es für mich unnötig wohl Bilder ausgibt. Aber ich bin etwas irritiert, ich hatte gelesen dass die Pixel Clock 25,dickemilch MHz ist bei 640x480, der Tiny wird aber mit 20MHz befeuert... Irgendwo muss ich da einen Denkfehler haben.

    Was der Tiny für eine Auflösung vorgaukelt ist egal, es soll nur den Standby verhindern.
     
    #1 TommyB, 21. März 2018
    Zuletzt bearbeitet: 21. März 2018
  2. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.145
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Der Tiny wird wahrscheinlich eine interne PLL haben, die es ermöglicht diese Frequenz zu realisieren.
    Gerade gesehen das dass ein "2313" ist, der dürfte keine "PLL" haben. Würde mich auch mal interessieren.
     
    #2 Janiiix3, 21. März 2018
    Zuletzt bearbeitet: 21. März 2018
  3. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.133
    Zustimmungen:
    113
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Hi Tommy,

    einen Pixelclock hast du dort nicht. Es gibt ein VSync und ein HSync. Kritisch ist das HSync, weil kürzer. Dieses liegt aber bei etwas über 30us Periodendauer.
    Bei HSync high wird das analoge Videosignal dargestellt, was du nicht benötigst.

    :ciao:
     
  4. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.145
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    VSync = Vertikale Synchronisation?
    HSync = Horizontale Synchronisation?

    Wozu sind dann die 25MHz?
     
  5. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Ja.

    Also wenn ich dich jetzt richtig verstehe... Moment, anders.
    Ich dachte HSync clockt die Pixel (~25MHz) und VSync die Zeilen.
    Heißt das jetzt dass HSync den Zeilenüberlauf darstellt und VSync die Bildwiederholrate (60hz) ist?
     
  6. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.133
    Zustimmungen:
    113
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Ja, ich denke schon ...

    Diese 480 HSyncs sind 480 Zeilen
    Mit den nicht dargestellten Zeilen sind es 525 Zeilen.
    upload_2018-3-21_19-46-57.png
     
  7. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Hmmm. Denn wäre es also nur ein Timer der einen Pin mit 25µs toggelt (HSync). Im Overflow reicht es bis zu 525 zu zählen und die 2 letzten Impulse Low zu ziehen (VSync), das wars schon. ?
    Denn kann ich auch n kleineren Tiny nehmen, so viele Pins brauch ich ja nicht, passt denn in n D-Sub Gehäuse.
     
  8. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.827
    Zustimmungen:
    40
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Ok, die Übertragung irgendwelcher Bilddaten interessiert Dich nicht - Du willst eh nur das Backlight aktiv halten.
    Mal folgende Überlegungen eingeworfen:
    • VSync soll 60 Hz sein, dummerweise mit 2 von 525 Zyklen low
    • HSync ist 525mal so schnell, also 31,5kHz
    Wenn Du einen 8Mhz-Takt durch 256 teilst, landest Du bei 31,25kHz - wäre von der Toleranz her einen Versuch wert gewesen (Tiny mit internem 8Mhz-Takt, Main Clock Prescaler auf 256, Clock Out aktiviert).
    Ggf kann man mit OSCCAL noch etwas rausholen...
    Für VSync wird ein 16Bit-Timer auf 524 (Plus Überlauftakt = 525) getrimmt, und im PWM verwendet (mit 1(+1) Duty).

    Sollte sich mit 'nem ATtiny4/5/9/10 (komplett im Hintergrund) machen lassen - allerdings würden an CLKOUT während des PowerUps 1MHz statt der 31,25kHz anliegen...

    Nein. die 25µs ist die Zeit(-dauer), die das analoge Video-Signal 5,66µs nach der (fallenden ? ) Flanke von HSync haben darf - zusammen 30,66µs der HSync-Periodendauer von 31,75µs
    Interessiert Dich nicht...
     
    #8 LotadaC, 21. März 2018
    Zuletzt bearbeitet: 21. März 2018
  9. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Das war so ungefähr auch meine Idee.
    Nur mit den 4/5/9/10 is blöd, die kann mein Drachen nicht. Ich dachte da eher an den 13er. Wobei der nur einen Prescaler /8 hat.
    Osccal hatte ich ja eh schon mal auf dem Plan vor langer Zeit. Naja, genug Messgeräte habe ich ja mittlerweile hier. Try'n'error.

    Während PowerUp, ich glaube das wäre kein Problem. Das Display wird wohl eh auch seine Zeit zum aufwachen brauchen. Vermutlich wesentlich mehr als ein Tiny.
     
  10. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.133
    Zustimmungen:
    113
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Da es lediglich darum geht, VSync und HSync zu erzeugen damit der Monitor nicht ausschaltet, und der Mikrocontroller wahrscheinlich sonst nichts "machen" muss, sollte es doch auch einfach über Portpinzugriffe mit Pausezeiten gehen.
    Das Timing muss man sicher nicht exakt einhalten. Der MC sollte dann schon mit 16MHz laufen, damit man unter 100ns Maschinenzyklus kommt. Je kürzer der Maschinenzyklus, desto genauer bekommt man es hin.
    Da könnte man irgendeinen AVR Mikrocontroller verwenden mit zwei freien IO Pins. Es wäre eine simple Lösung.
     
  11. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.827
    Zustimmungen:
    40
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Hab ich mir schon gedacht...
    Statt des 13 würde ich den 25/45 empfehlen. Welcher Tiny noch Clockout kann, weiß ich grad nicht. Die 25er können mit der PLL intern mit 16MHz takten und einen der beiden Timer mit 64MHz takten.
    Wenn man da wegen 8Bit nicht hin kommt, kann man gemäß Dirk ja immer noch zu Fuß gehen...
    Den 25 kannst Du als 150er SOIC (die schmalen), den 45 als TSSOP haben.

    Tiny10 und Tiny25 hätte ich hier - passen auch grad noch so in'nen Luftpolsterumschlag;-)
     
  12. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    So, erstes Proof of concept. Mangels Buchse aber noch ungetestet.
    Die i2c Leitungen habe ich nicht angeschlossen, ich weiß noch nicht an welcher Seite die PullUps sitzen. Sollte eigentlich nicht stören.
    Ist jetzt mit einem ATtiny13A und internen 9,6MHz, laut Simulator komm ich schon recht nahe an die Timings ran. Bissl Feintuning im OSCCAL falls nötig.



    CodeBox Assembler
    /* 
    
        VGASim V1.0 BETA
        ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
        Simulates a VGA signal (generates the clock impulses) to
        not let the monitor go into sleep mode.
    
        (C) tightDev.Net 2018
    
    
    
        Wireing: ATtiny13A
        ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
                     ___  ___
                    |o  \/   |
          ISP Reset |        | +5V
                 nc |        | ISP SCK
                 nc |        | ISP MISO / VSync
                GND |        | ISP MOSI / HSync
                    |________|
    
    
    
        Wireing: VGA
        ¯¯¯¯¯¯¯¯¯¯¯¯
          Pin 1, 2, 3: RGB signals. Unused, connected to GND. Can be 0.7V for white.
          Pin 5, 6, 7, 8, 10: GND
          Pin 13: HSync
          Pin 14: VSync
          Pin 4, 11, 12, 15: not connected
       
    */
    
    
    
    // Setup environment
    .INCLUDE <tn13Adef.inc>            ; Include chip defination
    .EQU SyncDDR    = DDRB            ; The port where the sync lines are connected to
    .EQU SyncPort    = PORTB            ; The port where the sync lines are connected to
    .EQU SyncPin    = PINB            ; The port where the sync lines are connected to
    .EQU HSync        = PINB0            ; Pin used for horizontal sync (31.777557100298 µS)
    .EQU VSync        = PINB1            ; Pin used for vertical sync (16.683217477656 mS)
    .EQU Reload        = 37            ; Timer reload value for HSync generation
    .EQU Calib        = 128            ; Calibration of the internal RC clock
    
    
    
    // Define registers
    .DEF Temp1        = R16            ; General purpose temp register (not for ISR)
    .DEF CntL        = R30            ; Counter register, high byte
    .DEF CntH        = R31            ; Counter register, low byte
    
    
    
    // Interrupt vector table
    .ORG 0x0000        RJMP Init        ; Start of application
    .ORG INT0addr    RETI            ; External Interrupt 0
    .ORG PCI0addr    RETI            ; External Interrupt Request 0
    .ORG OVF0addr    RETI            ; Timer/Counter0 Overflow
    .ORG ERDYaddr    RETI            ; EEPROM Ready
    .ORG ACIaddr    RETI            ; Analog Comparator
    .ORG OC0Aaddr    RCALL OnOC0A    ; Timer/Counter Compare Match A
    .ORG OC0Baddr    RETI            ; Timer/Counter Compare Match B
    .ORG WDTaddr    RETI            ; Watchdog Time-out
    .ORG ADCCaddr    RETI            ; ADC Conversion Complete
    .ORG INT_VECTORS_SIZE            ; End of table
    
    
    
    // Controller initialization
    Init:
    
        // Set port pins to output and high
        LDI        Temp1,        (1<<HSync) | (1<<VSync)
        OUT        SyncDDR,    Temp1
        OUT        SyncPort,    Temp1
    
        // Setup power saving: Idle mode, because we need the timer
        LDI        Temp1,        (1<<SE)
        OUT        MCUCR,        Temp1
    
        // Setup power saving: Disable analog comperator
        LDI        Temp1,   (1<<ACD)|(1<<ACI)
        OUT        ACSR,        Temp1    ; apply and wait 2 cycles
        NOP
        NOP
        OUT        ACSR,        Temp1    ; twice to ensure no interrupt has fired
    
        // Setup watchdog (1 second)
        CLI                            ; Disable interrupts
        IN        Temp1,        WDTCR
        ORI        Temp1,         (1<<WDCE) | (1<<WDE)
        OUT        WDTCR,        Temp1
        LDI        Temp1,        (1<<WDE) | (1<<WDP2) | (1<<WDP0)
        OUT        WDTCR,        Temp1
        SEI                            ; Enable interrupts
    
        // Setup Timer (CTC, Clock/8, Interrupt)
        LDI        Temp1,        (1<<WGM01)
        OUT        TCCR0A,        Temp1
        LDI        Temp1,        (1<<CS01)
        OUT        TCCR0B,        Temp1
        LDI        Temp1,        Reload
        OUT        OCR0A,        Temp1
        LDI        Temp1,        (1<<OCIE0A)
        OUT        TIMSK0,        Temp1
    
        // Reset counter
        LDI        CntH,        0
        LDI        CntL,        0
    
        // Set maximum values for row counter
        LDI        XH,            HIGH(523)
        LDI        XL,            LOW(523)
        LDI        YH,            HIGH(525)
        LDI        YL,            LOW(525)
    
        // Tweak the internal RC clock to match the frequencies
    //    LDI        Temp1,        Calib
    //    OUT        OSCCAL,        Temp1
    
    // RJMP Main                    ; Not required, it's the next command
    
    
    
    // Main application loop
    Main:
    
        // Nothing in here, fall asleep and kick the dog after interrupt
        SLEEP
        WDR
    
    RJMP Main
    
    
    
    // Interrupt Routine: Compare Match A
    OnOC0A:
    
        // Line is now completed, so toggle HSync
        SBI        SyncPin,    HSync    ; Toggle HSync
    
        // Increment counter to process VSync
        ADIW    CntH:CntL,    1        ; Increment line counter
    
        // Check HSync impulse
        CP        CntL,        XL        ; Compare low byte
        CPC        CntH,        XH        ; Compare high byte
        BRLO    OnOC0A_Exit            ; Exit if lower
    
        // VSync overflow, reset pin
        CBI        SyncPort,    HSync    ; Set pin low
    
        // Check VSync length
        CP        CntL,        YL        ; Compare low byte
        CPC        CntH,        YH        ; Compare high byte
        BRLO    OnOC0A_Exit            ; Exit if lower
    
        // VSync signal long enough, set pin and reset counter
        SBI        SyncPort,    HSync    ; Set pin high
        CLR        CntH                ; Reset counter (high byte)
        CLR        CntL                ; Reset counter (low byte)
    
      OnOC0A_Exit:
    
    RETI
     
  13. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.827
    Zustimmungen:
    40
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Hmm...
    Der Timer generiert im CTC 'ne Zeitbasis, im IRQ toggelst Du HSync. Das kann der Timer auch selbst in Hardware machen (Compare Output Mode = &B01).
    Zeitbasis: 9600000Hz/8 (Prescaler) = 1,2MHz Timertakt. Nach 38 Timertakten hast Du zwar die 31,666 µS (31,58kHz) - allerdings toggelst Du ja den Pin. Effektiv hast Du da also ca 15kHz).
    Du kannst Statt des CTC aber auch fastPWM nutzen, OC0B dann bei 18...

    Dein Zeilenzähler zählt von 1..525, zwei Perioden (und ein paar Takte) lang ist HSync (-> müßte VSync sein) gelöscht.
    Du kannst Dir einen der Vergleiche sparen, indem Du den Zähler von -525 gegen 0 laufen läßt - wenn der Zähler durch ADIW 0 erreicht, wird automatisch das Z gesetzt;)
     
  14. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.634
    Zustimmungen:
    50
    Ort:
    127.0.0.1 ;)
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Oops, ja, toggeln... Aber mit den Frequenzen bin ich eh noch nicht durch, der Simulator will mich verarschen...
    Im Einzelschritt geht es, mit BreakPoints nicht 0.o

    Auf die Idee mit rückwärts zählen war ich noch nicht gekommen, aber hast recht ;)
     
  15. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.827
    Zustimmungen:
    40
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Du mußt schon vorwärts zählen wenn Du ADIW nimmst, da die Konstante nur sechs Bit "groß" ist. Aber Du mußt ja nicht bei null beginnen. Alter Assembler-Trick...
    Wenn's zeitkritisch ist, kann man statt zwei LDI ein MOVW verwenden, kostet allerdings zwei weitere Register.

    Breakpoints hab ich im Simulator noch nie genutzt - höchstens mal Run to Cursor.
     

Diese Seite empfehlen

  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)