Need help with Timer2 programming

I tried everything to be able to run it.But it doesn't work.if anyone can help me,it's very much appreciated.



void myDelay() {
  

  
  // Timer Overflow Interrupt Enabled (TOIE2)
  TIMSK2 = 1 << TOIE2;
 
// assign 0 to Timer Counter 2
  TCNT2 = 0;

// Choose Normal mode of operation
 TCCR2A = 0;

  // Load values for Control register for prescale of 1024
  TCCR2B |= (1<<CS20) |(1<<CS21)| (1<<CS22);

// Check overflow vector  
  while((TIFR2 & (1 << TOV2) )==0);
  TCCR2B = 0;
  TIFR2 = (1 << TOV2);



}

void setup()
{
  DDRB |= (1 << PB0);
  
  myDelay();
}

void loop()
{
 PORTB ^= (1 << PB0);

}

What should it do ?
What does it actually do ?

Have you looked at the sample sketches?

where is the ISR then ? You probably don't need that.

The myDelay() function is using polling as the code waits for an overflow without taking advantage of interrupts, so it uses a busy-wait loop (while((TIFR2 & (1 << TOV2)) == 0); ), which is not efficient...

You should just use delay()...

Why is the title of your thread "Need help with Timer0 programming" when you're using Timer2?

Well, I am trying to learn register and timer programming and so far, i wasn't very successful at it.I am trying to mimic the behaviour of delay() function.myDelay() function must go into infinite loop for some reason because the connected led on pin 8 (PB0) doesn't light up.Thank you

Sorry, I corrected it.

May be this would be of interest

https://docs.arduino.cc/tutorials/generic/secrets-of-arduino-pwm/

1 Like

Thank you for the reply.I will read it but what is wrong in my code? Even I put myDelay() routinue in the loop() section the code doesn't turn led on.

Post that code, using code tags.

If you enable the TIMSK2 register bit, it will interrupt on overflow. But you have no ISR defined. So you probably should leave that off. You can still read the flag register though, but you need to clear the flag after you set the count to zero because it might already be set.

So from your post #1 it seems you want to delay for as long as it takes for the timer to overflow after starting at zero. Is that right?

I'm no expert on timer operations, but here's code I finally got to work where the order in which you set up the registers matters. I found that if I clear both control registers first, then set up the other registers, then finally set up the control registers, it seems to work.

//This demonstrates PWM output on D10.  The key to making it work
//is the order of register settings, turning on the clock at the
//very end.

void setup () {
  // Pin 10(OC1B) is output
  pinMode(10, OUTPUT);
  TCCR1A = 0;
  TCCR1B = 0;

  //Load 1000 into OCR1A for 15.98KHz
  OCR1A = 1000;

  //Load 200 into OCR1B for 20% duty cycle
  OCR1B = 200;

  // non-inverted fast PWM on OC1B with prescalar of 1 for 15.98KHz fast PWM
  TCCR1A = (1 << COM1B1) | (1 << WGM11) | (1 << WGM10);
  TCCR1B = (1 << WGM13) | (1 << WGM12) | (0b001 << CS10);
}

void loop() {
}

Hi Jremington, I changed the timer to Timer1 and made slight changes to increase readibility .This code still doesn't work.If you copy and paste it in IDE,you will see the LED is always on.


void myDelay() {
  // Prescale of 1024 is selected in control registers
  TCCR1B |= (1 << CS10) | (1 << CS12);

  // Normal Mode of operation is selected
  TCCR1A = 0;

  // 1 second time interval value is assigned
  TCNT1 = 65535 - (16000000 / 1024);

  // TOV1 flag is checked 
  while ((TIFR1 & (1 << TOV1)) == 0);

  // Timer is stopped 
  TCCR1B = 0;
  TCCR1A = 0;

  // TOV1 is cleared 
  TIFR1 = (1 << TOV1);
  
}

void setup() {
  // BUILTIN_LED is assigned as output
  DDRB |= (1 << PB5);
}

void loop() {
  // LED is on and off
  PORTB ^= (1 << PB5);

  // Delaying the time 1 second
  myDelay();
}

You were not initializing Timer1 correctly. Do not use bitwise OR to set the register, if you don't know the previous contents. This works as expected:

void myDelay() {
  // Normal Mode of operation is selected
  TCCR1A = 0;
  // Prescale of 1024 is selected in control registers
  TCCR1B = (1 << CS10) | (1 << CS12);

  // 1 second time interval value is assigned
  TCNT1 = 65535 - (16000000 / 1024);

  // TOV1 flag is checked 
  while ((TIFR1 & (1 << TOV1)) == 0);

  // Timer is stopped 
  TCCR1B = 0;
  TCCR1A = 0;

  // TOV1 is cleared 
  TIFR1 = (1 << TOV1);
  
}

void setup() {
  // BUILTIN_LED is assigned as output
  DDRB |= (1 << PB5);
}

void loop() {
  // LED is on and off
  PINB = (1 << PB5);  //toggle PB5, works only on AVR processors

  // Delaying the time 1 second
  myDelay();
}
1 Like

Thank you very much indeed.I couldn't see it coming really.Do you know the reason behind why we use logic one (1) to clear TOV1 flag?

Because that is what the processor data sheet tells us to do. Who knows why the designers made that decision? That was over 30 years ago.

Also, is important to clear TCCR1A before setting any other registers.

1 Like

Thank you for the side note.Do you know when does the timer ticking start? I mean after what instruction exactly does it start?

I believe that in the case of the code above, ticking starts at the expected frequency after TCCR1B has been set. It may be ticking all the time, because you don't know what is in TCCR1B when the routine is first entered.

For that reason, I always set both TCCR1A and TCCR1B to zero, to stop the timer before doing anything else.

1 Like

"Write One to Clear" is a common paradigm when dealing with with certain processor registers.

There are systems where grounding (writing a 0) is what triggers an action like in some relays. However, in the context of many processor registers, the convention of W1C is used because it aligns with the broader design principle where a 1 typically asserts a change or action, while a 0 is treated as passive or inactive.

This is not a universal rule, but rather a choice of convention for clarity and consistency in certain hardware designs.

To continue with my example, for relays, grounding (writing a 0) to trigger is security-driven, as it ensures the circuit is safe in case of power loss or signal interruption.

1 Like

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