Measurement Glitches for Minimum measurements

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Measurement Glitches for Minimum measurements

602 Views
admin
Specialist II

Hello there,

 

I am using Softec's SK-S12XDP512A EVB for my programming in Codewarrior.  

There is this problem of glitch in the real-time values for the wheelspeed and engine rpm measurement.

I have

  • enabled ECT for 2 input capture channels on rising edges,; prescalr factor=2
  • Timer channel period is 0.1 microseconds(PLL CLK = 20 MHz)
  • Timer overflow is 6.5536ms

channel one has been set for the wheel_speed calculation and channel two for Rpm calculation

The overflow ISR has a time out count for minimum wheel_s[peed and Rpm. The signal input is fed from a function generator .I have compiled and ran the code but there is a glitch in the values of RPM and Wheel_speed for their respective minimum measurements.. This peice of code is shown below...

 

//in main function//

   

  Gear_Ratio = (inputs.N*10)/inputs.D;
   Circum     = (3141*(long)inputs.dia)/1000;
   ECT_COUNT1 = (Circum*3600*Gear_Ratio)/(inputs.min_whlspd*inputs.Whlspd_ppr*65535);
   ECT_COUNT2 = (10000000*60)/(inputs.min_rpm*inputs.E_ppr*65536); 
 

 

  WRPM       = (frequency1*Gear_Ratio*6)/inputs.Whlspd_ppr; 
   Whl_Spd    = (WRPM*Circum*6)/10000;
   ERPM       = (frequency2*60)/inputs.E_ppr;

 

#pragma CODE_SEG __NEAR_SEG NON_BANKED
  interrupt 9 void ISR_TIMCH1(void)
  {
  if((TFLG2_TOF)&&(TC1<TCNT))              /*checks Timer overflow ISR pending */
   {
   count1++;
   Corr1=1;
   }
    else
    {
   Corr1=0;
    }
  
   new_count1 = TC1;
   over_flow1 = count1;
   period1    = (new_count1+((long)over_flow1*0xFFFF)-old_count1);
   old_count1 = new_count1;
   count1     = 0;
   frequency1 = 1000000000/period1;
   TFLG1      = 0x02;
 
   }
  #pragma CODE_SEG DEFAULT

//////////////////////////////
 Timer Channel 2 ISR  

//////////////////////////////
 
  #pragma CODE_SEG __NEAR_SEG NON_BANKED
  interrupt 10 void ISR_TIMCH2(void)
  {
 if((TFLG2_TOF)&&(TC2<TCNT))
   {
    count2++;
    Corr2=1;
   }
   else
   {
   Corr2=0;
   }
   new_count2 = TC2;
   over_flow2 = count2;
   period2    = (new_count2+((long)over_flow2*0xFFFF)-old_count2);
   old_count2 = new_count2;
   count2     = 0;
   frequency2 = 100000000/period2;
   TFLG1      = 0x04;
  
  }
  #pragma CODE_SEG DEFAULT

 

/////////////////////////////////  
Timer Overflow ISR     

////////////////////////////////
 
  #pragma CODE_SEG __NEAR_SEG NON_BANKED
  interrupt 16 void ISR_TIMOVF(void)
  {
   
   TFLG2_TOF = 1;
   count1+=1-Corr1;
   Corr1 =0;
   if(count1>ECT_COUNT1)   
   {      
     count1=0;
     frequency1=0;
   }
   
   count2+= 1-Corr2;
   Corr2 =0;
   if(count2>ECT_COUNT2)
   {
    count2=0;
    frequency2=0;
    ERPM      =0;
   }
  }
  
  #pragma CODE_SEG DEFAULT

 

would appreciate for a solution... 

Labels (1)
Tags (1)
0 Kudos
1 Reply

287 Views
Lundin
Senior Contributor IV

There are several, possibly fatal implicit cast issues in that program. Possibly also some nasty problems because of missing volatile. If you want a better reply, please post the variable declarations.

 

Also, why would you multiply with 65535 in one case and 65536 in another case? That does look like an obvious bug.

Hint: use the constant UINT_MAX in limits.h instead.

 

Also, if min_whlspd and Whlspd_ppr are 16 bit, the left side of this expression will probably overflow:

 

(inputs.min_whlspd*inputs.Whlspd_ppr*65535)

 

Order of evaluation could be left-to-right for multiplication, this is implementation-defined behavior and you cannot trust the compiler to do it in one particular way. It may evaluate the expression as:

 

(inputs.min_whlspd*inputs.Whlspd_ppr) * 65535

or

inputs.min_whlspd* (inputs.Whlspd_ppr * 65535)

 

Both are perfectly valid standard C.  In case of the former, the program might overflow. In the latter, implicit integer promotion will take place since 65535 is a 32-bit constant.

 

 

0 Kudos