Arduino VGA via Interrupts

Program Download:

Arduino Sketch
VGA_INTERRUPT.ino

The Software
           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.