AVR Timer - Doubt on While Condition

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I was reading the book about AVR and came across the following code :

 

#include "avr/io.h"

void T0Delay();

int main()
{
    DDRB = 0xFF;        //declare PORTB as output
    
    while(1)
    {
        PORTB = 0xFF;   //set all bits in PORTB
        T0Delay();      //delay
        PORTB = 0x00;   //clear all bits in PORTB
        T0Delay();      //delay
    }
}

void T0Delay()          //delay function
{
    TCNT0 = 0x20;       //load TCNT0    
    TCCR0 = 0x01;       //Timer0, Normal mode, no prescaler used <== This is where my confusion rises
    while ((TIFR&0x01)==0); //wait for TF0 to roll over
    TCCR0 = 0;
    TIFR = 0x01;        //clear TFO
}

 

Here is my logic :

1. 'Roll over' means the timer will go from $FF to $00 causing the Timer Overflow Flag(TOV0) sets to '1'

2. When the TOV0 is set, we want to turn off the timer(TCCR0 = 0), and clear the TOV0 Flag (TIFR = 0x01), these are done so that delay function can be used afterward.

3. What I don't get is why we write "while ((TIFR&0x01)==0)." Doesn't it mean "check if TOV0 = 0" ? Shouldn't we check it when TOV0 = 1 (when overflow happens) ?

Thanks :)
 

3. 

This topic has a solution.

Last Edited: Tue. Nov 13, 2018 - 05:42 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, It checks if it is zero so that it waits at this point and only continues when overflow occurs.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

RichMo wrote:

Yes, It checks if it is zero so that it waits at this point and only continues when overflow occurs.

So do you mean 'while' is used to halt the code temporarily?

 

If I'm not mistaken in C it should be like

while (condition) {

statement }

 

So if condition TRUE, then do the statement

In this case, the condition 'TOV = 0', is TRUE from the beginning isn't it? So then it should move to 'TCCR0 = 0'

Is my understanding incorrect regarding while logic?

 

Last Edited: Thu. Oct 18, 2018 - 02:53 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 3

raivata wrote:
So do you mean 'while' is used to halt the code temporarily?

Imagine that you have a conventional mailbox at the end of your driveway.  You have it rigged with one of those flags that raises into the air when the mail carrier opens the mailbox and delivers.

So you sit in the house looking out the window at the mailbox.  You look over and over and over again.  If you care  to, you can do other stuff between looks.  In the case of your sample code, nothing is done except continual looks out the window?  How many flags do you see?  Zero.  Then look again.  How many flags do you see?  Zero.  Then look again.  How many flags do you see?  Zero.  Then look again.  ...

 

Until you see >>one<< flag, and then you move away from that monitoring window and proceed to do stuff, like walk down and get the mail.  You then reset the flag for the next time...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

The while() does NOT "halt" things though it may seem like it does. In fact, the code is sitting in a very tight loop, rechecking the argument on every pass through the loop. So, it has the end effect of halting and waiting for the test condition to change, but really never stops.

 

This is actually a key characteristic of microcontrollers. With the exception of "sleep" or its equivalent, the machine never stops. It executes new code on every clock tick, or maybe parts of new code. It is always, with the fore-mentioned sleep exception, grinding away at the code in its memory.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

raivata wrote:

while ((TIFR&0x01)==0); //wait for TF0 to roll over

 

Probably what's confusing is the lack of a block after the while

statement.  The semicolon after the test is the block.  An empty

one that does nothing.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

If you're having trouble wrapping your head around the logic, it can help to rewrite it into a form that makes sense to you:

while ((TIFR&0x01)==0);
while (!(TIFR & 0x01));
while (!(TIFR & (1 << TOV0));
while (!(TIFR & (1 << TOV0)) {}
while (1) {
  if (TIFR & (1 << TOV0))) {
    break;
  }
}
do {
  if (TIFR & (1 << TOV0))) {
    break;
  }
} while (1);
do {
} while (!(TIFR & (1 << TOV0)));

The above are all equivalent (unless I've made a typo...).

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

raivata wrote:

while ((TIFR&0x01)==0); //wait for TF0 to roll over

 

Probably what's confusing is the lack of a block after the while

statement.  The semicolon after the test is the block.  An empty

one that does nothing.

 

--Mike

 

Yes.  I would write it like this, to give a bit more visual cue

 

while ((TIFR&0x01)==0) //wait for TF0 to roll over
{}

or

 

while ((TIFR&0x01)==0) //wait for TF0 to roll over
   ;
Last Edited: Thu. Oct 18, 2018 - 05:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd suggest always using braces - that way one or more statements may later be added to execute while the while() is waiting.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
while the while

I'll wager you have waited your whole life to pull out that one, and by-the-by the opportunity came along.

 

https://www.dailywritingtips.com... With my 3rd-grade sense of humor, I especially like the do-do one.

 

1. “What you do do is your own business.”

2. “They had had many arguments.”

3. “I showed her her message.”

...

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My favourite one of these concerns signs hanging outside of pubs. Up our road was a pub called the "Bell and Gate". They got in a sign writer to re-do the sign and he painstakingly repainted the wording. But then some wag pointed out an error in the spacing of the words. Apparently "the spacing between Bell and and and and and Gate did not match". Oh dear!

 

EDIT: googling this to find the original origin brought me to this on Wikipedia:

Martin Gardner offered the example: "Wouldn't the sentence 'I want to put a hyphen between the words Fish and And and And and Chips in my Fish-And-Chips sign' have been clearer if quotation marks had been placed before Fish, and between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips?

You gotta love Martin Gardner !! 

Last Edited: Fri. Oct 19, 2018 - 02:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Apparently "the spacing between Bell and and and and and Gate did not match". Oh dear!

Lol.  Not exactly the same, but I saw on a "true crime" TV show where the victim/suspect were last seen at the tavern called Richard Cranium's.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

"... between Fish and and, and and and And, and And and and, and and and And, and And and and, and and and Chips, as well as after Chips?"

 

Brilliant!!!

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
They got in a sign writer to re-do the sign and he painstakingly repainted the wording.

The painter's Cockney 'elper gave a 'and on that job.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Fri. Oct 19, 2018 - 06:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

theusch wrote:

raivata wrote:
So do you mean 'while' is used to halt the code temporarily?

Imagine that you have a conventional mailbox at the end of your driveway.  You have it rigged with one of those flags that raises into the air when the mail carrier opens the mailbox and delivers.

So you sit in the house looking out the window at the mailbox.  You look over and over and over again.  If you care  to, you can do other stuff between looks.  In the case of your sample code, nothing is done except continual looks out the window?  How many flags do you see?  Zero.  Then look again.  How many flags do you see?  Zero.  Then look again.  How many flags do you see?  Zero.  Then look again.  ...

 

Until you see >>one<< flag, and then you move away from that monitoring window and proceed to do stuff, like walk down and get the mail.  You then reset the flag for the next time...

 

 

ka7ehk wrote:

The while() does NOT "halt" things though it may seem like it does. In fact, the code is sitting in a very tight loop, rechecking the argument on every pass through the loop. So, it has the end effect of halting and waiting for the test condition to change, but really never stops.

 

This is actually a key characteristic of microcontrollers. With the exception of "sleep" or its equivalent, the machine never stops. It executes new code on every clock tick, or maybe parts of new code. It is always, with the fore-mentioned sleep exception, grinding away at the code in its memory.

 

Jim

 

avr-mike wrote:

raivata wrote:

while ((TIFR&0x01)==0); //wait for TF0 to roll over

 

Probably what's confusing is the lack of a block after the while

statement.  The semicolon after the test is the block.  An empty

one that does nothing.

 

--Mike

 

 

Hello guys sorry haven`t been around in a while, need to take care of an urgent matter.
To all of you people, I would say really thank you! 

Yeah, the thing is I learnt C programming but I've never seen a while statement which immediately followed by a semi-colon (without the braces {} ) as I posted. 

 

I learnt something today, thanks guys!, case closed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

raivata wrote:
void T0Delay() //delay function { TCNT0 = 0x20; //load TCNT0 TCCR0 = 0x01; //Timer0, Normal mode, no prescaler used <== This is where my confusion rises while ((TIFR&0x01)==0); //wait for TF0 to roll over TCCR0 = 0; TIFR = 0x01; //clear TFO }   Here is my logic : 1. 'Roll over' means the timer will go from $FF to $00 causing the Timer Overflow Flag(TOV0) sets to '1' 2. When the TOV0 is set, we want to turn off the timer(TCCR0 = 0), and clear the TOV0 Flag (TIFR = 0x01), these are done so that delay function can be used afterward. 3. What I don't get is why we write "while ((TIFR&0x01)==0)." Doesn't it mean "check if TOV0 = 0" ? Shouldn't we check it when TOV0 = 1 (when overflow happens) ? Thanks :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

raivata wrote:
while ((TIFR&0x01)==0); //wait for TF0 to roll over

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

raivata wrote:
raivata wrote: while ((TIFR&0x01)==0); //wait for TF0 to roll over   Probably what's confusing is the lack of a block after the while statement.  The semicolon after the test is the block.  An empty one that does nothing.   --Mike

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@ffw_admin_user,

 

Are you having some issues with operating this messaging system? You have made 3 very "odd" posts there. Can I suggest that if you just want to learn how this message board works you make some kind of "test" thread of your own in the Off Topic forum and practice there rather than "spamming" a real thread?

 

Moderator.