For my led screen project, I'm trying to implement bit angle modulation to control the brightness of some leds. Part of that requires the use of interrupts to help refresh the screen and control how long leds are actually on.
I decided to use Timer0 (and yes I know that messes with delay() and millis()), and was able to get the timer running. For whatever reason though, I cannot seem to get the ISR to fire. I've read through the datasheet for the '328 and it seems like the flag to trigger the interrupt is automatically set upon compare match with TCNT0 and OCR0A. I know it is matching because I currently have the OC0A pin toggling and can see the waveform on my scope, but the ISR still won't go. I've looked at many many sites online and compared code and everything SHOULD be fine as far as I can tell. But I probably missed something....can you all look and see if I screwed up somewhere?
/*
* MasterCode.cpp
*
* Created: 5/7/2014 4:09:49 PM
* Author: Brandon
*/
#include <avr/io.h>
#include "Arduino.h"
#include "MasterSPI.h"
#define refresh 100 //refresh frequency in Hertz
volatile int timer[4];
volatile int pos=0;
void initializeInterrupt(int refreshRate)
{
//timer[] corresponds to bits 3, 2, 1, 0 respectively for BAM
//don't worrry about this part
timer[0] = 1000000/(refreshRate*128);
timer[1] = 1000000/(refreshRate*256);
timer[2] = 1000000/(refreshRate*512);
timer[3] = 1000000/(refreshRate*1024);
//disable global interrupts and clear control registers
cli();
TCCR0A = 0;
TCCR0B = 0;
//set compare match MAX (random test val to see if working)
OCR0A = 10;
//turn on CTC mode and toggle OC0A upon match (just for testing purposes)
TCCR0A |= ((1<<WGM01)|(1<<COM0A0));
//sets prescaler to 1024
TCCR0B |= ((1<<CS02)|(1<<CS00));
//enables interrupts for COMP0A
TIMSK0 |= (1<<OCIE0A);
//enable global interrupts
sei();
}
int main(void)
{
MasterSPI SPI;
SPI.setup();
//set intPin as output and low
DDRC = (1<<PORTC2);
PORTC &= ~(1<<PORTC2);
//test for OC0A...ignore
DDRD |= (1<<PORTD6);
initializeInterrupt(100);
while(1)
{
//do stuff here...
}
}
ISR(TIMER0_COMPA_vect)
{
//toggle the pin high or low
if(PORTC2)
PORTC &= ~(1<<PORTC2);
else
PORTC |= (1<<PORTC2);
/*
//Update the OCR0A value
pos++;
OCR0A = timer[pos];
if(pos==3)
pos=0;
*/
}