Jump to content
Sign in to follow this  
mikew

Interrupts On Pic16f876

Recommended Posts

Thanks to those who offered help, and the problem is now solved - but I'm not sure the result indicates a bug.

 

After many re-compilations of much the same code, I noticed once a warning was flagged that a redundant IF statement had been optimised out. This, of course, was in the ISR, and this is where all the code within the IF statement had gone!!

 

The IF statement was intended to detect a Timer1 interrupt, and I guess the compiler/linker detects that only timer1 interrupts were enabled. It does seem a bit drastic to remove the code with optimization, though!

Share this post


Link to post
Share on other sites

Mike,

 

The IF statement was intended to detect a Timer1 interrupt, and I guess the compiler/linker detects that only timer1 interrupts were enabled. It does seem a bit drastic to remove the code with optimization, though!

The compiler is not quite that clever ;)

I guess there was something wrong with your if expression that meant it would always be false, that would cause the compiler to optimise it away.

Please post the code fragment that caused the fault so we can check it.

 

Regards

Dave

Share this post


Link to post
Share on other sites

Below is the ISR, with the unwanted 'IF' commented out.

Now I look at it again, I think I see the problem, the declaration of TMR1F.

This code has been ported from HI-Tech C; I thought I'd changed all these labels.

Perhaps it should be:

 

if (pir1,TMR1IF) etc....

 

And I suppose that TMR1F is not flagged as undeclared since it's in one of the included header files.

 

My apologies, but my excuse is that I'm a hardware man, not a programmer!!

 

 

/**************************** ISR **********************/

void interrupt(void)

{

unsigned char ticks; //temp store for Timer1 ticks

/**** Timer1 OverFlow Interrupt ****/

// if(TMR1IF)

// {

tmr1h=0x38; // Reset Timer1 reg., adjusted for slow clock?

tmr1l=0;

++ticks;

if (ticks==2) /* timer ticks for 1 second */

{

ticks=0;

++seconds;

}

if (seconds==60)

{

seconds=0;

++minutes;

}

if (minutes==60)

{

minutes=0;

++hours;

}

if (hours==24)

{

hours=0;

}

clear_bit(pir1,TMR1IF); /* Clear the Timer Flag */

// }

}

Share this post


Link to post
Share on other sites

Your statement "if (pir1,TMR1IF)" looks like it provokes a compiler bug. This should cause a compile error.

 

Other forms like "c=(pir1,TMR1IF)" do cause a compiler error.

 

Dave, is this a bug?

Share this post


Link to post
Share on other sites

cac001,

Your statement "if (pir1,TMR1IF)" looks like it provokes a compiler bug. This should cause a compile error.

 

Other forms like "c=(pir1,TMR1IF)" do cause a compiler error.

 

Dave, is this a bug?

No, its neither a bug or a "feature". This format of code "if (pir1,TMR1IF)" is accepted by other compilers (eg MSVC).

 

Regards

Dave

Share this post


Link to post
Share on other sites

mikew,

 

    if(TMR1IF)

Will get optimised away because TMR1F is define as a constant, so the equivalent code is:

    if( 0x0000 )

Check out the definition of TMR1IF.

 

Your code would work if you used:

if( pir1.TMR1IF )

 

Regards

Dave

Share this post


Link to post
Share on other sites

More questions on this interrupt;

 

if(pir1,TMR1IF) etc

 

does not cause any error to be flagged, but I am unclear of the difference between this and

 

if(pir1.TMR1IF) i.e. the use of dot rather than comma...

 

Also, I have used (elsewhere) for example-

 

if (test_bit(pir1,TMR1IF)) etc...

 

which seems OK, but now I'm not sure! I'm starting to look at the code produced for such 'errors' but I may well be looking at the wrong stuff, that is not where the mistakes really are.

 

mikew.

Share this post


Link to post
Share on other sites

Dave,

 

MSCV 6.0 accepts both "if (pir1,TMR1IF)" and "c=(pir1,TMR1IF);" statments.

 

MSVC.NET reports errors for both "if (pir1,TMR1IF)" and "c=(pir1,TMR1IF);" statments.

 

BoostC reports "c=(pir1,TMR1IF);" as a compile error.

 

Is it correct for a compiler to accept the "if" syntax and reject the assignment syntax?

 

Thanks,

Cac.

Share this post


Link to post
Share on other sites

Cac,

Is it correct for a compiler to accept the "if" syntax and reject the assignment syntax?

I would say not, both should really be accepted.

Now we are in the realms of obscure coding style, which I think 99% of people won't understand what the codes meant to do (including me) :)

 

Don't expect the assignment case to be fixed very soon.

 

Regards

Dave

Share this post


Link to post
Share on other sites
More questions on this interrupt;

 

    if(pir1,TMR1IF)  etc

 

does not cause any error to be flagged, but I am unclear of the difference between this and

 

   if(pir1.TMR1IF)      i.e. the use of dot rather than comma...

 

Also, I have used (elsewhere) for example-

 

   if (test_bit(pir1,TMR1IF))  etc...

 

which seems OK, but now I'm not sure!  I'm starting to look at the code produced for such 'errors' but I may well be looking at the wrong stuff, that is not where the mistakes really are.

 

mikew.

 

Mikew,

 

What you are perplexed by is one of the many cases of C language syntax looking similar but doing very different things.

 

BoostC has a syntax extension that allows access to the individual bits of a byte. This has the form of "<variable name><PERIOD><constant in the range of 0-31>", for example "pir1.0" or "pir1.TMRIF". This kind of extension is common to many C compilers targeted to support microcontroller that have opcodes for direct bit manipulation.

 

The statement "test_bit(pir1,TMR1IF)" is standard syntax for a function call or preprocessor macro.

 

The statement "(pir1,TMR1IF)" is what I call a sequential expression. This syntax is used to let the compiler know that you need these expressions evaluated in a specific order and to keep the optimizer from "helping" too much.

 

So you may be asking: If "(pir1,TMR1IF)" is an expression what value does it return? The answer is the value of the last expression as evaluated from left to right. In this case the value TMR1IF or literally zero.

 

This is why in your example "if(pir1,TMR1IF)" is always false, because TMR1IF is literally defined as zero.

 

What's confusing is that these things all look similar:

 

1 - A target specific language extension.

2 - Common syntax for parameter lists.

3 - Seldom used standard language feature for sequential expressions.

 

Hope this helps.

Edited by cac001

Share this post


Link to post
Share on other sites
...So you may be asking: If "(pir1,TMR1IF)" is an expression what value does it return? The answer is the value of the last expression as evaluated from left to right. In the case the value TMR1IF or literally zero.

 

This is why in your example "if(pir1,TMR1IF)" is always false, because TMR1IF is literally defined as zero...

 

I was about to reply but the above post answers brilliantly the original question. Because TMR1IF is a constant expression 'if(pir1,TMR1IF)' is same as 'if(0)' and it gets optimizad out by the compiler.

 

Regards,

Pavel

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...