I'm working with a Freescale MC9S12DG256B with MW CodeWarrior IDE in C. I am using a global float in a RTI to accumulate a value, but I keeps displaying 7271460400000000.... as the result of the calculation. Code snippet: top of file: //they are initialized to zero. float currentMCF; In RTI_ISR: // update minutes if(sec_ctr == 60){ sec_ctr = 0; mins_ctr = mins_ctr+1; currentMCF = (currentMCF + SCFM/1000.0); } currentMCF is displayed on an LCD and alway comes back as garbage. SCFM is another global float that is being updated from a different function in the same file. Any thoughts???
Using global float not working.
Started by ●March 13, 2009
Reply by ●March 13, 20092009-03-13
> I'm working with a Freescale MC9S12DG256B with MW CodeWarrior IDE in C. I > am using a global float in a RTI to accumulate a value, but I keeps > displaying 7271460400000000.... as the result of the calculation. > > Code snippet: > > top of file: > //they are initialized to zero. > float currentMCF; > > > In RTI_ISR: > // update minutes > if(sec_ctr == 60){ > sec_ctr = 0; > mins_ctr = mins_ctr+1; > currentMCF = (currentMCF + SCFM/1000.0); > } > > > currentMCF is displayed on an LCD and alway comes back as garbage. SCFM is > another global float that is being updated from a different function in > the > same file.You're only showing half of the problem, the input part. What's the output part look like (as in sprintf)? Otherwise, maybe sec_ctr never evaluates to 60. How is SCFM declared? If you're using the C formatting library, do you have the right floating point support enabled? Do yourself a favor and declare currentMCF as volatile. Same for other non-local ISR variables. JJS
Reply by ●March 13, 20092009-03-13
eeboarder wrote:> float currentMCF;Well, for starters this is missing a "volatile" qualifier. And this being a float on a CPU which, I guess, doesn't support those in hardware, would complicate matters further. Just how certain are you that your compiler's runtime library support functions for implementing 'float' are reentrant? In a nutshell: don't do that.
Reply by ●March 13, 20092009-03-13
>> I'm working with a Freescale MC9S12DG256B with MW CodeWarrior IDE in C.I>> am using a global float in a RTI to accumulate a value, but I keeps >> displaying 7271460400000000.... as the result of the calculation. >> >> Code snippet: >> >> top of file: >> //they are initialized to zero. >> float currentMCF; >> >> >> In RTI_ISR: >> // update minutes >> if(sec_ctr == 60){ >> sec_ctr = 0; >> mins_ctr = mins_ctr+1; >> currentMCF = (currentMCF + SCFM/1000.0); >> } >> >> >> currentMCF is displayed on an LCD and alway comes back as garbage. SCFMis>> another global float that is being updated from a different functionin>> the >> same file. > >You're only showing half of the problem, the input part. What's the >output >part look like (as in sprintf)? > >Otherwise, maybe sec_ctr never evaluates to 60. How is SCFM >declared? If >you're using the C formatting library, do you have the right floating >point >support enabled? > >Do yourself a favor and declare currentMCF as volatile. Same for >other >non-local ISR variables. > >JJS >I'm using floats just fine in other locations of the code. I put in the 'volatile' just now. Still not working. SCFM is a global float. It is initialized to 0 in an initialize function, then calculated as follows: SCFM=128.8*K*Di*Di*sqrt((ambPressure*diffPressure)/((ambTemperature+460.0)*Ss)); ambPressure and diffPressure are both floats calculated by other equations through my ADC. Output: // displaying yesterday MCF sprintf(ATDstring6,"%f MCF yesterday ",currentMCF); writeLine(ATDstring6,1); All other global variables in RTI_ISR are working fine. I have them outputing as a clock, and it is counting appropriately.
Reply by ●March 13, 20092009-03-13
Here is my file. I'll spare you the huge lookup table. Please excuse the sloppiness for now. It's a first run. :) #include <mc9s12dp256.h> // derivative information #include "pll.h" #include "adc.h" // ADC_Init, ADC_Read #include "lcd.h" // LCD Display #include "flow.h" // flow calculation fuction #include "stdio.h" // common functions #include "math.h" // math functions unsigned int ms_ctr; unsigned int sec_ctr; unsigned int mins_ctr; unsigned int hrs_ctr; unsigned int days_ctr; float Temp[446]; volatile float currentMCF; volatile float yesterdayMCF; float SCFM; void flowCalc() { float ambPressure; float diffPressure; float ambTemperature; unsigned int Conv1; unsigned int Conv2; unsigned int Conv3; char ATDstring1[16]; char ATDstring2[16]; char ATDstring3[16]; char ATDstring4[16]; char ATDstring5[16]; char ATDstring6[16]; for(;;) { // reading ATD channel 13(Temperature) Conv1 = ADC_Read(0x85); ambTemperature = Temp[Conv1]; //sprintf(ATDstring1,"%f deg F ",ambTemperature); //writeLine(ATDstring1,1); // reading ATD channel 14(Ambient Pressure) Conv2 = ADC_Read(0x86); ambPressure = (float)(((Conv2-205.0)/819.0)*50.0); //sprintf(ATDstring2,"%f PSIA ",ambPressure); //writeLine(ATDstring2,0); // reading ATD channel 15(Differential Pressure) Conv3 = ADC_Read(0x87); diffPressure = (float)(((Conv3-205.0)/819.0)*138.40); //sprintf(ATDstring3,"%f in H2O ",diffPressure); //writeLine(ATDstring3,1); // calculating flow in SCFM SCFM=128.8*K*Di*Di*sqrt((ambPressure*diffPressure)/((ambTemperature+460.0)*Ss)); sprintf(ATDstring4,"%f SCFM ",SCFM); writeLine(ATDstring4,0); // displaying time // sprintf(ATDstring5,"%id%ih%im%is ",days_ctr,hrs_ctr,mins_ctr,sec_ctr); // writeLine(ATDstring5,1); // displaying yesterday MCF sprintf(ATDstring6,"%f MCF yesterday ",currentMCF); writeLine(ATDstring6,1); } } __interrupt void RTI_ISR() { // clearing flag CRGFLG = 0x80; // update milliseconds ms_ctr = ms_ctr+1; // update seconds if(ms_ctr == 25) { ms_ctr = 0; sec_ctr = sec_ctr+1; } // update minutes if(sec_ctr == 60){ sec_ctr = 0; mins_ctr = mins_ctr+1; currentMCF = (currentMCF + SCFM); } // fudge correction if(mins_ctr == 30){ sec_ctr = sec_ctr+42; } // updates hours if(mins_ctr == 60){ // fudge correction sec_ctr = sec_ctr+42; mins_ctr = 0; hrs_ctr = hrs_ctr+1; } // updates days if(hrs_ctr == 24) { hrs_ctr = 0; days_ctr = days_ctr+1; yesterdayMCF = currentMCF; currentMCF = 0.00; } } void RTI_Init() { SCFM = 0.00; ms_ctr = 0; sec_ctr = 0; mins_ctr = 0; hrs_ctr = 0; days_ctr = 0; currentMCF = 0.00; yesterdayMCF = 0.00; // Enable interrupts asm cli // RTIE On CRGINT = 0x80; // RTI Freq Divide Rate 11x2^16 // Interrupts every 90.112 ms RTICTL = 0x74; } void temperatureInit() { Temp[0]=-60.0000000000000; Temp[1]=-53.1734380020266; Temp[2]=-46.2560695623409;
Reply by ●March 13, 20092009-03-13
Hans-Bernhard Br�ker wrote:> eeboarder wrote: > >> float currentMCF; > > Well, for starters this is missing a "volatile" qualifier. And this > being a float on a CPU which, I guess, doesn't support those in"volatile" is far from enough - in fact, it probably will not affect the code at all. The important thing is to make sure that accesses outside the interrupt routine are atomic. However, a better solution is to use a single byte flag variable (which should be volatile) and do the calculation outside the ISR.> hardware, would complicate matters further. Just how certain are you > that your compiler's runtime library support functions for implementing > 'float' are reentrant? >This is important - on small micros, library functions used for floating point are often not re-entrant.> In a nutshell: don't do that.At least, don't do it in the interrupt routine. Have the interrupt routine set a flag, and do the calculations in the main code when the flag is set.
Reply by ●March 14, 20092009-03-14
eeboarder wrote:> Here is my file. I'll spare you the huge lookup table. Please excuse the > sloppiness for now. It's a first run. :)Well, let's see. All of these:> unsigned int ms_ctr; > unsigned int sec_ctr; > unsigned int mins_ctr; > unsigned int hrs_ctr; > unsigned int days_ctr;have to be either made volatile, or removed from file scope. As-is, there's no way of knowing what'll happen if any routine other than your RTI ISR accesses them.> float SCFM;This has to be made volatile, too.> void flowCalc() {What calls this routine? And, perhaps more importantly, who will pat the puppy while it sits in an endless loop?> __interrupt void RTI_ISR() {[...]> // update seconds > if(ms_ctr == 25) { > ms_ctr = 0; > sec_ctr = sec_ctr+1; > }So your variable ms_ctr is ill-named. It doesn't count ms.> // fudge correction > if(mins_ctr == 30){ > sec_ctr = sec_ctr+42; > }This completely misfires. You're applying your fudge term 2400 times in that minute. Not even to mention that your (secs_ctr == 60) condition will fail miserably with the above kind of fudging in place.> // Interrupts every 90.112 msThat doesn't seem to match the way you count interrupts into seconds.
Reply by ●March 14, 20092009-03-14
eeboarder wrote:> Here is my file. I'll spare you the huge lookup table. Please excuse the > sloppiness for now. It's a first run. :)Well, let's see. All of these:> unsigned int ms_ctr; > unsigned int sec_ctr; > unsigned int mins_ctr; > unsigned int hrs_ctr; > unsigned int days_ctr;have to be either made volatile, or removed from file scope. As-is, there's no way of knowing what'll happen if any routine other than your RTI ISR accesses them.> float SCFM;This has to be made volatile, too.> void flowCalc() {What calls this routine? And, perhaps more importantly, who will pat the puppy while it sits in an endless loop?> __interrupt void RTI_ISR() {[...]> // update seconds > if(ms_ctr == 25) { > ms_ctr = 0; > sec_ctr = sec_ctr+1; > }So your variable ms_ctr is ill-named. It doesn't count ms.> // fudge correction > if(mins_ctr == 30){ > sec_ctr = sec_ctr+42; > }This completely misfires. You're applying your fudge term 1500 times in that minute. Not even to mention that your (secs_ctr == 60) condition will fail miserably with the above kind of fudging in place.> // Interrupts every 90.112 msThat doesn't seem to match the way you count interrupts into seconds.
Reply by ●March 15, 20092009-03-15
On Sat, 14 Mar 2009 01:16:48 +0100, David Brown <david.brown@hesbynett.removethisbit.no> wrote:>Hans-Bernhard Br�ker wrote: >> eeboarder wrote: >> >>> float currentMCF; >> >> Well, for starters this is missing a "volatile" qualifier. And this >> being a float on a CPU which, I guess, doesn't support those in > >"volatile" is far from enough - in fact, it probably will not affect the >code at all. The important thing is to make sure that accesses outside >the interrupt routine are atomic. > >However, a better solution is to use a single byte flag variable (which >should be volatile) and do the calculation outside the ISR. > >> hardware, would complicate matters further. Just how certain are you >> that your compiler's runtime library support functions for implementing >> 'float' are reentrant? >> > >This is important - on small micros, library functions used for floating >point are often not re-entrant.There are forums you can ask about this at http://freescale.com (the appropriate Codewarrior compiler forum would be the appropriate forum...), and there are people there who KNOW whether the FP package is re-entrant or not.> >> In a nutshell: don't do that. > >At least, don't do it in the interrupt routine. Have the interrupt >routine set a flag, and do the calculations in the main code when the >flag is set.
Reply by ●March 16, 20092009-03-16