There are two main portions of code that you'll see explained and in detail below:
-Initialization and Main Loop
-Interrupt Control
There isn't much in the initialization and main code, which is how it should be in an interrupt driven system. Below you can see the start-up settings and variables used. One very important thing to note is that Timer0 must be turned off. Arduino uses Timer0 to generate functions like millis() and will mess up our timing if they're left enabled.
Initialization
------------« Begin Code »------------
.. ... int i = 0; int color = 0; void setup() { //Get Rid Of Dumb Timer0 (millis()/micros() functions) TIMSK0 = 0x00; DDRB = 0xFF; //PortB Is Used As Outputs DDRD = 0xFF; //PortD Is Used As Outputs // initialize timer1 cli(); // disable all interrupts TCCR1A = 0; TCCR1B = 0; TCNT1 = 65536-27; // preload timer 65536 - 27 instructions TCCR1B |= (1 << CS10); // 1 prescaler TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt sei(); // enable all interruptss color = 0x10; // set default color red } /* In the loop we're just setting what color should be output... 200 Blue.. 200 Green... 200 Red....... */ void loop() { if(i == 1) color = 0x04; if(i == 200) color = 0x08; if(i == 400) color = 0x10; } .. ...
------------« End Code »------------
The interrupt control portion of the code is where all the action is at. Every 3.2uS the following 23.2uS of instructions must be executed, in order to conform to the VGA standard for 800x600 @ 60 Hz resolution.
Main Loop
------------« Begin Code »------------
... .. /// ISR Timer Routine ISR(TIMER1_OVF_vect) { HSYNC_LOW; //HSYNC Low if(i > 622) VSYNC_HIGH; else VSYNC_LOW; //Color High PORTB = color; microsecond_delay; __asm__("nop\n\t""nop\n\t""nop\n\t"); //20uS Color Data //10 uS Delay microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; //10 uS Delay microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; microsecond_delay; //Color Low PORTB = 0x00; i++; if(i==627) i=0; //3.2uS Horizontal Sync TCNT1 = 65536-27; // preload timer for next interrupt flag HSYNC_HIGH; //HSYNC High }
------------« End Code »------------
With the software written and completed, let's load the software onto our arduino and give it a test.