solved: AtmelStudio, Simulation and 2 Timer not in sync - problem

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,
I'm going to debug a piece of code and I'm experiencining some difficulties. Unfortunately, I hadn't been able to find a solution in the forum yet.

Relevant piece of code:

// timer0 and timer1 are set to essentially the same configuration
volatile unsigned long counter_0a = 0;
volatile unsigned long counter_1a = 0; 

// Interrupt for Timer/Counter0 Compare Match A
ISR ( TIMER0_COMPA_vect ) {
    counter_0a++;
} 

// Interrupt for Timer/Counter1 Compare Match A
ISR ( TIMER1_COMPA_vect ) {
    counter_1a++;
} 

// timer0
TCCR0B |= ((1 << WGM02) | (1 << CS02)); // Configure timer0 for CTC mode, start timer @F_CPU/256
OCR0A = 125;
TIMSK0 |= (1 << OCIE0A); // Enable Timer/Counter Compare Match A interrupt 

// timer1
TCCR1B |= ((1 << WGM12) | (1 << CS12)); // Configure timer1 for CTC mode, start timer @F_CPU/256
OCR1A = 125;
TIMSK1 |= (1 << OCIE1A ); // Enable Timer/Counter Compare Match A interrupt
sei (); // Enable global interrupts

Since I have no HW availalbe yet, I'm using the Atmel Studio Simulation.

After running for some time, starting all from 0, I get the result:

counter_0a = 15;
counter_1a = 30;

I'd expect them both to be in sync?

 

Any suggestions?

 

Thanks in advance!

 

Regards Andreas

Last Edited: Fri. Dec 4, 2015 - 07:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You haven't mentioned which AVR.  Let's assume ATmega48/88/168/328 family.

 

This:

TCCR0B |= ((1 << WGM02) | (1 << CS02)); // Configure timer0 for CTC mode, start timer @F_CPU/256

... actually sets a non-existent timer mode:

 

 

Who knows what the simulator will do in such an instance.  However, as a guess, I'd say it would revert to mode 0, which would explain the roughly 1:2 ratio you are seeing, since the period for TIMER0 would be 256, not 126.

 

You are correctly setting CTC mode for TIMER1.

 

 

 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Fri. Dec 4, 2015 - 05:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using the atmega328p.

 

Yes, your're right. I somehow assumed the registers and configuration for timer0 and timer1 to be symmetrical, but WGM01 is located in TCR0A, and now the results are completely as expected. Thanks!

 

For completeness please find the corrected code:

 

// timer0 and timer1 are set to essentially the same configuration
volatile unsigned long counter_0a = 0; 
volatile unsigned long counter_1a = 0; 

// Interrupt for Timer/Counter0 Compare Match A 
ISR ( TIMER0_COMPA_vect ) { 
    counter_0a++; 
} 

// Interrupt for Timer/Counter1 Compare Match A 
ISR ( TIMER1_COMPA_vect ) { 
    counter_1a++; 
} 

// timer0
TCCR0A |= (1 << WGM01);     // Configure timer0 for CTC mode,
TCCR0B |= (1 << CS02);      // start timer @F_CPU/256 
OCR0A = 125; 
TIMSK0 |= (1 << OCIE0A); // Enable Timer/Counter Compare Match A interrupt 

// timer1 
TCCR1B |= ((1 << WGM12) | (1 << CS12)); // Configure timer1 for CTC mode, start timer @F_CPU/256 
OCR1A = 125; 
TIMSK1 |= (1 << OCIE1A ); // Enable Timer/Counter Compare Match A interrupt 
sei (); // Enable global interrupts

 

Regards Andreas