atmega32u4 configure counter in CTC mode

Questions relating to designing PCBs

Moderator: phalanx

Post Reply
nanawhite107
Posts: 2
Joined: Mon Jun 26, 2017 2:10 am

atmega32u4 configure counter in CTC mode

Post by nanawhite107 » Wed Jun 28, 2017 2:05 am

I tried to use the generated clock of timer 4 as input for a counter1 and counter1 should fire the compare match event after 42 clock cycles.

Here is the date sheet of atmega32u4

But I'm not able to reach the desired behavior. Here is a little test code:

#include "Arduino.h"

#define CLOCKPIN 12
#define DEBUGPIN 19

//#define USE_A

// generate 1 MHz from 8 MHz
#define CLOCKCYCLE 3

// UPDATE
#ifdef USE_A
ISR(TIMER1_COMPA_vect) {
#else
ISR(TIMER1_COMPB_vect) {
#endif
digitalWrite(DEBUGPIN,HIGH);
digitalWrite(DEBUGPIN,LOW);
}

void setup()
{

// set up pins
pinMode(CLOCKPIN, OUTPUT);
pinMode(DEBUGPIN, OUTPUT);

//--------------------- generate clock -------------------
// reset timer4
OCR4C = 0;
OCR4D = 0;

TCCR4A = 0x00;
TCCR4B = 0x00;
TCCR4C = 0x00;
TCCR4D = 0x00;

TCNT4=0;

// Toggle OC4D on Compare Match | enable PWM
TCCR4C = _BV(COM4D0) | _BV(PWM4D);


// Clear Timer on Compare Match
TCCR4D = _BV(WGM41);

// set lock bit for sync update
TCCR4E = _BV(TLOCK4);

// Set compare value
OCR4C = CLOCKCYCLE*2;
OCR4D = CLOCKCYCLE;

// No prescaling
TCCR4B = _BV(CS10);

//--------------------- setup counter -------------------

//reset timer
TCNT1 = 0;

// disable
TCCR1A = 0;
TCCR1B = 0;

// clear interrupt flags
TIFR1 = _BV(OCF1A) | _BV(OCF1B);


// trigger on falling edge of T1
TCCR1B = _BV(CS12) | _BV(CS11) | _BV(CS10) | _BV(WGM12);


#ifdef USE_A
// interrupt on every 42. cycle
OCR1A = 42;

// turn on compare A interrupt.
TIMSK1 = _BV(OCIE1A);
#else
// interrupt on every 42. cycle
OCR1B = 42;

// turn on compare B interrupt.
TIMSK1 = _BV(OCIE1B);
#endif
}

loop is empty.

With define USE_A I get the following waveform: USE_A the interrupt is fired every ~66200µs sounds like the 16bit counter overflow.

With define USE_A commented out I got the following wired result: USE_B 219µs clock on 1180µs clock of. the only idea I have for this is a reset or something.

Does anybody have an idea whats wrong with my counter code?
UPDATE:

Changed the missing flag and ISR call. Now does USE_A look like this: USE_A1 Top should now set to 42 and reset to 0 after interrupt occured? But currently it takes nearly twice the time...

Post Reply