We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hello,
I am having two problems which I think are pretty much related to each other:
Problem 1: passing parameters to function called from ISR
I am invoking a function from ISR. To this function, I pass a variable (unsigned char). When the function is invoked, the value received in the function is zero! If the same function is called from main (), then the value received = the value passed. What am I missing ? How to rectify this problem, besides use of global variables to pass the data (this work around I am already using).
Problem 2: function called from ISR does not behave as intended
There is a delay function that I invoke from the ISR (void delay_6ms()). I have simulated the code on KEIL, which shows that the delay introduced by this function should be to the tune of 6 msec. When I invoke it from ISR, the delay is about 320 usec, however, when I invoke it from main (), the delay is about 4 msec. Why the difference ? Why main() does not give 6 msec delay ?
If I declare the variable inside the function as static (i and j), the delay in ISR changes to 1.4 msec. I tried to declare the function reentrant to see the effect, but there was no change.
--------------------------------------------------- void delay_ms() { unsigned char xdata i; unsigned char xdata j;
i = 0;
while(i++ < 25) { j++; }
i = 0; }
void delay_6ms () { delay_ms(); delay_ms(); delay_ms(); delay_ms(); delay_ms(); delay_ms(); } ---------------------------------------------------
This function should give 1 msec delay, and if called multiple times, then should give a delay in proximity to the number of times it is called.
Regards Aman
The ISR is a "sag" ISR, which means that the system is going down.
Ah, ok. That is a good example for an exception to the rule.
The ISR is using "using 1", but the function is not using any "using X". Should not the compiler handle this; switch the register bank before invoking the function and pass variables in the appropriate register bank ?
No, it does not and should not handle this (because doing so would mean that it switches banks at every function call, which adds unnecessary overhead). Register bank switches are taken care of by the called function, not by the calling function.
A simple solution would be adding a "using X" to the function that is called. Another solution would be having two copies of the same function, one for each register bank (assuming that you're not running out of program space). Refer to the chapter "Register banks" in the compiler manual to find out under which circumstances the compiler will generate a register bank switch.
Lets say that the compiler version, optimisation, bla bla are kept constant. Then why the difference ?
In that case, I would assume it's the register bank mixup. Solve this issue first and check if the behavior changes.
What do you suggest now ?
Write the delay function in assembly. Then you can count exactly how many processor cycles it will use, giving you an exact delay.