Delay function using timer/counter 1

avrccounterdelaytimer

i have made a function called _MY_Delay() which use 16bit timer/counter1 in ATMEGA16
, and used this function to blink a LED . the problem is i didn't work and i don't know the reason , here is my code :

 #define  F_CPU 1000000
 #include <avr/io.h>
 #include <avr/interrupt.h>

 void _MY_Delay(int delay){
 int n = (delay*F_CPU)/(1000*64) ; // number of counts required for the given delay 
 OCR1BL = n;                    // n =T(overflow time)*F_cpu / 64
 OCR1BH = n >> 8 ;
 while (!(TIFR & 1<<OCF1B));
 }


 int main(void)
 {
 DDRA = 0x00;
 DDRA |= 0x01;
 TCCR1B = (1<<CS10)|(1<<CS11); //divide by 64 (prescaler)
 sei();
 TIMSK |= 1<< OCIE1B ;
 WDTCR = 0x00; // disable watchdog timer 
 while(1)
 {
    PORTA |= 0x01 ;
    _MY_Delay(100);
    PORTA &= ~(0x01);
    _MY_Delay(100);
 }
 }

Best Answer

The primary problem is with your arithmetic.

The argument to _MY_Delay() is declared as int, and you're passing in the value 100.

The first thing you do is divide the argument by 1000. The result of this division will always be zero.

You'll get more useful results if you do the multiplication first:

void _MY_Delay(int delay){
  int n = (delay*F_CPU)/1000; // number of counts required for the given delay 
  ...
}

... but make sure that the intermediate result won't overflow an integer. If so, use a long.