Development - driving VGA monitors

Status
Not open for further replies.

millwood

Banned
I thought that there may be some interest in driving VGA monitors with a mcu. My motivation is to use those monitors to display analog signals digitized by a MCU.

so I thought to set out and see if we can collectively write something about it.

I think in the end, it will need a very fast processor to achieve adequate horizontal resolutions but for development purposes, i will do it on a pic using picc/tide. we can always port the code to something faster (like an ARM7 chip).
 
I started working on it and quickly confirmed my fear: you will need an extremely mcu to reach any respectable horizontal resolution.

the pic does 1 instruction per 1us. the horizontal timing of vga is about 32us, 25us for the viewable area so in maximum we can execute 25 instruction each line.

I compiled my code (see below) in TIDE and in the disassembly window, each "bit" takes 20 instructions. In other words, by the time I finish drawing one bit, I am done. so I will have a horizontal resolution of 1. not cool at all.

here is the rough code in case others want to persue it.

Code:
#include <htc.h>

//hardware configuration
#define R		GPIO0				//red on GPIO0
#define G		GPIO1				//green on gpio1
#define B		GPIO2				//blue on gpio2
#define HSync	GPIO4				//hsync on gpio4
#define VSync	GPIO5				//vsync on gpio5
//end hardware configuration

//macros


//function declaration
void mcu_init(void);	//initialize the mcu;

//global variables
//1-bit colors for now
#define RED			0b00000001		//red is 0th bit
#define GREEN		0b00000010		//green is the 1st bit
#define BLUE		0b00000100		//BLUE is the 2nd bit
#define CLR_MASK	RED|GREEN|BLUE	//port mask used to set the output, value depends on hardware configuration. only the bits set to 1 will be changed.
#define BLACK		0b00000000		//black is nothing
#define H_Res		8		//horizontal resolution
#define V_Res		1		//vertical resolution, set at 1 for now.
const char Vid_RAM[V_Res][H_Res] = {		//display ram
		{RED, GREEN, BLUE, RED|GREEN, RED|BLUE, GREEN|BLUE, RED|GREEN|BLUE, BLACK}
		};

void mcu_init(void) {			//initialize the mcu

}

void
main(void)
{
	int h_index, v_index;		//horizontal and vertical indexes;
	char GPIO_VandH;			//GPIO's VSync and HSync bits;
	mcu_init();
	VSync=0;					//Vsync is normally low;
	HSync=0;					//Hsync is normally low;
	while (1){
		//TODO Auto-generated main function
		for (v_index=0; v_index<V_Res*0+200; v_index++){		//one line at a time, v_index should reach V_res but for now, we will try to just repeat the same line
			for (h_index=0; h_index<H_Res; h_index++) {			//now, generate each line
				GPIO = Vid_RAM[0][h_index];						//output video ram's content
			}
			HSync=1;			//send the hsync signal;
			NOP();
			NOP();
			NOP();
			HSync=0;			//reset the hsync signal;
		}
		VSync=1;				//send the VSync signal;
		NOP();					//may need more nop;
		VSync=0;				//reset the Vsync signal;
	}
}
 
heh thats at only 4mhz lol a 40 mhz pic should do 1 cycle at 0.0000001 Second. AKA 100nS
 
Last edited:
ronsimpson: that's one interesting device. coupled with the base board it would have been a perfect solution, if not for the rs232 interface. I wonder if the SPI mode works - that would have allowed a much faster conversation between the graphics card and the mcu.

Jason: if it does take 20 cycles to execute one "pixel", to reach a 480 pixel on a line, you need to execute 10,000 cycles in 25us. or about 2.5ns per cycle. that equates to a pic running at 160mhz, .

obviously, you can optimize the code to reduce the number of cycles per line but looks like a FPGA solution is the way to go there.
 
Im sure its possible with a lower speed and something is getting miscalculated.
 
Last edited:
I started working on it and quickly confirmed my fear: you will need an extremely mcu to reach any respectable horizontal resolution.

It depends exactly what you're trying to do?, check the PICLIST where there's a VERY old design for an audio spectrum analyser that does FFT and directly drives a VGA monitor using an old 17 series PIC.
 
Jason, the program I was writting is capable of 8 bit color (3 bits each for two colors and 2 bits for the 3rd color, identical to that sparkfun module). it could also go to 480 pixels horizontally, with a fast enough mcu.

I looked only at the 16f84 one and it has one bit (green) color output, and it has 26 horizontal pixels.

Eric's model has 52 instructions per line - so I am not sure if he is running his chip 2x as fast or he was working on a non-vga monitor - looks like he was running on CGA which is 240 horizontally.

Craft's model does 6 bits of colors. I couldn't go through craft's files - the formating is messed up on my computer. but the horizontal resolution appears to be low.

I think programming in C for this purpose is pushing the limit of the mcu.
 
It depends exactly what you're trying to do?, check the PICLIST where there's a VERY old design for an audio spectrum analyser that does FFT and directly drives a VGA monitor using an old 17 series PIC.

that's also a 3bits design: one bit each for three colors. the source files talked about finishing a line in 169 cycles so the horizontal resolution couldn't have been more than 169 pixels.
 
Last time I used a FPGA. It it eazy to hit 100m pix/sec.

The first time I did this I needed to move data very fast for that CPU (8051). I used the POP instruction to move 2-8 bit numbers from memory to video. I made hardward to capture data during the POP instructions. (POP= move byte1, move byte2 and inc pointer by 2)

"takes 20 instructions" Why 20? That seems slow.

I have used DMA and an ARM.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…