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
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...
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.