I am trying to get an understanding how to program the timers in C on a Arduino nano.
I have a simple internal class to set the Led on the board on and off every 1000 update calls.
class Led2 {
int ledPin;
int ledState;
int divider;
public:
Led2(int pin) {
ledPin = pin;
pinMode(ledPin, OUTPUT);
ledState = LOW;
divider = 0;
}
void Update() {
divider++;
if (divider >= 1000) {
if (ledState == LOW) {
ledState = HIGH;
digitalWrite(ledPin, ledState);
} else {
ledState = LOW;
digitalWrite(ledPin, ledState);
}
divider = 0;
}
}
};
I have set the output compare register A for timer 0 to 0x01. Just a random value. Any value should be ok, right ?
// Timer 0 output compare register A
OCR0A = 0x01;
The prescaler has been set to 0x3E (62) to get a frequency of 1000Hz. So there are 16000000/256/1000 'ticks' required to increase the counter in register A. Correct ?
TCCR0A = 0x3E;
The timer compare interrupt for timer 0 register a is set
The hardware is not necessarily ready to be diddled with when your constructor is called. You should, therefore, NOT be diddling with the hardware in the constructor. You SHOULD have a begin() method where the hardware diddling is done.
@PaulS Thanks for your reply, but this is not an answer to the question.
In the mean time i have been googling around to find some useful documentation that clearly explains how to set timers and interrupts. These articles from maxembedded clearly explain how to set timers and interrupts.
These helped me out to set the correct register values to create an interrupt every 1ms.
// TCCR
// CPU Freq 16Mhz
// Need interval of 1Ms ==> 0,001/(1/16000000) = 16.000 ticks
//
// Prescaler 64 ==> resolution changes from 0,0000000625 to 0,000004
// Need interval of 1Ms ==> 0,001/((1/16000000)*64) = 250 ticks
// Set prescaler to 64 ; (1 << CS01)|(1 << CS00)
// Clear Timer on Compare (CTC) mode ; (1 << WGM02)
TCCR0A = 0 ;
TCCR0B |= (1 << WGM02)|(1 << CS01)|(1 << CS00) ;
// set Output Compare Register to (250 - 1) ticks
OCR0A = 0xF9;
// TCNT0
// Timer count = (required delay/clock time period) - 1
// 249 = (0,001/0,000004) - 1
// initialize counter
TCNT0 = 0 ;
// TIMSK0
// Set Timer Interrupt Mask Register to
// Clear Timer on Compare channel A for timer 0
TIMSK0 |= (1 << OCIE0A) ;
After setting the registers accordingly the Interrupt Service Routine (ISR) is called every 1ms and the led is blinking every 1 second
As a heads up to anyone thinking of using this - be aware that it trashes millis(), since it reconfigures the builtin timer0 which is used for millis (and PWM on 2 pins)