Timer1 TCCR1A WGM10 (TOP = 0x00FF) on Arduino Uno R3 - not working as expected?

Hello! I'm currently looking at timers, and have come upon the situation where timer 1 seems to be going at half the speed I am expecting when TCCR1A bit WGM10 is set, for a top of 0x00FF

Code:

void wasteabout1second(){//actually takes 2 seconds...
  noInterrupts();

  asm volatile(
    
  //count about 16 million clocks
  "   ldi     r21, 244         \n"// = 16000000/65535
  "   clr     __tmp_reg__      \n"
  
  "   sts     0x85, __zero_reg__ \n"//reset timer1
  "   sts     0x84, __zero_reg__ \n"
  "   sbi     0x16, 0            \n"//clear timer1 overflow flag
  
  "loopstart: "
  "  sbis 0x16, 0   \n"
  "  rjmp loopstart \n"//if no overflow, loop
  
  "  sbi 0x16, 0    \n"//clear the timer overflow flag. 256 cycles have passed?
  "  dec __tmp_reg__\n"
  "  brne loopstart \n"

  "   dec r21       \n"//once zero, roughly 256*256*241 cycles passed = 15.79m cycles
  "  brne loopstart \n"

  "sei              \n"//re enable interrupts for serial
    : //outputs
    : //inputs
    : "r21"//clobbers
  );
};

void setup() {
  Serial.begin(115200);
  TCCR1C = 0;
  TCCR1B = bit(CS10);//set timer1 no clock divider
  TCCR1A = bit(WGM10);//set timer1 to 0x0000 - 0x00FF
}

void loop() {
  wasteabout1second();
  Serial.print("\n");//show timestamp (or toggle an led or whatever instead)
}

Am I doing something wrong? Cheers if you can help!

Without looking into details: PWM modes except FastPWM run at half speed: first half counting up to TOP, second half counting down to BOTTOM.

Looking into the details, just setting TCCR1A to bit(WGM10) is indeed a phase correct mode that both counts up and down:

Thanks to both of you for looking!, (I think I now understand what the TOV happening at BOTTOM is all about), so that should explain the results of that code...

however, changing one line, setting TCCR1A = 5;, (Fast PWM, 8-bit), I'm still getting the same result, 2 seconds to overflow it 256*244 times... Any ideas?

More bits in the other registers affect the mode.

2 Likes

I have looked at this SO MANY TIMES, and was 100% CERTAIN that only WGM13 was to be found in a different register, and I wasn't using that...

anyway, it absolutely isn't, so with

TCCR1B = bit(CS10)|bit(WGM12);
TCCR1A = bit(WGM10);

it's working as expected...

Cheers!

1 Like

This is part of the initializing routine of Arduino IDE

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.