Hello,
I have a couple of questions about frequency measurement in Kinetis MCUs (K22).
First of all, I would like to measure some fast signal (a clock) with a frequency of 1/10th of core clock( let's say 48MHz of core clock, 5 mhz max of input frequency). According to the datasheet, my max input frequency shall be core clock /4
Is there a way to calculate what will my accuracy be? Ok, I suppose it will depend from the "architecture" I am going to use to perform measurements. And so, here comes the first "true" question.
What's the best approach to measure a fast signal like this one?
Three possibile approaches:
I already saw a couple of other threads like How can I measure frequency (0 - 100KHz) of a signal using a K10 microcontroller? but I couldn't figure out the "best practice" for this kind of measurement.
Any hint would be gladly appreciated.
Best regards,
Luca.
Hi Iuca,
FTM module support a enhance mode which calls Dual Edge Capture mode and this mode can measure a pulse width or period of the signal on the input of channel of a channel pair efficiently.
I'd like to highly recommend you to apply this method and you can find the detail information about the Dual Edge Capture mode in the RM.
Wish it helps,
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi, Luca,
If the external tested signal clock frequency is very high for example 5MHz in your case, I think you can use the high frequency clock to fill a signal with big period. This is the procedure:
1)From hardware perspective,connect the tested signal to FTM_CLKINx pin, for K22, it is multiplexed with PTA18.
2)From software perspective, set the CLKS as 11 in binary, in the case, the FTM will count the external tested clock.
3)I suggest you use PIT to generate an interrupt, in the ISR of PIT, you can read the FTM_CNT value, because the PIT period is known and fixed, you can figure out the tested signal frequency by the computing difference of two reading of FTM_CNT and dividing it by (PIT period).
4)maybe the above method is inaccurate due to indefinitive pipe line of software. If you want to get more accurate frequency, you can use capture mode of FTM, you can connect another low frequency clock signal to FTM_CHx, whose frequency is known. For example, you can use a 1KHz signal to FTM_CHx pin, in the ISR of capture, you can read the FTM_CnV register to one variable, in the consecutive ISR of capture, you can read the FTM_CnV to another variable, compute the difference of the two variables, it is okay. you can use the Dual Edge Capture mode as JeremyZhou pointed out, in one ISR, you can read FTM_CnV and FTM_Cn+1V and compute the difference.
Hope it can help you.
BR
Xiangjun Rong
thank you very much for both your reply.
I've tried dual edge capture but still not accurate measurements.
Following, there is a snip of the code:
void FTM0_Init(void)
{
/* Start FTM0 configuration*/
/* Set PORT pin mux to CH0 */
SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK;
PORTC_PCR1 = (uint32_t) (PORT_PCR_MUX(4) |PORT_PCR_SRE_MASK);
/* Enable FTM0 Module */
SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK;
/* disable write protection AND Free running counter */
FTM_PDD_WriteProtectionDisable(FTM0_BASE_PTR);
FTM0_CNT = 0x0;
FTM0_MOD = (uint16_t)(0xFFFF);
FTM_PDD_WriteCombineReg(FTM0_BASE_PTR,FTM_COMBINE_DECAPEN0_MASK |FTM_COMBINE_DECAP0_MASK);
FTM_PDD_WriteChannelControlReg(FTM0_BASE_PTR, FTM_PDD_CHANNEL_0,FTM_CnSC_ELSA_MASK); //No IRQ on chn(n)
FTM_PDD_WriteChannelControlReg(FTM0_BASE_PTR, FTM_PDD_CHANNEL_1,FTM_CnSC_CHIE_MASK | FTM_CnSC_ELSA_MASK);// Enable IRQ on ch(n +1)
/* Add IRQ into NVIC*/
NVICIP42 = NVIC_IP_PRI42(0x70);
NVICISER1 |= NVIC_ISER_SETENA(0x400);
NVICICPR1 |= NVIC_ICPR_CLRPEND(42);
}
/* FTM0 IRQ*/
void FTM0_IRQHandler(void) {
if(FTM0_C1SC & FTM_CnSC_CHF_MASK)
{
lDBIsoClocK.Ftm0_CNT_Val[0] = FTM0_C0V;
lDBIsoClocK.Ftm0_CNT_Val[1] = FTM0_C1V;
FTM_PDD_ClearChannelInterruptFlag(FTM0_BASE_PTR, FTM_PDD_CHANNEL_1);
lDBIsoClocK.Done = true;
}
}
int main(void)
{[...]
FTM0_Init();
/* Start FTM0 */
FTM0_SC |= (uint32_t)(FTM_SC_CLKS(1));
while(lDBIsoClocK.Done != true)
{
}
/* Clock computation here*/
}
}
anyway, yet no accurate measurement for fast clock.
As previously said, FTM bus is clocked @48MHz.
Am I missing something?
Best regards,
L.
Hi Luca,
I'm sorry to hear that the Dual Edge Capture mode also doesn't get the measurement accuracy you want.
About the method from Xianggun Rong, I think you should give a shot and I'm also looking forward to the testing result.
Have a great day,
Ping
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi, Luca,
It is the same result whether you use dual edge capture or single edge capture mode, it can not improve the accuracy of measurement.
As I said in last Email, you can connect the 5MHz tested signal to FTM_CLKIN, initialize FTM so that it can count the external clock, when it reach up to FTMx_MOD with 0xFFFF, generate overflow interrupt and reload the FTM_CTNIN value. Initialize the PIT so that PIT can generate 1KHz interrupt, there are 5000 external clock ticks during the PIT interval. If you set 500Hz PIT interrupt, there are 10000 external clock ticks during the interval of PIT, I think it is okay for accuracy of measurement.