打印
[活动]

【多旋翼飞控】通过FTM进行PWM波输出和脉冲捕获

[复制链接]
2351|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
冷不丁|  楼主 | 2016-2-6 15:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
不同于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;
  }
}




相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:hungry

10

主题

36

帖子

7

粉丝