提前说明,实测效果只能捕获4kHz-40kHz
需求:使用通用定时器单通道实现PWM波占空比的捕获。
实现大致思路:
1、将定时器配置成上升沿触发中断
2、进入中断之后将中断触发方式改成下降沿触发
3、如此反复,在上升沿触发时改为下降沿触发,在下降沿触发时改为上升沿触发
4、在中断中读取计数器的值
5、清0计数器
代码:
初始化FTM
void init_FTM(void) {
SIM_SCGC |= SIM_SCGC_FTM2_MASK; /* Sys Clk Gate Ctrl: enable bus clock to FTM2 */
/* FTM2 module settings for desired channel modes: */
FTM2_MODE |= FTM_MODE_WPDIS_MASK; /* Write protect to registers disabled (default) */
FTM2_COMBINE = 0x00000000; /* DECAPEN (Dual Edge Capture Mode Enable) = 0 (default) */
/* COMBINE (chans n & n+1) = 0 (default; independent chans) */
FTM2_MOD = 65500;
FTM2_CNTIN = 1;
FTM2_SC = 0x00000007; /* CWMS (Center aligned PWM Select) = 0 (default, up count) */
/* TOIE (Timer Overflow Interrupt Ena) = 0 (default) */
/* CLKS (Clock source) = 0 (default, no clock; FTM disabled) */
/* PS (Prescaler factor) = 7. Prescaler = 2**7 = 128 */
}
初始化捕获通道:
void init_FTM2_ch3_IC(void) {
FTM2_C3SC = 0x00000044; /* FTM2 ch3: Input Capture on rising edge */
/* CHIE (Chan Interrupt Ena) = 0 (default) */
/* MSB:MSA (chan Mode Select) = 0b00 */
/* ELSB:ELSA (chan Edge or Level Select) = 0b01 */
SIM_PINSEL1 &= ~SIM_PINSEL1_FTM2PS3_MASK; /* Use default pad PTB4 */
FTM2_FILTER = 0x0000F000;//添加滤波器
FTM2_FLTCTRL = 0x00000F88;
}
中断函数:
void FTM2_IRQHandler(void)
{
FTM2_C3SC &= ~FTM_CnSC_CHF_MASK;//清除中断标志位
if(flag == 0)
{
CurrentCaptureVal1 = FTM2_C3V;
FTM2_C3SC = 0x00000048; /* FTM2 ch4: Input Capture on falling edge */
/* CHIE (Chan Interrupt Ena) = 1 (default) */
/* MSB:MSA (chan Mode Select) = 0b00 */
/* ELSB:ELSA (chan Edge or Level Select) = 0b10 */
flag = 1;
FTM2_CNT = 0x00000000;
}
else
{
CurrentCaptureVal2 = FTM2_C3V;
FTM2_C3SC = 0x00000044; /* FTM2 ch4: Input Capture on falling edge */
/* CHIE (Chan Interrupt Ena) = 1 (default) */
/* MSB:MSA (chan Mode Select) = 0b00 */
/* ELSB:ELSA (chan Edge or Level Select) = 0b01 */
flag = 0;
}
}
选择时钟源:
void start_FTM_counters (void) {
FTM2_SC |= FTM_SC_CLKS(1); /* Start FTM2 ctr with clk source TIMER_CLK (20 MHz)*/
}
时钟初始化
/* clocks.c (c) 2015 Freescale Semiconductor, Inc.
* Descriptions: Basic clock functions
* 28 Sept 2015 Osvaldo Romero et al: Initial version
*/
#include "derivative.h"
#include "clocks.h"
void init_clks_FEI_48MHz (void) { /* FLL Enabled with Internal clock */
OSC_CR = 0x00; /* (default value) */
/* OSCEN=0: OSC module disabled */
/* OSCSTEN=0: OSC clock disabled in Stop mode */
/* OSCOS=0: Ext clk source (don't care here) */
/* RANGE=0: Low Freq range of 32 KHz */
/* HGO=0: low power High Gan Osc mode (don't care here) */
ICS_C2 = 0x20; /* Use defaults until dividers configured (default) */
/* BDIV=1: divided by 2 */
/* LP = 0: FLL Not disabled in bypass mode */
ICS_C1 = 0x04; /* Internal ref clock is FLL source (default)*/
/* CLKS=0: Output of FLL is selected to control bus freq */
/* RDIV=0: Ref divider = 1 since RANGE = 0 */
/* IREFS=1: Int Ref clock is selected */
/* IRCLKEN=0: ICSIRCLK is inactive */
/* IREFSTEN=0: Int ref clk is disabled in Stop mode */
while ((ICS_S & ICS_S_LOCK_MASK) == 0); /* Wait for FLL to lock*/
SIM_CLKDIV = 0x01100000; /* OUTDIV1 = 0; Core/sysclk is ICSOUTCLK div by 1 */
/* OUTDIV2 = 1 bus/flash is OUTDIV1/2 */
/* OUTDIV3 = 1; FTMs, PWT is ICSOUTCLK div by 2 */
ICS_C2 = 0x00; /* BDIV div by 1- increases bus/flash freq */
}
void init_clks_FEE_40MHz(void) { /* FLL Enabled with External clock */
OSC_CR = 0x96; /* High range & gain; select osc */
/* OSCEN =1 ; OSC module enabled */
/* OSCSTEN = 0; OSC clock disabled in stop mode */
/* OSCOS = 1; OSC clcok source is selected */
/* RANGE = 1; High freq range of 4-24 MHz */
/* HGO = 1; High-gain mode */
while ((OSC_CR & OSC_CR_OSCINIT_MASK) == 0); /* Wait until oscillator is ready*/
ICS_C2 = 0x20; /* BDIV div by 2; use default until dividers configured*/
/* LP = 0; FLL is not disabled in bypass mode */
ICS_C1 = 0x18; /* 8 Mhz ext ref clk/256 is source to FLL */
/* CLKS = 0; Output of FLL is selected (default) */
/* RDIV = 3; ref clk prescaled by 256 with RANGE=0 */
/* IREFS = 0; ext clk source selected */
/* IRCLKEN = 0; ICSIRCLK inactive */
/* IREFSTEN = 0; Int ref clk disabled in Stop mode */
while ((ICS_S & ICS_S_IREFST_MASK) == 1); /* Wait for external source selected */
while ((ICS_S & ICS_S_LOCK_MASK) == 0); /* Wait for FLL to lock */
SIM_CLKDIV = 0x01100000; /* OUTDIV1 = 0; Core/sysclk is ICSOUTCLK div by 1 */
/* OUTDIV2 = 1 bus/flash is OUTDIV1/2 */
/* OUTDIV3 = 1; FTMs, PWT is ICSOUTCLK div by 2 */
ICS_C2 = 0x00; /* BDIV div by 1- increases bus/flash freq */
}
主函数:
/* main.c (c) 2015 Freescale Semiconductor, Inc.
* Descriptions: FTM example code.
* 28 Sept 2015 Osvaldo Romero: Initial version
*/
#include "derivative.h" /* include peripheral declarations SKEAZ128M4 */
#include "FTM.h"
#include "clocks.h"
int main(void) {
init_clks_FEE_40MHz(); /* KEA128 clks FEE, 8MHz xtal: core 40 MHz, bus 20MHz */
init_FTM (); /* Enable bus clock to FTM1,2 prescaled by 128 */
init_FTM2_ch3_IC(); /* PTB5 input; connect J2_5 and J2_10 */
NVIC_EnableIRQ(FTM2_IRQn);
start_FTM_counters();
for(;;)
{
}
}