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.