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 everyone,
I am currently having an issue with some code I have that seems to vary based on optimization:
In CommBuff ISR:
if (commData == 0x61) /* 0x61 = 'a' */ { if(DAC1DifVoltn==1) { DigPressure1 = DiffPressure1; // Enters this section, problem here } else { DigPressure1 = Pressure1>>3; } COMBUF = DigPressure1>>8; } else if (commData == 0x62) /* 0x62 = 'b' */ { COMBUF = DigPressure1; }
Currently, DAC1DifVoltn is set to 1. When the COMBUF register gets a 0x61, it updates DigPressure1 and puts out the MSB on the COMBUF. When it receives 0x62, it sends out the LSB bits.
The problem I'm having is with the line:
DigPressure1 = DiffPressure1;
DiffPressure1 is set to 0x0FF8. When optimization is set to 4-8, DigPressure1 is set to 0x0097. When it's set to 3, it gets 0x0F97. When it's set to 2-0, it gets the correct value (0x0FF8). Realistically, this has to do with the way my code is written rather than it being an assembly issue but I can't seem to see a better way to handle this.
Does anyone have any explanations as to what I can do? If you need me to post the assembly code, I can do that as well. Any help would be appreciated. Thanks!
The question I have is is this something that was done by Keil (since changing that checkbox fixed it) or is this something that was done/could have been avoided by me and if so, how?
A bit of both. But it's mostly your fault, for not paying enough attention to the documentation.
You called a function (the only one you've actually shown here) from another one that assumed a different register bank (your actual __interrrupt function). That is known and documented to cause incorrect program behaviour. So you shouldn't have done that.
Bah, rookie mistake on my end! I posted the code I thought was relevant but probably masked the real problem: calling a function from within an ISR (as Eric alluded to). I moved the function call code to within the ISR and the problem seems to have disappeared with me, even with the disable direct addressing box unchecked. I really should know better than to do this!
Thanks for the insight and links, everyone! I learned a lot from this (like I need to BE MORE CAREFUL). I appreciate the patience and explanations.
rookie mistake on my end two comments: 1) you alluded in a previous post that you might have atomicity problems, carefully make sure you do not a) 2) avoid calling subroutines from an ISR b)
a) to obtain a variable longer than 8 bits used in an ISR from main
EAsave =EA; EA = 0; local variable = shared variable; EA= EAsave;
b)calling a subroutine from an ISR is wrong for 3 reasons: 1) it makes the ISR slower; 2) if you need to for clarity purposes, your ISr is already too complex to adhere to KISS and 3) not having a subroutine makes the mistake of calling a subroutine from main and ISr impossible.
Erik