Microcontroller : ATmega328P in Arduino Uno
Clock Frequency : 16MHz
void timeDelay_CTC(float sec, unsigned char times) //0.1 <= sec <= 4
{
OCR1A = (sec / 0.000064f) - 1;
TCCR1A = 0b00000000;
TCCR1B = 0b00001101;
for( unsigned char i = 1; i <= times; i++ )
{
while( (TIFR1 & (1<<OCF1A)) == 0 );
TIFR1 |= (1<<OCF1A);
}
TCCR1A = 0;
TCCR1B = 0;
}
The above function is used for calculating the number of time delay cycles and then implement it in CTC mode. It works well. Now, I want to write a similar function in normal mode. The folowing is the code.
void timeDelay_NORM(float sec, unsigned char times)
{
unsigned int cycle = (sec / 0.000064f);
TCNT1 = 65534 - cycle;
TCNT1 = 49910;
TCCR1A = 0b00000000;
TCCR1B = 0b00000101;
for( unsigned char x = 1; x <= 2; x++ )
{
while( (TIFR1 & (1<<TOV1)) == 0 );
TIFR1 |= (1<<TOV1);
}
TCCR1A = 0;
TCCR1B = 0;
}
However, the normal mode function with argument "times" > 1, the time delay will be much longer than expected. So, I tried the following code.
void timeDelay_NORM(float sec, unsigned char times)
{
//unsigned int cycle = (sec / 0.000064f);
//TCNT1 = 65534 - cycle;
TCNT1 = 49910; //Cycles for 0.5sec
TCCR1A = 0b00000000;
TCCR1B = 0b00000101;
//for( unsigned char x = 1; x <= 2; x++ )
//{
while( (TIFR1 & (1<<TOV1)) == 0 ); //Run 0.5sec two times to delay 1sec
TIFR1 |= (1<<TOV1);
while( (TIFR1 & (1<<TOV1)) == 0 );
TIFR1 |= (1<<TOV1);
//}
TCCR1A = 0;
TCCR1B = 0;
}
I found that when it run the following instruction 2 times, the time delay will be much longer than expected. It delay around 5s instead of 1s.
while( (TIFR1 & (1<<TOV1)) == 0 );
TIFR1 |= (1<<TOV1);
Can you teach me how to make it work? Or give me some hints.
Thank you for your help!
You do not reset TCNT1 between the loop iterations.
On the first loop it will count (UINT16_MAX - 49910) cycles. After TOV1 is set, TCNT1 rolls over to 0 (overflow) and counts up all the way to UINT16_MAX which causes the longer delay.