PIC micro drives VGA monitor

Discussion in 'The Projects Forum' started by THE_RB, Jan 2, 2010.

  1. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Hi, thought you might be interested in one of my little "holidays" projects. :)

    It uses a PIC 18F452 which runs at 10 MIPS to directly drive a VGA computer monitor in 640x480 60Hz mode.

    Actual video pixels are generated by the PIC's inbuilt serial SPI module and sent at 10 Megapixels / second, so it makes actual 251 pixels across and 480 pixels down.

    It's not as good as some of the AVR video projects (because the PIC is 4x slower than AVR at this type of task) but it's proof of concept that a cheap PIC can create video at 10 Megapix/sec with some crude colour control etc thrown in for fun. I haven't provided source code because it's a mess of C and assembler chunks and still unfinished but I did provide .HEX code in case anyone want to try it on their own PIC.

    The hardware only requires the PIC, xtal and 3 resistors to form the RGB video "DAC".

    [​IMG]

    More details on the project can be found near the bottom of this page;

    PIC drives VGA monitor project!
     
    spider87 likes this.
  2. peter_morley

    Member

    Mar 12, 2011
    179
    0
    hello I am using the same microcontroller and would like to know how you generated a fast enough pixel clock while accessing ram.
     
  3. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Hi Peter, I did say somewhere on my web page. I used the PIC internal hardware MSSP serial module, this sends bits out at 10 megabits per second (which gives 10 mega pixels per second).

    So the firmware needs to load a byte into the MSSP module, and the module shifts the 8 bits out automatically at the processor speed (10MHz).
     
  4. peter_morley

    Member

    Mar 12, 2011
    179
    0
    So the processor will shift the eight bits out at any port I want?
     
  5. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    No, the MSSP module has a data out pin, that is the pin the shifter data comes out from.

    It is all explained in the PIC datasheet under the "MSSP module" chapter. :)
     
  6. peter_morley

    Member

    Mar 12, 2011
    179
    0
    oh so we are talking only one bit per cycle. Sorry to keep asking you questions but one problem i have not been able to tackle is my problem of jitter. I seem to be getting little changes in frequency that cause the pixels to shift one pixel from left to right. These changes are very little but add up to almost a moving/pulsing picture. Any suggestions to troubleshooting this problem?
     
  7. John P

    AAC Fanatic!

    Oct 14, 2008
    1,634
    224
    Roman, I'm curious about how you create color. The processor only has a single synchronous port output, and VGA uses 3 color inputs. Did you set up external logic to create the colors?

    Or maybe you only use 2 colors. If you had all 3, you'd be "The_RGB".
     
  8. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    To Peter_Morley; the sync is hard to get right. You probably need to use assembler and hard-code with the PIC timers to make sure the h-sync pulse happens on an exact interval.

    John-P; Hi, my schematic is shown on the web page linked to in post #1. The video is generated in black/white pixels on pin RC5 (the MSSP port output pin) then there are 3 PIC output pins and 3 resistors, these are used as "colour killers" so they are either high impedance (which has no effect on that colour), or they are outputs pulled to ground (that kills that colour).

    The 3 pins give 8 possible RGB colours, you can see all 8 colours on the text lines.

    Of course the PIC is not fast enough to control RGB colour for each pixel, so it sets the colour at the start of the horiz line and then the colour is set for the whole horiz pixel line.

    So you can call me "THE_RGB" but only on one line! ;)
     
  9. peter_morley

    Member

    Mar 12, 2011
    179
    0
    The RB- I have been using assembler from the start. What do you mean by hard code the PIC timers. I have implemented my code with timers with interrupts and counter iterations. Both are not giving jitter free results. My hsync code seems to be completely correct and i have checked and rechecked with no results. The thing that doesnt make sense to me is that some of the bars jitter while others do not. These are jitters in the 15-20Mhz range (rough guess compared to my pixel clock) which I can't actually implement because outputting colors takes 64MHz/8cycles = 8MHz pixel clock. Could this be from a jittering cpu from using the PLL?
     
  10. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    Does your MCU have a SPI port? Use that instead of code and you can save yourself a lot of headaches.
     
  11. peter_morley

    Member

    Mar 12, 2011
    179
    0
    yes it does but it only has a one bit output per cycle so it isn't what im looking for. I feel my code is fine and there has to be another reason other than coding that is causing my problem.
     
  12. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    The number of execution cycles is not always deterministic, especially if you are using other things such as timers, interrupts, UARTs, ADC etc.

    I am doing SVGA from a MCU also and am generating pixels at 21MHz.
     
  13. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    No, it is not the HSPLL. Your jitter will be in the order of 1 or 2 PIC instructions etc, many many times larger than any expected HSPLL phase error.

    That is a very typical symptom that some lines jitter and some don't. It will be a beat frequency of the hsync as it beats to the timer or interrupt.

    Exactly how are you generating the hsync pulse? If you do it in assembler in a single timer interrupt (with no other interrupts enabled) the int freq and int latency should remain stable, and if the pulse is hard coded in asm it should be as stable as the interrupt frequency.

    If you post the small section of code for your hsync pulse in the interrupt we might be able to see the problem?
     
  14. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    Interrupt latency is never stable. There is usually at least one clock cycle uncertainty for a single cycle per instruction machine.

    One possible solution around this problem is to execute a WAIT instruction before your timer interrupt occurs (if your MCU supports this).
     
    Last edited: Dec 26, 2011
  15. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Sorry MrChips you are wrong. I have done timing applications for many years with PICs and the timer overflow interrupt latency is stable. I have even created test setups with markers on the CRO and tested which timer count corresponds to the first instruction executable in the interrupt.

    The stability of the timer overflow interrupt is exactly what makes solid hsync possible on mine and everybody elses PIC 16F and 18F video generator projects.
     
  16. MrChips

    Moderator

    Oct 2, 2009
    12,446
    3,362
    Ok. Fine. I believe you. What I know is that when an interrupt occurs, the current instruction must be completed before the interrupt sequence begins. I suppose your timer is synchronized with the CPU SYSCLK.
     
  17. peter_morley

    Member

    Mar 12, 2011
    179
    0
    Don't pay too much attention to the comments because i have been changing the code so often the comments are not relevant anymore unfortunately so don't let them confuse you. Thanks for taking a look. This is only the hsync loop.
    Code ( (Unknown Language)):
    1. displayloop                                     ;Executes pixels in each line
    2.         bsf     PORTB,0
    3.         bsf     PORTA,7
    4.         nop
    5.         nop
    6.         nop
    7.         nop
    8.         nop
    9.         nop
    10.         nop
    11.         nop    
    12.         nop
    13.         nop
    14.         nop
    15.         nop
    16.         nop
    17.         nop
    18.         nop
    19.         nop
    20.         nop
    21.         nop
    22.         nop
    23.         nop
    24.         nop
    25.         nop
    26.         nop
    27.         nop
    28.         nop
    29.         nop
    30.         nop
    31.         nop
    32.         nop
    33.         nop
    34.         nop
    35.         nop
    36.         nop    
    37.         nop
    38.         nop
    39.         nop
    40.         nop
    41.         nop
    42.         nop
    43.         nop
    44.         nop
    45.         nop
    46.         nop
    47. ;rgb on phase 406 cycles
    48.  
    49. ;first 88 cycles
    50.         movf    POSTINC0,0
    51.         movwf   PORTA
    52.         movf    POSTINC0,0
    53.         movwf   PORTA
    54.         movf    POSTINC0,0
    55.         movwf   PORTA
    56.         movf    POSTINC0,0
    57.         movwf   PORTA
    58.         movf    POSTINC0,0
    59.         movwf   PORTA
    60.         movf    POSTINC0,0
    61.         movwf   PORTA
    62.         movf    POSTINC0,0
    63.         movwf   PORTA
    64.         movf    POSTINC0,0
    65.         movwf   PORTA  
    66.         movf    POSTINC0,0
    67.         movwf   PORTA
    68.         movf    POSTINC0,0
    69.         movwf   PORTA
    70.         movf    POSTINC0,0
    71.         movwf   PORTA
    72.         movf    POSTINC0,0
    73.         movwf   PORTA
    74.         movf    POSTINC0,0
    75.         movwf   PORTA
    76.         movf    POSTINC0,0
    77.         movwf   PORTA
    78.         movf    POSTINC0,0
    79.         movwf   PORTA
    80.         movf    POSTINC0,0
    81.         movwf   PORTA
    82.         movf    POSTINC0,0
    83.         movwf   PORTA
    84.         movf    POSTINC0,0
    85.         movwf   PORTA
    86.         movf    POSTINC0,0
    87.         movwf   PORTA
    88.         movf    POSTINC0,0
    89.         movwf   PORTA
    90.         movf    POSTINC0,0
    91.         movwf   PORTA
    92.         movf    POSTINC0,0
    93.         movwf   PORTA
    94.         movf    POSTINC0,0
    95.         movwf   PORTA
    96.         movf    POSTINC0,0
    97.         movwf   PORTA
    98.         movf    POSTINC0,0
    99.         movwf   PORTA
    100.         movf    POSTINC0,0
    101.         movwf   PORTA
    102.         movf    POSTINC0,0
    103.         movwf   PORTA
    104.         movf    POSTINC0,0
    105.         movwf   PORTA
    106.         movf    POSTINC0,0
    107.         movwf   PORTA
    108.         movf    POSTINC0,0
    109.         movwf   PORTA
    110.         movf    POSTINC0,0
    111.         movwf   PORTA
    112.         movf    POSTINC0,0
    113.         movwf   PORTA
    114.         movf    POSTINC0,0
    115.         movwf   PORTA
    116.         movf    POSTINC0,0
    117.         movwf   PORTA
    118.         movf    POSTINC0,0
    119.         movwf   PORTA
    120.         movf    POSTINC0,0
    121.         movwf   PORTA
    122.         movf    POSTINC0,0
    123.         movwf   PORTA
    124.         movf    POSTINC0,0
    125.         movwf   PORTA
    126.         movf    POSTINC0,0
    127.         movwf   PORTA
    128.         movf    POSTINC0,0
    129.         movwf   PORTA
    130.         movf    POSTINC0,0
    131.         movwf   PORTA
    132.         movf    POSTINC0,0
    133.         movwf   PORTA
    134.         movf    POSTINC0,0
    135.         movwf   PORTA
    136.         movf    POSTINC0,0
    137.         movwf   PORTA
    138.  
    139. ;second 100 cycles
    140.         movf    POSTINC0,0
    141.         movwf   PORTA
    142.         movf    POSTINC0,0
    143.         movwf   PORTA
    144.         movf    POSTINC0,0
    145.         movwf   PORTA
    146.         movf    POSTINC0,0
    147.         movwf   PORTA
    148.         movf    POSTINC0,0
    149.         movwf   PORTA
    150.         movf    POSTINC0,0
    151.         movwf   PORTA
    152.         movf    POSTINC0,0
    153.         movwf   PORTA
    154.         movf    POSTINC0,0
    155.         movwf   PORTA  
    156.         movf    POSTINC0,0
    157.         movwf   PORTA
    158.         movf    POSTINC0,0
    159.         movwf   PORTA
    160.         movf    POSTINC0,0
    161.         movwf   PORTA
    162.         movf    POSTINC0,0
    163.         movwf   PORTA
    164.         movf    POSTINC0,0
    165.         movwf   PORTA
    166.         movf    POSTINC0,0
    167.         movwf   PORTA
    168.         movf    POSTINC0,0
    169.         movwf   PORTA
    170.         movf    POSTINC0,0
    171.         movwf   PORTA
    172.         movf    POSTINC0,0
    173.         movwf   PORTA
    174.         movf    POSTINC0,0
    175.         movwf   PORTA
    176.         movf    POSTINC0,0
    177.         movwf   PORTA
    178.         movf    POSTINC0,0
    179.         movwf   PORTA
    180.         movf    POSTINC0,0
    181.         movwf   PORTA
    182.         movf    POSTINC0,0
    183.         movwf   PORTA
    184.         movf    POSTINC0,0
    185.         movwf   PORTA
    186.         movf    POSTINC0,0
    187.         movwf   PORTA
    188.         movf    POSTINC0,0
    189.         movwf   PORTA
    190.         movf    POSTINC0,0
    191.         movwf   PORTA
    192.         movf    POSTINC0,0
    193.         movwf   PORTA
    194.         movf    POSTINC0,0
    195.         movwf   PORTA
    196.         movf    POSTINC0,0
    197.         movwf   PORTA
    198.         movf    POSTINC0,0
    199.         movwf   PORTA
    200.         movf    POSTINC0,0
    201.         movwf   PORTA
    202.         movf    POSTINC0,0
    203.         movwf   PORTA
    204.         movf    POSTINC0,0
    205.         movwf   PORTA
    206.         movf    POSTINC0,0
    207.         movwf   PORTA
    208.         movf    POSTINC0,0
    209.         movwf   PORTA
    210.         movf    POSTINC0,0
    211.         movwf   PORTA
    212.         movf    POSTINC0,0
    213.         movwf   PORTA
    214.         movf    POSTINC0,0
    215.         movwf   PORTA
    216.         movf    POSTINC0,0
    217.         movwf   PORTA
    218.         movf    POSTINC0,0
    219.         movwf   PORTA
    220.         movf    POSTINC0,0
    221.         movwf   PORTA
    222.         movf    POSTINC0,0
    223.         movwf   PORTA
    224.         movf    POSTINC0,0
    225.         movwf   PORTA
    226.         movf    POSTINC0,0
    227.         movwf   PORTA
    228.         movf    POSTINC0,0
    229.         movwf   PORTA
    230.         movf    POSTINC0,0
    231.         movwf   PORTA
    232.         movf    POSTINC0,0
    233.         movwf   PORTA
    234.         movf    POSTINC0,0
    235.         movwf   PORTA
    236.         movf    POSTINC0,0
    237.         movwf   PORTA
    238.         movf    POSTINC0,0
    239.         movwf   PORTA
    240.    
    241. ;third 100 cycles
    242.         movf    POSTINC0,0
    243.         movwf   PORTA
    244.         movf    POSTINC0,0
    245.         movwf   PORTA
    246.         movf    POSTINC0,0
    247.         movwf   PORTA
    248.         movf    POSTINC0,0
    249.         movwf   PORTA
    250.         movf    POSTINC0,0
    251.         movwf   PORTA
    252.         movf    POSTINC0,0
    253.         movwf   PORTA
    254.         movf    POSTINC0,0
    255.         movwf   PORTA
    256.         movf    POSTINC0,0
    257.         movwf   PORTA  
    258.         movf    POSTINC0,0
    259.         movwf   PORTA
    260.         movf    POSTINC0,0
    261.         movwf   PORTA
    262.         movf    POSTINC0,0
    263.         movwf   PORTA
    264.         movf    POSTINC0,0
    265.         movwf   PORTA
    266.         movf    POSTINC0,0
    267.         movwf   PORTA
    268.         movf    POSTINC0,0
    269.         movwf   PORTA
    270.         movf    POSTINC0,0
    271.         movwf   PORTA
    272.         movf    POSTINC0,0
    273.         movwf   PORTA
    274.         movf    POSTINC0,0
    275.         movwf   PORTA
    276.         movf    POSTINC0,0
    277.         movwf   PORTA
    278.         movf    POSTINC0,0
    279.         movwf   PORTA
    280.         movf    POSTINC0,0
    281.         movwf   PORTA
    282.         movf    POSTINC0,0
    283.         movwf   PORTA
    284.         movf    POSTINC0,0
    285.         movwf   PORTA
    286.         movf    POSTINC0,0
    287.         movwf   PORTA
    288.         movf    POSTINC0,0
    289.         movwf   PORTA
    290.         movf    POSTINC0,0
    291.         movwf   PORTA
    292.         movf    POSTINC0,0
    293.         movwf   PORTA
    294.         movf    POSTINC0,0
    295.         movwf   PORTA
    296.         movf    POSTINC0,0
    297.         movwf   PORTA
    298.         movf    POSTINC0,0
    299.         movwf   PORTA
    300.         movf    POSTINC0,0
    301.         movwf   PORTA
    302.         movf    POSTINC0,0
    303.         movwf   PORTA
    304.         movf    POSTINC0,0
    305.         movwf   PORTA
    306.         movf    POSTINC0,0
    307.         movwf   PORTA
    308.         movf    POSTINC0,0
    309.         movwf   PORTA
    310.         movf    POSTINC0,0
    311.         movwf   PORTA
    312.         movf    POSTINC0,0
    313.         movwf   PORTA
    314.         movf    POSTINC0,0
    315.         movwf   PORTA
    316.         movf    POSTINC0,0
    317.         movwf   PORTA
    318.         movf    POSTINC0,0
    319.         movwf   PORTA
    320.         movf    POSTINC0,0
    321.         movwf   PORTA
    322.         movf    POSTINC0,0
    323.         movwf   PORTA
    324.         movf    POSTINC0,0
    325.         movwf   PORTA
    326.         movf    POSTINC0,0
    327.         movwf   PORTA
    328.         movf    POSTINC0,0
    329.         movwf   PORTA
    330.         movf    POSTINC0,0
    331.         movwf   PORTA
    332.         movf    POSTINC0,0
    333.         movwf   PORTA
    334.         movf    POSTINC0,0
    335.         movwf   PORTA
    336.         movf    POSTINC0,0
    337.         movwf   PORTA
    338.         movf    POSTINC0,0
    339.         movwf   PORTA
    340.         movf    POSTINC0,0
    341.         movwf   PORTA
    342.  
    343. ;fourth 86 cycles
    344.         movf    POSTINC0,0
    345.         movwf   PORTA
    346.         movf    POSTINC0,0
    347.         movwf   PORTA
    348.         movf    POSTINC0,0
    349.         movwf   PORTA
    350.         movf    POSTINC0,0
    351.         movwf   PORTA
    352.         movf    POSTINC0,0
    353.         movwf   PORTA
    354.         movf    POSTINC0,0
    355.         movwf   PORTA
    356.         movf    POSTINC0,0
    357.         movwf   PORTA
    358.         movf    POSTINC0,0
    359.         movwf   PORTA  
    360.         movf    POSTINC0,0
    361.         movwf   PORTA
    362.         movf    POSTINC0,0
    363.         movwf   PORTA
    364.         movf    POSTINC0,0
    365.         movwf   PORTA
    366.         movf    POSTINC0,0
    367.         movwf   PORTA
    368.         movf    POSTINC0,0
    369.         movwf   PORTA
    370.         movf    POSTINC0,0
    371.         movwf   PORTA
    372.         movf    POSTINC0,0
    373.         movwf   PORTA
    374.         movf    POSTINC0,0
    375.         movwf   PORTA
    376.         movf    POSTINC0,0
    377.         movwf   PORTA
    378.         movf    POSTINC0,0
    379.         movwf   PORTA
    380.         movf    POSTINC0,0
    381.         movwf   PORTA
    382.         movf    POSTINC0,0
    383.         movwf   PORTA
    384.         movf    POSTINC0,0
    385.         movwf   PORTA
    386.         movf    POSTINC0,0
    387.         movwf   PORTA
    388.         movf    POSTINC0,0
    389.         movwf   PORTA
    390.         movf    POSTINC0,0
    391.         movwf   PORTA
    392.         movf    POSTINC0,0
    393.         movwf   PORTA
    394.         movf    POSTINC0,0
    395.         movwf   PORTA
    396.         movf    POSTINC0,0
    397.         movwf   PORTA
    398.         movf    POSTINC0,0
    399.         movwf   PORTA
    400.         movf    POSTINC0,0
    401.         movwf   PORTA
    402.         movf    POSTINC0,0
    403.         movwf   PORTA
    404.         movf    POSTINC0,0
    405.         movwf   PORTA
    406.         movf    POSTINC0,0
    407.         movwf   PORTA
    408.         movf    POSTINC0,0
    409.         movwf   PORTA
    410.         movf    POSTINC0,0
    411.         movwf   PORTA
    412.         movf    POSTINC0,0
    413.         movwf   PORTA
    414.         movf    POSTINC0,0
    415.         movwf   PORTA
    416.         movf    POSTINC0,0
    417.         movwf   PORTA
    418.         movf    POSTINC0,0
    419.         movwf   PORTA
    420.         movf    POSTINC0,0
    421.         movwf   PORTA
    422.         movf    POSTINC0,0
    423.         movwf   PORTA
    424.         movf    POSTINC0,0
    425.         movwf   PORTA
    426.         movf    POSTINC0,0
    427.         movwf   PORTA
    428.         movf    POSTINC0,0
    429.         movwf   PORTA
    430.    
    431.         movlw   B'11000000'
    432.         movwf   PORTA
    433.         nop
    434.         nop
    435.         nop
    436.         nop
    437.         nop
    438.         nop
    439.         nop
    440.         nop
    441.         nop
    442.         nop
    443.         nop
    444.         nop
    445.         nop
    446.         nop
    447.         nop
    448.         nop
    449.         nop
    450.         nop
    451.         nop
    452.         nop
    453.         nop
    454.         nop
    455.         nop
    456.         nop
    457.         nop
    458.         nop
    459.         nop
    460.         nop
    461.         nop
    462.  
    463.         clrf    FSR0L
    464.         nop
    465.         nop
    466.         nop
    467.         nop
    468.         nop
    469.         nop
    470.         nop
    471.         nop
    472.         nop
    473.         nop
    474.         nop
    475.         nop
    476.         nop
    477.         nop
    478.         nop
    479.         nop
    480.         nop
    481.         nop
    482.         nop
    483.         nop
    484.         nop
    485.         nop
    486.         nop
    487.         nop
    488.         nop
    489.         nop
    490.         nop
    491.         bcf     PORTA,7
    492.  
    493.         decf    lowbytecount                    ;decrement the low byte skip if 0
    494.         bz      setlowbyte
    495.         goto    skipvtiming
    496. setlowbyte
    497.         movlw   LOWVCOUNT                           ;low byte count for v sync timing
    498.         movwf   lowbytecount   
    499.         decf    highbytecount                   ;decrement the high byte skip to v low status
    500.         bz      sethighbyte
    501.         goto    skipvtiming2
    502. sethighbyte
    503.         movlw   VLOW                           
    504.         movwf   PORTA
    505.         movlw   HIGHVCOUNT                          ;highbyte count for v sync timing
    506.         movwf   highbytecount
    507.         goto    vlowenable
    508.  
    509. skipvtiming                                         ;timing stall
    510.         nop
    511.         nop
    512.         nop
    513.         nop
    514.         nop
    515.         nop
    516.         nop
    517.         nop
    518.         goto    displayloop
    519. skipvtiming2
    520.         nop
    521.         nop
    522.         nop
    523.         goto    displayloop
     
  18. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    <ed> Ignore this bit, I didn't realise POSTINC0 was an FSR
    Is there some code in the interrupt that is changing POSTINC0?
    If not, pretty much the whole of that code could be replaced by a couple of delay loops.
    If so post the interrupt code.

    </ed>
    If you need to code a short delay using nops, you should consider replacing some of them with "goto $+1" (takes 2 instruction cycles) or "call delay4cycles" (place the label "delay4cycles" immediately before any return statement in the same program memory page [takes 4 instruction cycles]).
     
    Last edited: Dec 28, 2011
  19. THE_RB

    Thread Starter AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    That sounds logical... But a loop would mean minimum 3 cycles per output byte, and possibly 4 cycles as you need to check for the time to end the loop, where his code above gives exactly 2 cycles per output byte. That's probably 100% more hpixel resolution. :)

    To Peter_Morley; where's your timer sync?? :eek:

    It looks like you are just looping the hlines and trying to put some extra NOPs in there to compensate processing time. That is not a great way to do it.

    There's plenty of time at the start of each hline to do a timer sync. :)
     
  20. peter_morley

    Member

    Mar 12, 2011
    179
    0
    Thanks Roman! What do you mean by a timer sync. Would I implement a timer that would interrupt or is this something completely different?
     
Loading...