TIM_initConfig.timMode = IfxGtm_Tim_Mode_inputEvent;这个是事件采集可以获得边延数 TIM_CNT = GTM_TIM0_CH0_GPR0.B.GPR0;//边沿数,通过这个寄存器获取
设置什么模式是通过这个初始化来的
简单点,我们的编码器只输出一个通道的脉冲信号,为了实现使用两种模式测量。我们需要用两个TIM通道来测量,一个通道测周期、一个则对边沿计数。
那么需配置:
(1)输入时钟配置:TIM的三个模块需要配置时钟,分别是:捕捉单元、滤波、超时检测。我们配置捕捉和超时检测单元的时间分度为10us,使用CMU_CLK_0;而滤波模块时间分度为1us,使用CMU_CLK_6。
下面是CMU单元代码:
void GTM_Cmu_init()
{
//Enable the GTM
IfxGtm_enable(gtm);//解锁寄存器
IfxGtm_Cmu_Clk clkIndex=IfxGtm_Cmu_Clk_0;
//enable GTM clock
boolean frequency = IfxGtm_Cmu_isClkClockEnabled(&MODULE_GTM,clkIndex);//GTM时钟使能,返回为使能/不使能:1/0
//Set the global clock frequency to the max
IfxGtm_Cmu_setGclkFrequency(gtm,1000000.0f);//把全局时钟频率设为最大,设为1MHz
//Set the CMU CLK0
IfxGtm_Cmu_setClkFrequency(gtm,IfxGtm_Cmu_Clk_0,100000.0f);
IfxGtm_Cmu_setClkFrequency(gtm,IfxGtm_Cmu_Clk_6,1000000.0f);
// FXCLK: used by TOM and CLK0: used by ATOM
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_CLK0);
GTM_CMU_FXCLK_CTRL.B.FXCLK_SEL = IfxGtm_Cmu_Clk_0; // TOM时钟源
// enable FX clock
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK);
}
代码在之前介绍过,这里就不多说了。
(2)滤波和超时检测
我们设定的最大转速为100转,编码器为400脉冲/转(便宜货)。也就是可以计算最小周期为1.5ms,相邻两个边沿的时间为750us。我们滤波时间配置为100us,使用immediate edge propagation模式。检测到边沿后的100us内任何边沿都是无效的。超时时间默认设为最大180ms(低于1转/s)。
(3)通道配置
TIMO_CH0作为我们的第一个通道,采集周期信息,需配置为TPWM模式;TIM0_CH1作为我们的第二个通道,输入源配置为通道0的输入,采集边沿,需配置为TIEM模式。
以下便是初始化代码:
TIM0_CH0初始化
void TIM0_CH0_init(void)
{
IfxGtm_Tim_In_Config TIM_initConfig;
IfxGtm_Tim_In TIM_driverConfig;
//TIM_initConfig.gtm = gtm;
//通道0,作为事件采集
IfxGtm_Tim_In_initConfig (&TIM_initConfig, gtm_tim);
TIM_initConfig.channelIndex = IfxGtm_Tim_Ch_0;
TIM_initConfig.capture.irqOnNewVal = TRUE;
TIM_initConfig.isrPriority = TIM_EDGE_DETECT;
TIM_initConfig.filter.inputPin = &IfxGtm_TIM0_0_TIN0_P02_0_IN;
TIM_initConfig.filter.input = IfxGtm_Tim_In_Input_currentChannel;
TIM_initConfig.filter.clock = IfxGtm_Cmu_Tim_Filter_Clk_6;
TIM_initConfig.filter.risingEdgeMode = IfxGtm_Tim_In_ConfigFilterMode_immediateEdgePropagation;
TIM_initConfig.filter.risingEdgeFilterTime = 0.0001;//100us
TIM_initConfig.filter.fallingEdgeMode = IfxGtm_Tim_In_ConfigFilterMode_immediateEdgePropagation;
TIM_initConfig.filter.fallingEdgeFilterTime= 0.0001;//100us
TIM_initConfig.timeout.timeout = 18000;//180ms
TIM_initConfig.timMode = IfxGtm_Tim_Mode_inputEvent;
IfxGtm_Tim_In_init (&TIM_driverConfig, &TIM_initConfig);
IfxCpu_Irq_installInterruptHandler(TIM0Ch0_ISR,TIM_EDGE_DETECT);
IfxCpu_enableInterrupts();
}
TIM0_CH1初始化
void TIM0_CH1_init(void)
{
IfxGtm_Tim_In_Config TIM_initConfig;
IfxGtm_Tim_In TIM_driverConfig;
//TIM_initConfig.gtm = gtm;
//通道0,作为事件采集
IfxGtm_Tim_In_initConfig (&TIM_initConfig, gtm_tim);
//通道1,作为周期,占空比采集
//IfxGtm_Tim_In_initConfig (&TIM_initConfig, gtm_tim);
TIM_initConfig.channelIndex = IfxGtm_Tim_Ch_1;
TIM_initConfig.filter.input = IfxGtm_Tim_In_Input_adjacentChannel;
TIM_initConfig.capture.irqOnNewVal = TRUE;
TIM_initConfig.isrPriority = TIM_PULSE_DETECT;
TIM_initConfig.filter.inputPin = &IfxGtm_TIM0_0_TIN0_P02_0_IN;
TIM_initConfig.filter.risingEdgeMode = IfxGtm_Tim_In_ConfigFilterMode_immediateEdgePropagation;
TIM_initConfig.filter.risingEdgeFilterTime = 0.0001;//100us
TIM_initConfig.filter.fallingEdgeMode = IfxGtm_Tim_In_ConfigFilterMode_immediateEdgePropagation;
TIM_initConfig.filter.fallingEdgeFilterTime= 0.0001;//100us
TIM_initConfig.timeout.timeout = 18000;//180ms
TIM_initConfig.timMode = IfxGtm_Tim_Mode_pwmMeasurement;
IfxGtm_Tim_In_init (&TIM_driverConfig, &TIM_initConfig);
IfxCpu_Irq_installInterruptHandler(TIM0Ch1_ISR,TIM_PULSE_DETECT);
IfxCpu_enableInterrupts();
}
然后在中断中读取周期、以及边沿数目
IFX_INTERRUPT(TIM0Ch0_ISR,0,TIM_EDGE_DETECT)
{
// IfxPort_togglePin(&MODULE_P13, 1);
IfxPort_togglePin(&MODULE_P14, 8);
//if(IfxGtm_Tim_In_isNewData())
TIM_CNT = GTM_TIM0_CH0_GPR0.B.GPR0;//边沿数
period = GTM_TIM0_CH1_GPR0.B.GPR0;//周期
dutycycle=GTM_TIM0_CH1_GPR1.B.GPR1;//占空比
if(TIM_CNT >= 60)
TIM_CNT = 0;
//Adc_Samp(AN1);
IfxCpu_enableInterrupts();
}