不同于STM32使用有PWM和定时器中断,可以分别用于PWM输出和脉冲捕获。
K64还有很多其他NXP M4系列的芯片都具有PWM输出和脉冲捕获的模块FTM。
FTM功能很强大,基本功能PWM、输入捕获、正交解码。
这次多旋翼飞控,使用FTM输入捕获来获取接收机的遥控信号。
FTM PWM输出来控制无刷电机转数。
分享一下我学习FTM用到的资料:
Kinetis定时器FTM模块.rar
(930.42 KB)
第8课-FTM的PWM、输入捕获、正交解码.rar
(120.32 KB)
FTM PWM输出的设置
#define MOTO_FTM_BASE FTM3
#define MOTO_FTM_INSTANCE 3
#define MOTO_FTM_PERIOD_HZ 50
#define MOTO_0_CHANNEL 0
#define MOTO_1_CHANNEL 1
#define MOTO_2_CHANNEL 2
#define MOTO_3_CHANNEL 3
extern ftm_pwm_param_t MotoParam;
extern ftm_user_config_t ftmInfo;
void PWM_Init(void);
void PWMPulseWidthSet(uint32_t instance, uint32_t Width, uint8_t channel);
PORT_HAL_SetDriveStrengthMode(PORTD,0u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,0u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,0u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,1u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,1u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,1u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,2u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,2u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,2u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,3u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,3u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,3u,kPortSlowSlewRate);
ftm_pwm_param_t MotoParam = {
.mode = kFtmEdgeAlignedPWM,
.edgeMode = kFtmHighTrue,
.uFrequencyHZ = 50u,
.uDutyCyclePercent = 1250,
.uFirstEdgeDelayPercent = 0,
};
ftm_user_config_t ftmInfo;
void PWM_Init(void)
{
// Initialize FTM module,
// configure for software trigger.zsaA
memset(&ftmInfo, 0, sizeof(ftmInfo));
ftmInfo.syncMethod = kFtmUseSoftwareTrig;
FTM_DRV_Init(MOTO_FTM_INSTANCE, &ftmInfo);
FTM_DRV_SetClock(MOTO_FTM_INSTANCE, kClock_source_FTM_SystemClk, kFtmDividedBy64);
PWMPulseWidthSet(MOTO_FTM_INSTANCE, 1250, MOTO_0_CHANNEL);
PWMPulseWidthSet(MOTO_FTM_INSTANCE, 1250, MOTO_1_CHANNEL);
PWMPulseWidthSet(MOTO_FTM_INSTANCE, 1250, MOTO_2_CHANNEL);
PWMPulseWidthSet(MOTO_FTM_INSTANCE, 1250, MOTO_3_CHANNEL);
}
void PWMPulseWidthSet(uint32_t instance, uint32_t Width, uint8_t channel)
{
MotoParam.uDutyCyclePercent=Width;
// Start PWM mode with updated duty cycle.
FTM_DRV_PwmStart(MOTO_FTM_INSTANCE, &MotoParam, channel);
// Software trigger to update registers.
FTM_HAL_SetSoftwareTriggerCmd(g_ftmBase[MOTO_FTM_INSTANCE], true);
}
FTM 输入捕获的设置
#define MOTO_FTM_BASE FTM3
#define MOTO_FTM_INSTANCE 3
#define MOTO_FTM_PERIOD_HZ 100
#define MOTO_0_CHANNEL 0
#define MOTO_1_CHANNEL 1
#define Recive_FTM_BASE FTM0
#define Recive_FTM_INSTANCE 0
#define Recive_FTM_PERIOD_HZ 100
#define Recive_0_CHANNEL 0
#define Recive_1_CHANNEL 1
uint32_t Temp_Vlue1_A[2], Temp_Vlue1_B[2], Temp_Vlue2_A[2], Temp_Vlue2_B[2],Temp_Vlue3_A[2];//定时捕获遥控器控制量
//定时捕获暂存值
uint32_t Temp1_A1, Temp1_A2, Temp1_B1, Temp1_B2, Temp2_A1, Temp2_A2, Temp2_B1, Temp2_B2,Temp3_A2,Temp3_A1;
int16_t THROTTLE;
void FTM0_IRQHandler(void)
{
if (FTM_HAL_IsChnIntEnabled(g_ftmBase[Recive_FTM_INSTANCE], Recive_0_CHANNEL))
{
FTM_HAL_ClearChnEventStatus(g_ftmBase[Recive_FTM_INSTANCE], Recive_0_CHANNEL);
Temp_Vlue2_A[1]= FTM_HAL_GetChnCountVal(g_ftmBase[Recive_FTM_INSTANCE],Recive_0_CHANNEL);
if(Temp_Vlue2_A[0]<Temp_Vlue2_A[1])
{
Temp2_A1 = Temp_Vlue2_A[1] - Temp_Vlue2_A[0];
}
if(Temp2_A1 > 2500)
{
Temp2_A1 = Temp2_A2;
}
Temp_Vlue2_A[1] = Temp_Vlue2_A[0];
Temp2_A2 = Temp2_A1;
THROTTLE = Temp2_A2; //油门的大小
if(Temp_Vlue2_A[0]<Temp_Vlue2_A[1])
{
Temp2_A1 = Temp_Vlue2_A[1] - Temp_Vlue2_A[0];
}
}
if(FTM_HAL_GetChnCountVal(g_ftmBase[Recive_FTM_INSTANCE],Recive_0_CHANNEL) > 12000) FTM_HAL_SetCounter(g_ftmBase[Recive_FTM_INSTANCE], 0); //计时器清零
}
ftm_user_config_t ftmInfo;
// Configure ftm params with frequency 24kHZ
ftm_pwm_param_t ftmParam = {
.mode = kFtmInputCapture,
.edgeMode = kFtmHighTrue,
.uFrequencyHZ = 50u,
.uDutyCyclePercent = 0,
.uFirstEdgeDelayPercent = 0,
};
hardware_init();
configure_ftm_pins(Recive_FTM_INSTANCE);
OSA_Init();
while(1){
PRINTF("\r\n====== %d ======\r\n\r\n", THROTTLE);
OSA_TimeDelay(40u);
}
// Print a note to terminal.
PRINTF("\r\nWelcome to FTM example\r\n");
PRINTF("\r\nSee the change of LED brightness");
// Initialize FTM module,
// configure for software trigger.zsaA
memset(&ftmInfo, 0, sizeof(ftmInfo));
ftmInfo.syncMethod = kFtmUseSoftwareTrig;
FTM_DRV_Init(Recive_FTM_INSTANCE, &ftmInfo);
FTM_DRV_SetClock(MOTO_FTM_INSTANCE, kClock_source_FTM_SystemClk, kFtmDividedBy64);
void configure_ftm_pins(uint32_t instance)
{
switch(instance) {
case FTM0_IDX: /* FTM0 */
/* Affects PORTA_PCR7 register */
PORT_HAL_SetDriveStrengthMode(PORTC,1u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTC,1u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTC,1u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTC,2u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTC,2u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTC,2u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTC,3u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTC,3u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTC,3u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTA,0u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTA,0u,kPortMuxAlt3);
PORT_HAL_SetSlewRateMode(PORTA,0u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTA,1u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTA,1u,kPortMuxAlt3);
PORT_HAL_SetSlewRateMode(PORTA,1u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTA,2u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTA,2u,kPortMuxAlt3);
PORT_HAL_SetSlewRateMode(PORTA,2u,kPortSlowSlewRate);
break;
case FTM3_IDX:
/* Affects PORTA_PCR7 register */
PORT_HAL_SetDriveStrengthMode(PORTD,0u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,0u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,0u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,1u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,1u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,1u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,2u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,2u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,2u,kPortSlowSlewRate);
PORT_HAL_SetDriveStrengthMode(PORTD,3u,kPortLowDriveStrength);
PORT_HAL_SetMuxMode(PORTD,3u,kPortMuxAlt4);
PORT_HAL_SetSlewRateMode(PORTD,3u,kPortSlowSlewRate);
break;
// case FTM0_IDX: /* FTM0 */
// /* Affects PORTC_PCR1 register */
// PORT_HAL_SetMuxMode(PORTC,1u,kPortMuxAlt4);
// break;
default:
break;
}
}
|