Fast thinking for left aligned incoming pulses…using my old code (for another MCU) for frequency measurement adding additional code. Timer channel 1 is set for both edges interrupt and main timer is set for overflows. The code is just presenting approach. Probably it is correct, I am sorry topically can't see mistake....it requires some time for thinking....I know.....
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^|___________|^^^^^^^^^^^^^^^^^ incomming signal
Irising edge |falling edge |rising edge
|<---------period or duty or Globalperiod_1--------------->|<----period--->|<----period-----
|<-----------------------------------------Globalperiod----------->|<---------------------Globalperiod-----
// Count overflows
//*********************************
#pragma CODE_SEG NON_BANKED
interrupt XX void ECT_OvfIsr(void) // count overflows
{
ch1ovfCnt++; // count overflows
if(ch1ovfCnt>MAX_OVERFLOWS)
{
ch1ovfCnt = 0;
FREQUENCY_TOO_LOW = TRUE;
SCI0_SendValue(); // send message to the PC
}
else
{ FREQUENCY_TOO_LOW = FALSE;
}
ECT_TFLG2 = 0B10000000; // clear interrupt flag of main timer
}
#pragma CODE_SEG DEFAULT
//*********************************
//Service interrupt for rising and falling edge
// calculate topical length of the finished level and length/globalperiod of invcoming signal:
//*********************************
#pragma CODE_SEG NON_BANKED
interrupt XX void ECT_Ch1Isr(void)
{
unsigned int ovfs;
//------
timerNewValue = ECT_TC1; // read new captured value and clear flag
ovfs = ch1ovfCnt; // save amount of ovfs to temporary variable
ch1ovfCnt = 0; // clear number of overflows
ECT_TFLG1 = 0B00000010; // clear interrupt flag from PT1
//----- Ch1 period calculation, calculate lengt of currently finished level of incoming signal ---------
if(!ovfs) // Did edges appear within one timer period?
{
period = (ULONG)(timerNewValue - timerOldValue); // per. of given level
}
else // some number of overflows has appeared between two edges
{
// time given by overflows period=....
period = (ULONG)( ~timerOldValue+1 ); // time in the first period
period+= (ULONG)( timerNewValue); // time in the last period
period+= (ULONG)((ULONG)((ovfs-1)) * (ULONG)(65536));
}
timerOldValue = timerNewValue; // prepare new old value
//------------- calculate period and duty of incomming signal
if(rising edge)
{
Globalperiod = Globalperiod_1 + period; // period of incoming signal
Data_prepared = TRUE;
// now you have entire period and duty cycle of the Globalperiod which
// has now gone. This value you can use for PWM
}
else
{
Globalperiod_1 = period; // also it is duty of a new Globalperiod
}
}
#pragma CODE_SEG DEFAULT
Note; if you set prescaler of main timer to be sure there is only one overflow between rising and falling edge then formulas and code could be simplified. This is general approach for pulse of long length with maximum lengt of MAX_OVERFLOWS.
Best regards,
Ladislav