Hello
I'm working on a Kinetis k70 with MQX 4.1.1
I'm looking for a way to measure a Frequency of a square wave signal on an Input (General IO or a specific IO if needed)
I see we can do something with LPTMR module, but I don't find the way to use it via MQX or with my own code but without interfering with MQX.
Have you some Idea, or exemple allowing to measure a Frequency on an input?
Thank:smileyhappy:
已解决! 转到解答。
Hi Arno:
I think you can try FTM module, the dual edge capture mode, please read the following document, section 44.4.24
http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K70P256M150SF3RM.pdf?fasp=1
Have a nice day,
Daniel
Hi Arno:
I think you can try FTM module, the dual edge capture mode, please read the following document, section 44.4.24
http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K70P256M150SF3RM.pdf?fasp=1
Have a nice day,
Daniel
Hello
Then I use FTM2 CH0/CH1
I implement the following code, I'm still to test It. I hope I don't forget anything..
But I have a question, Like CH0 and CH1 are combine, Is these Pin are linked internaly or I have to apply my swquare wave signel on both Pin PTF20 and PTF21 (FTM2_CH0 / FTM2_CH1) ?
/* Activate FTM2 Clock */ SIM_SCGC3 |= SIM_SCGC3_FTM2_MASK; /* Set up mode register */ FTM2_MODE = FTM_MODE_WPDIS_MASK | FTM_MODE_FTMEN_MASK; /* Clear status and control register */ FTM2_SC = (uint32_t)0x01UL; /* Clear counter initial register */ FTM2_CNTIN = (uint32_t)0x00UL; /* Reset counter register */ FTM2_CNT = (uint32_t)0x00UL; /* Clear channel status and control register */ FTM2_C0SC = (uint32_t)0x00UL; FTM2_C1SC = (uint32_t)0x00UL; /* FTM1_C1SC: CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=1,DMA=0 */ /* Set up channel status and control register */ /* MSnA = 1: Continus Mode */ /* ElsnB:ElsnA = 0:1 : Rising Edge */ FTM2_C0SC = FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK; FTM2_C1SC = FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK; /* PTF20 and PTF21 -> FTM_CH0, FTM_CH1 */ PORTF_PCR20 = PORT_PCR_MUX(3); PORTF_PCR21 = PORT_PCR_MUX(3); /* Combine CH0 and CH1 */ FTM2_COMBINE = FTM_COMBINE_COMBINE0_MASK | FTM_COMBINE_DECAPEN0_MASK; /* Do separatly, because DACAP bit can be set only when DECAPEN = 1 */ FTM2_COMBINE |= FTM_COMBINE_DECAP0_MASK; /* Set up status and control register */ /* ClkSource = Bus Clock, PREDIV = 32 */ FTM2_SC = (uint32_t)0x0DUL;
Then I get the frequency like that:
Cpt0 = FTM2_C0V; Cpt1 = FTM2_C1V; /* Calcul Delta counter value*/ if (Cpt1 >= Cpt0) { CptCalcul = (uint32_t)(Cpt1 - Cpt0); } else { CptCalcul = (uint32_t)(65536 - Cpt0 - Cpt1); } CptCalcul = (CptCalcul * DV_FMETER_PRDIV); CptCalcul = DV_FMETER_CpuClockSource / CptCalcul;
Then I done the following correction:
-Don't use external PIN PTF20
-Initialisze MOD register to 0xFFFF, else counter stay at 0.
Initialisation part:
/* Find out input frequency*/ DV_FMETER_CpuClockSource = _cm_get_clock(_cm_get_clock_configuration(), CM_CLOCK_SOURCE_BUS); /* Activate FTM2 Clock */ SIM_SCGC3 |= SIM_SCGC3_FTM2_MASK; /* Set up mode register */ FTM2_MODE = FTM_MODE_WPDIS_MASK | FTM_MODE_FTMEN_MASK; /* Clear status and control register */ FTM2_SC = (uint32_t)0x01UL; /* Clear counter initial register */ FTM2_CNTIN = (uint32_t)0x00UL; /* Reset counter register */ FTM2_CNT = (uint32_t)0x00UL; /* Clear channel status and control register */ FTM2_C0SC = (uint32_t)0x00UL; FTM2_C1SC = (uint32_t)0x00UL; /* No need modulo, let counter count in all stage */ FTM2_MOD = 0xFFFF; /* FTM1_C1SC: CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=1,DMA=0 */ /* Set up channel status and control register */ /* MSnA = 1: Continus Mode */ /* ElsnB:ElsnA = 0:1 : Rising Edge */ FTM2_C0SC = FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK; FTM2_C1SC = FTM_CnSC_MSA_MASK | FTM_CnSC_ELSA_MASK; /* PTF20 and PTF21 -> FTM_CH0, FTM_CH1 */ PORTF_PCR20 = PORT_PCR_MUX(3); /* Combine CH0 and CH1 */ FTM2_COMBINE = FTM_COMBINE_COMBINE0_MASK | FTM_COMBINE_DECAPEN0_MASK; /* Do separatly, because DACAP bit can be set only when DECAPEN = 1 */ FTM2_COMBINE |= FTM_COMBINE_DECAP0_MASK; /* Set up status and control register */ /* ClkSource = Bus Clock, PREDIV = 32 */ FTM2_SC = (uint32_t)0x0DUL;
Get result part:
uint32_t CptCalcul = 0;; uint16_t Cpt0; uint16_t Cpt1; if (DV_FMETER_Intialised == TRUE) { /* Get twice counter value */ Cpt0 = FTM2_C0V; Cpt1 = FTM2_C1V; /* Calcul Delta counter value*/ if (Cpt1 >= Cpt0) { CptCalcul = (uint32_t)(Cpt1 - Cpt0); } else { CptCalcul = (uint32_t)(65536 - Cpt0 + Cpt1); } CptCalcul = (CptCalcul * DV_FMETER_PRDIV); CptCalcul = DV_FMETER_CpuClockSource / CptCalcul; }