Timer0 Challenge

I am not sure why, but the below code is not working.
I have tried to use timer0 of an Arduino Uno to delay time in milliseconds. Any help would be appreciated...

#include <avr/io.h>

//prototypes of functions
void delay_with_timer0();
void delay_generic(unsigned long);

void setup() {
  //initializing built in LED as output
  pinMode(LED_BUILTIN, OUTPUT);
  
  //enabling serial monitoring for debugging
  Serial.begin(9600);
}

void loop(){
  //turning built in LED on and off
  digitalWrite(LED_BUILTIN, HIGH);
  delay_generic(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay_generic(1000);
  Serial.print("SUCCESS\n");
}

void delay_with_timer0(){  
  //disable I-Flag
  cli();
  
  //initializing clock to zero
  TCNT0 = 0;
  
  //sets to normal mode
  TCCR0A = (0 << WGM00);
  TCCR0A = (0 << WGM01);
  TCCR0B = (0 << WGM02);
  
  //sets prescaler
  TCCR0B = (0 << CS00);
  TCCR0B = (1 << CS01);
  TCCR0B = (0 << CS02);
  
  //waiting for the overflow flag to be set
  while(true){
    if(TIFR0 |= (1 == TOV0)){
      break;
    }
  }
  
  //stops the clock
  TCCR0B = (0 << CS00);
  TCCR0B = (0 << CS01);
  TCCR0B = (0 << CS02);
  
  //clears TOV0 flag
  TIFR0 = (0 << TOV0);
  
  //enable I-Flag
  sei();
}

void delay_generic(unsigned long ms){
  //for loop that uses delay_with_timer0() function
  for(int i = 0; i < ms*250; i++){
    delay_with_timer0();
  }
}

"not working".... how? Please give details...

It does not delay time properly. I am not sure if it delays time at all besides due to the code itself being repeated numerous times.

Google a bit more, you are going about a perfectly reasonable experiment in an unconventional manner, at least I usually see

setup - configure all timer 0 control bits

use - examine and change only a few things

also odd and not what you want to do is mess with the interrupt stuff. No need whatsoever to accomplish simple timing using timer 0.

a7

Try looking at the TimerOne library

that looks pretty nonsensical. Surely you want

  if (TIFR0 & (1<<TOV0)) {

Use TCCR0B = 0<<CS02 | 1<<CS01 | 0<<CS00 instead

That is NOT how you set and clear individual bits in hardware registers. You need something like:

  // Initialize the registers to 0
  TCCR0A = 0;
  TCCR0B = 0;

  //sets to normal mode
  TCCR0A &= ~(1 << WGM00);  // Clear bit
  TCCR0A &= ~(1 << WGM01);  // Clear bit
  TCCR0B &= ~(1 << WGM02);  // Clear bit
  
  //sets prescaler
  TCCR0B &= ~(1 << CS00);  // Clear bit
  TCCR0B |=    (1 << CS01);  // Set bit
  TCCR0B &= ~(1 << CS02);  // Clear bit

Note: Once the registers are set to 0 there is no need to clear bits.

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