Reply by Steve at fivetrees March 18, 20092009-03-18
"eeboarder" <jmeyer@emittechnologies.com> wrote in message 
news:jKudnQS7NKjg_yPUnZ2dnUVZ_r-WnZ2d@giganews.com...
>I set flags and did the calcualtion elsewhere. Everything is working as it > should!
Everyone learns this lesson ("set flags in the ISR and do the real stuff elsewhere") eventually ;). Welcome! Best, Steve -- http://www.fivetrees.com
Reply by eeboarder March 16, 20092009-03-16
I set flags and did the calcualtion elsewhere. Everything is working as it
should! 

Thank you.
Reply by Ben Bradley 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&#4294967295;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 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 ms
That 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 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 ms
That doesn't seem to match the way you count interrupts into seconds.
Reply by David Brown March 13, 20092009-03-13
Hans-Bernhard Br&#4294967295;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 eeboarder 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 eeboarder 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 >
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
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. 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