I am trying to measure the percentage of a PWM signal on a FRDM-K64 board. I am using the FTM2 FlexTimer in dual edge capture mode on channels 0-1. I'm getting the interrupts both for the rising and falling edge of the pulses.But after entering the interrupt function, simply enter a rising edge of a subroutine, but there is no falling entered a subroutine, why is there such a situation
code:
#include "board.h" #include "fsl_debug_console.h" #include "pin_mux.h" #include "clock_config.h" #include "fsl_ftm.h" /******************************************************************************* * Definitions ******************************************************************************/ /* The Flextimer instance/channel used for board */ #define DEMO_FTM_BASEADDR FTM2 /* FTM channel pair used for the dual-edge capture, channel pair 0 uses channels 0 and 1 */ #define BOARD_FTM_INPUT_CAPTURE_CHANNEL_PAIR kFTM_Chnl_0 /* Interrupt number and interrupt handler for the FTM instance used */ #define FTM_INTERRUPT_NUMBER FTM2_IRQn #define FTM_INPUT_CAPTURE_HANDLER FTM2_IRQHandler /* Interrupt to enable and flag to read; depends on the FTM channel used for dual-edge capture */ #define FTM_CHANNEL0_INTERRUPT_ENABLE kFTM_Chnl0InterruptEnable #define FTM_CHANNEL1_INTERRUPT_ENABLE kFTM_Chnl1InterruptEnable #define FTM_CHANNEL0_FLAG kFTM_Chnl0Flag #define FTM_CHANNEL1_FLAG kFTM_Chnl1Flag /* Get source clock for FTM driver */ #define FTM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_BusClk) /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ volatile bool ftmIsrFlag = false; /******************************************************************************* * Code ******************************************************************************/ void FTM_INPUT_CAPTURE_HANDLER(void) { if ((FTM_GetStatusFlags(DEMO_FTM_BASEADDR) & FTM_CHANNEL0_FLAG) == FTM_CHANNEL0_FLAG) { PRINTF("\r\n/**********************rasing interrupt****************************\n"); FTM_ClearStatusFlags(DEMO_FTM_BASEADDR, FTM_CHANNEL0_FLAG); } if ((FTM_GetStatusFlags(DEMO_FTM_BASEADDR) & FTM_CHANNEL1_FLAG) == FTM_CHANNEL1_FLAG) { PRINTF("\r\n/**********************falling interrupt****************************\n"); FTM_ClearStatusFlags(DEMO_FTM_BASEADDR, FTM_CHANNEL1_FLAG); } } /*! * @brief Main function */ int main(void) { ftm_config_t ftmInfo; ftm_dual_edge_capture_param_t edgeParam; /* Board pin, clock, debug console init */ BOARD_InitPins(); BOARD_BootClockRUN(); BOARD_InitDebugConsole(); /* Print a note to terminal */ PRINTF("\r\nFTM dual-edge capture example\r\n"); PRINTF("\r\nSYSTEM Clock:%d\r\n",CLOCK_GetFreq(kCLOCK_CoreSysClk)); PRINTF("\r\nBUS Clock:%d\r\n",CLOCK_GetFreq(kCLOCK_BusClk)); FTM_GetDefaultConfig(&ftmInfo); ftmInfo.prescale = kFTM_Prescale_Divide_128; /* Initialize FTM module */ FTM_Init(DEMO_FTM_BASEADDR, &ftmInfo); edgeParam.mode = kFTM_Continuous; //Set capture edges to calculate the pulse width of input signal edgeParam.currChanEdgeMode = kFTM_RisingEdge; edgeParam.nextChanEdgeMode = kFTM_FallingEdge; /* Setup dual-edge capture on a FTM channel pair */ FTM_SetupDualEdgeCapture(DEMO_FTM_BASEADDR, BOARD_FTM_INPUT_CAPTURE_CHANNEL_PAIR, &edgeParam, 0); /* Set the timer to be in free-running mode */ DEMO_FTM_BASEADDR->MOD = 0xffff; /* Enable channel interrupt when the second edge is detected */ FTM_EnableInterrupts(DEMO_FTM_BASEADDR, FTM_CHANNEL0_INTERRUPT_ENABLE); FTM_EnableInterrupts(DEMO_FTM_BASEADDR, FTM_CHANNEL1_INTERRUPT_ENABLE); /* Enable at the NVIC */ EnableIRQ(FTM_INTERRUPT_NUMBER); FTM_StartTimer(DEMO_FTM_BASEADDR, kFTM_SystemClock); while (1) { ; } }
Original Attachment has been moved to: main.c.zip
Solved! Go to Solution.
Yes, that code doesn't take into account the case of FTMx_CNT overflow.
So if you want that code get the correct result, you need ensure FTMx_CNT doesn't overflow.(FTMx_CNT period > PWM period)
You can increase the overflow period of FTMx_CNT by setup "ftmInfo.prescale".
If kFTM_Prescale_Divide_1, then pulseWidth = ((capture2Val - capture1Val) + 1) / (FTM_SOURCE_CLOCK / 1000000);
If kFTM_Prescale_Divide_128, then pulseWidth = 128*((capture2Val - capture1Val) + 1) / (FTM_SOURCE_CLOCK / 1000000);
Best Regards,
Robin
Hi Rbin_Shen,
Thank for your help,I've looked at your code, I also had a look at this example, the code for this but there is a problem, this code does not take into account the case of overflow interrupt, and overflow interrupt calculated according to the desired value in the first interval along the overflow interrupt flag is set to 0, so it is necessary in the first direction to generate an interrupt, but I list the code shows: generate interrupt flag is wrong, but why is wrong. Can you help me?
Yes, that code doesn't take into account the case of FTMx_CNT overflow.
So if you want that code get the correct result, you need ensure FTMx_CNT doesn't overflow.(FTMx_CNT period > PWM period)
You can increase the overflow period of FTMx_CNT by setup "ftmInfo.prescale".
If kFTM_Prescale_Divide_1, then pulseWidth = ((capture2Val - capture1Val) + 1) / (FTM_SOURCE_CLOCK / 1000000);
If kFTM_Prescale_Divide_128, then pulseWidth = 128*((capture2Val - capture1Val) + 1) / (FTM_SOURCE_CLOCK / 1000000);
Best Regards,
Robin
Hi,Robin_Shen
Thank you for your answer, your answer was very helpful。
Yes -- as long as capture1Val and capture2Val are declared as 16-bit unsigned, and FTMxCNT is 0xFFFF (full 65536 counts)., and then you CAN IGNORE OVERFLOW. For THEN a pulse (not clear if user is looking for 'high time', 'low time', or 'full pulse time') that happens to fall across an 'overflow time point' will get the proper mathematical result: For example, 1 - 0xFFFF in 16 bit math is a proper 2, in 32bit it is 0xFFFF0002.
Hi, EARL GOODRICH
Thank you for your answer, your answer was helpful。
IF that 'ftm_dual_edge_capture' demo code had defined capture1Val and capture2Val as uint16_t, (and only allowed the promotion to 32-bit math in the '+1' operation) then the 'natural' 16-bit-integer math would preclude any requirement to worry about 'overflow' as long as the overall pulse width to measure is less than one full FTM cycle.