View previous topic :: View next topic |
Author |
Message |
wewa
Joined: 02 Jul 2008 Posts: 27
|
Function blocks interrupt |
Posted: Fri Jul 11, 2008 12:55 am |
|
|
Hi, I've got problem with a programm which looks like this: Code: | #include <18F4525.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=PC)
int1 function() {
int32 cnt;
while(1) {
}
if(cnt<1000) { return TRUE;}
else {return FALSE;}
} //END function
#INT_RDA
void seriell() {
char c;
c=getc(PC);
output_high(pin_b4);
} //END seriell
void main() {
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //für seriellen Empfang
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
ENABLE_INTERRUPTS(INT_RDA); //serieller Empfang
ENABLE_INTERRUPTS(Global);
function(); /*This seems to block the serial Interrupt, if I don't call this function serial Interrupt fires.*/
while (1) {
} //END while
} //END main | The problem is, if I call a function where a while()-loop is in it, the Interrupt doesn't fire. But if I don't call the function everything works fine.
Why does such a function block the Interrupt?
Last edited by wewa on Fri Jul 11, 2008 2:23 am; edited 1 time in total |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Fri Jul 11, 2008 1:25 am |
|
|
I've now found out, that the declaration of variables (eg. cnt) in the function blocks the Interrupt. If I don't declare a variable in the function the Interrupt works fine.
But why? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 11, 2008 1:49 am |
|
|
You need to clear the rda interrupt by calling fgetc(PC) inside the
#int_rda routine. |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Fri Jul 11, 2008 1:53 am |
|
|
I've also tried this, but it has no effect. |
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 11, 2008 2:11 am |
|
|
You do need to get the character, or the RDA interrupt will be continuously called.
However your function, is completely screwy!.....
Code: |
int1 function() {
int32 cnt; //This will contain a random(ish) value...
while(1) { //'1' is permanently 'true'
} //This marks the _end_ of the while loop.
//You can never get here
if(cnt<1000) { return TRUE;}
else {return FALSE;}
} //END function
|
As it stands, you can never reach the second 'half' of this function. 'while (1)', is permanently true
Also, 'cnt', is a temporary local variable, and is never initialised or changed. It's contents will be garbage, depending on what else is being done by the processor before you reach this routine. The 'return' value (which will never occur anyway), will be random....
Best Wishes |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jul 11, 2008 2:12 am |
|
|
Put it into the #int_rda routine anyway. It needs to be there.
Then look closely at your other function. It's got an infinite loop in it.
It can't return. Remove that loop. |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Fri Jul 11, 2008 2:22 am |
|
|
I know that the function is nonsense, but the interrupt has to fire regardless if there is a while(1)-Loop in the function or not. (You also make suche loops in the void main()-Function and it's no problem.)
Again - The problem is the variable declaration in the function:
If the function looks like this: Code: | int1 function () {
while(1) {
}
} | The Interrupt fires. But if I declare a variable in this function e.g. Code: | int1 function () {
int1 var;
while(1) {
}
} | the interrupt doesn't fire.
Why does this declaration of a variable block the interrupt (without it interrupt works fine)?
PS: There's a getc() in #INT_RDA but I've not posted it (until yet). |
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 11, 2008 3:15 am |
|
|
First, post your compiler version. Though I have never seen anything like this, some of the early 4.00x compilers have some screwy bugs.
Second, post a program that actually proves the point. Compilable, and workable, with the fault. At the moment, you are saying that the real 'test' code differs from what you post, and this doesn't make it possible for use to help at all.
As an example, this runs fine:
Code: |
#include <18F4525.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_C6, rcv=PIN_C7, ERRORS, stream=PC)
#include <stdlib.h>
#define RAND_MAX (6000)
char c;
int1 function() {
static int32 cnt=0;
while(1) {
cnt=rand();
if(cnt<1000) { return TRUE;}
else {return FALSE;}
}
} //END function
#INT_RDA
void seriell() {
c=getc(PC);
output_high(pin_b4);
} //END seriell
void main() {
int1 dummy;
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //für seriellen Empfang
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
ENABLE_INTERRUPTS(INT_RDA); //serieller Empfang
ENABLE_INTERRUPTS(Global);
dummy=function();
while (1) {
} //END while
} //END main
|
Using both 3.249, and 4.070
Best Wishes |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Fri Jul 11, 2008 10:27 am |
|
|
sorry, the problem was somewhere else
In #INT_TIMER3 a function was called which waited on a action to be taken in #INT_RDA. And I think this was too much for the PIC.
But thanks for your help.
Problem solved. |
|
|
|