volatile bool isr_t0a_flag = false;
volatile uint32_t isr_t0a_delta_time = 0;
#define TIMER_0_COMPARE_A_POST_SCALER 50
volatile bool isr_t0b_flag = false;
volatile uint32_t isr_t0b_delta_time = 0;
#define TIMER_0_COMPARE_B_POST_SCALER 100
void PrintTimer0()
{
char buffer[20];
Serial.println("\nTimer 0");
sprintf(buffer, " TCCR0A = 0x%02x", TCCR0A);
Serial.println(buffer);
sprintf(buffer, " TCCR0B = 0x%02x", TCCR0B);
Serial.println(buffer);
sprintf(buffer, " OCR0A = 0x%02x", OCR0A);
Serial.println(buffer);
sprintf(buffer, " OCR0B = 0x%02x", OCR0B);
Serial.println(buffer);
sprintf(buffer, " TIMSK0 = 0x%02x", TIMSK0);
Serial.println(buffer);
}
void setup()
{
Serial.begin(115200);
Serial.print("\n");
// Find out what Timer0 has been initialised to.
PrintTimer0();
// Serial.println(TCCR0A, HEX); // 3 = Fast PWM mode with a fixed timeout of 255.
// Serial.println(TCCR0B, HEX); // 3 = 64 prescaler.
// Serial.println(OCR0A, HEX); // 0
// Serial.println(OCR0B, HEX); // 0
// Serial.println(TIMSK0, HEX); // 1 = Timer overflow interrupt enabled for millis()/micros().
// Serial.print("\n\n");
cli(); // Disable interrupts.
//
// Set Timer0 compare interrupts
//
// Clock frequency = 16 MHz
// Prescaler = 64
// Timeout = 255
//
// Overflow interrupt frequency = 16 MHz / 64 / (255 + 1) = 977 Hz (1024 us)
// Overflow interrupt frequency = 8 MHz / 64 / (255 + 1) = 488 Hz (2048 us)
//
OCR0A = 0x55; // Set 1/3rd phase shift for compare A.
OCR0B = 0xAA; // Set 2/3rds phase shift for compare B.
TIMSK0 |= (1 << OCIE0A); // Enable compare A interrupt.
TIMSK0 |= (1 << OCIE0B); // Enable compare B interrupt.
sei(); // Enable interrupts.
// Verification.
PrintTimer0();
// Serial.println(TCCR0A, HEX); // 3 = Fast PWM mode with a fixed timeout of 255.
// Serial.println(TCCR0B, HEX); // 3 = 64 prescaler.
// Serial.println(OCR0A, HEX); // 85 = 1/3rd phase shift for compare A.
// Serial.println(OCR0B, HEX); // 170 = 2/3rds phase shift for compare B.
// Serial.println(TIMSK0, HEX); // 7 = All 3 interrupts enabled.
// Serial.print("\n\n");
}
void loop()
{
uint32_t t0a_delta_time = 0;
uint32_t t0b_delta_time = 0;
////////////////////////////
// BEGIN CRITICAL SECTION
cli(); // Disable interupts.
bool t0a_flag = isr_t0a_flag;
if (t0a_flag)
{
t0a_delta_time = isr_t0a_delta_time;
isr_t0a_flag = false;
}
bool t0b_flag = isr_t0b_flag;
if (t0b_flag)
{
t0b_delta_time = isr_t0b_delta_time;
isr_t0b_flag = false;
}
sei(); // Enable interrupts.
// END CRITICAL SECTION
////////////////////////////
if (t0a_flag)
{
Serial.print("T0a ");
Serial.println(t0a_delta_time);
}
if (t0b_flag)
{
Serial.print("T0b ");
Serial.println(t0b_delta_time);
}
}
ISR(TIMER0_COMPA_vect)
{
static byte count = 0;
count++;
if (count >= TIMER_0_COMPARE_A_POST_SCALER)
{
count = 0;
static uint32_t previous_time = 0;
uint32_t time = micros();
uint32_t delta_time = time - previous_time;
previous_time = time;
isr_t0a_delta_time = delta_time;
isr_t0a_flag = true;
}
}
ISR(TIMER0_COMPB_vect)
{
static byte count = 0;
count++;
if (count >= TIMER_0_COMPARE_B_POST_SCALER)
{
count = 0;
static uint32_t previous_time = 0;
uint32_t time = micros();
uint32_t delta_time = time - previous_time;
previous_time = time;
isr_t0b_delta_time = delta_time;
isr_t0b_flag = true;
}
}