【简介】
S32K146 的PWM 可以通过FTM模块(FlexTimer Module)来输出,FTM 的每个channel 都可以配置为PWM 功能。PWM 按照模式可以分为Edge Aligned PWM 和 Center Aligned PWM 。
以下是Edge Aligned PWM 工作模式的时序
以下是Center Aligned PWM 工作模式的时序
【PWM引脚配置】
本地使用PTB5 作为PWM输出引脚,通过S32DS配置PTB5 pinmux 为ftm0 channel5.
【时钟配置】
FTM0 时钟配置为内部SIRC_DIV1为工作时钟
【PWM 参数配置】
PWM 通路参数配置
生成对应配置代码如下:
/*********************************************************************************************************************** * This file was generated by the S32 Configuration Tools. Any manual edits made to this file * will be overwritten if the respective S32 Configuration Tools is used to update this file. **********************************************************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* !!GlobalInfo product: Peripherals v14.0 processor: S32K146 package_id: S32K146_LQFP144 mcu_data: s32sdk_s32k1xx_rtm_401 processor_version: 0.0.0 functionalGroups: - name: BOARD_InitPeripherals UUID: 2d0c0af7-dbe7-4f00-821a-837510d6ab4e called_from_default_init: true selectedCore: core0 * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /******************************************************************************* * Included files ******************************************************************************/ #include "peripherals_flexTimer_pwm_1.h" /******************************************************************************* * flexTimer_pwm_1 initialization code ******************************************************************************/ /* clang-format off */ /* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* instance: - name: 'flexTimer_pwm_1' - type: 'flexTimer_pwm' - mode: 'general' - custom_name_enabled: 'false' - type_id: 'ftm_pwm' - functional_group: 'BOARD_InitPeripherals' - peripheral: 'FTM_0' - config_sets: - ftm_pwm: - ftmPwmUserConfig: - ftmPwmInitConfig: - ftmPwmClkCfg: - ClockSource: 'FTM_CLOCK_SOURCE_SYSTEMCLK' - ftmprescaler: '4' - ftmPwmGlobalCfg: - ftmMode: 'FTM_MODE_EDGE_ALIGNED_PWM' - debugMode: 'FTM_BDM_MODE_00' - timerOverInter: 'false' - initTrigger: 'false' - ftmPwmRegSyncCfg: - softTrigger: 'true' - hardwareTrigger1: 'false' - hardwareTrigger2: 'false' - hardwareTrigger3: 'false' - ftmSyncPoint: 'FTM_UPDATE_NOW' - maxload: 'false' - minload: 'false' - AutoTrigClear: 'false' - ftmRegisterUpdate: 'FTM_PWM_SYNC' - ftmSoftwareOutControl: 'FTM_PWM_SYNC' - ftmOutMaskSync: 'FTM_PWM_SYNC' - ftmCounterInitSync: 'FTM_PWM_SYNC' - ftmPwmConfiguration: - ftmPwmGeneralCfg: - periodInFreq: '1000000' - deadTimeValue: '0' - deadTimePrescaler: 'FTM_DEADTIME_DIVID_BY_1' - FtmPwmConfigArr: - faultConfig: - faultMode: 'FTM_FAULT_CONTROL_DISABLED' - pwmFaultInterrupt: 'false' - faultFilterValue: '0' - pwmOutputStateOnFault: 'false' - ftmFaultChannelParam: - 0: - faultChannelEnabled: 'false' - faultFilterEnabled: 'false' - ftmFaultPinPolarity: 'FTM_POLARITY_LOW' - 1: - faultChannelEnabled: 'false' - faultFilterEnabled: 'false' - ftmFaultPinPolarity: 'FTM_POLARITY_LOW' - 2: - faultChannelEnabled: 'false' - faultFilterEnabled: 'false' - ftmFaultPinPolarity: 'FTM_POLARITY_LOW' - 3: - faultChannelEnabled: 'false' - faultFilterEnabled: 'false' - ftmFaultPinPolarity: 'FTM_POLARITY_LOW' - ftmPwmIndptChnCfg: - pwmIndependentChannelConfig: - 0: - ftmpwmIndptName: 'flexTimer_pwm_1_IndependentChannelConfig0' - ftmPwmIndptHwChnId: '5' - polarity: 'FTM_POLARITY_LOW' - uDutyCyclePercent: '0x4000' - enableExternalTrigger: 'false' - safeState: 'FTM_LOW_STATE' - enableSecondChannelOutput: 'false' - secondChannelPolarity: 'FTM_MAIN_INVERTED' - IndptdeadTimeEn: 'false' - ftmPwmCombChnCfg: - pwmCombinedChannelConfig: [] * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ /* clang-format on */ /** * @page misra_violations MISRA-C:2012 violations * * @section [global] * Violates MISRA 2012 Advisory Rule 8.7, External variable could be made static. * The external variables will be used in other source files in application code. * */ /* Global configuration of flexTimer_pwm_1 InitConfig */ ftm_user_config_t flexTimer_pwm_1_InitConfig = { { true, /* Software trigger state */ false, /* Hardware trigger 1 state */ false, /* Hardware trigger 2 state */ false, /* Hardware trigger 3 state */ false, /* Max loading point state */ false, /* Min loading point state */ FTM_PWM_SYNC, /* Update mode for INVCTRL register */ FTM_PWM_SYNC, /* Update mode for SWOCTRL register */ FTM_PWM_SYNC, /* Update mode for OUTMASK register */ FTM_PWM_SYNC, /* Update mode for CNTIN register */ true, /* Automatic clear of the trigger*/ FTM_UPDATE_NOW, /* Synchronization point */ }, FTM_MODE_EDGE_ALIGNED_PWM, /* Mode of operation for FTM */ FTM_CLOCK_DIVID_BY_4, /* FTM clock prescaler */ FTM_CLOCK_SOURCE_SYSTEMCLK, /* FTM clock source */ FTM_BDM_MODE_00, /* FTM debug mode */ false, /* Interrupt state */ false /* Initialization trigger */ }; /* Fault configuration structure for flexTimer_pwm_1*/ ftm_pwm_fault_param_t flexTimer_pwm_1_FaultConfig = { false, /* Output pin state on fault */ false, /* PWM fault interrupt state */ 0U, /* Fault filter value */ FTM_FAULT_CONTROL_DISABLED, /* Fault mode */ { { false, /* Fault channel state (Enabled/Disabled) */ false, /* Fault channel filter state (Enabled/Disabled) */ FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */ }, { false, /* Fault channel state (Enabled/Disabled) */ false, /* Fault channel filter state (Enabled/Disabled) */ FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */ }, { false, /* Fault channel state (Enabled/Disabled) */ false, /* Fault channel filter state (Enabled/Disabled) */ FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */ }, { false, /* Fault channel state (Enabled/Disabled) */ false, /* Fault channel filter state (Enabled/Disabled) */ FTM_POLARITY_LOW, /* Fault channel state (Enabled/Disabled) */ }, } }; /* The independent channels configuration structure for flexTimer_pwm_1_IndependentChannelsConfig */ ftm_independent_ch_param_t flexTimer_pwm_1_IndependentChannelsConfig[1] = { { 5, /* Hardware channel Id */ FTM_POLARITY_LOW, /* Polarity of the PWM signal */ 16384U, /* Duty cycle percent 0-0x8000 */ false, /* External Trigger */ FTM_LOW_STATE, /* Safe state of the PWM channel when faults are detected */ false, /* Enabled/disabled the channel (n+1) output */ FTM_MAIN_INVERTED, /* Select channel (n+1) output relative to channel (n) */ false, /* Dead time enabled/disabled */ } }; /* PWM configuration for flexTimer_pwm_1 */ ftm_pwm_param_t flexTimer_pwm_1_PwmConfig = { 1U, /* Number of independent PWM channels */ 0U, /* Number of combined PWM channels */ FTM_MODE_EDGE_ALIGNED_PWM, /* PWM mode */ 0U, /* Dead time value */ FTM_DEADTIME_DIVID_BY_1, /* Dead time prescale */ 1000000U, /* PWM frequency */ flexTimer_pwm_1_IndependentChannelsConfig, /* The independent PWM channels configuration structure */ NULL, /* Combined PWM channels configuration structure */ &flexTimer_pwm_1_FaultConfig /* PWM fault configuration structure */ };
【代码验证】
添加以下代码初始化pwm 输出1Mhz 50%的占空比配置
static int pwm_init(void) { status_t ret; /* config pwm timer */ ret = FTM_DRV_Init(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_InitConfig, &ftm0_pwm_state); if(ret != STATUS_SUCCESS) { LOG_E("Ftm0 init failed %x.",ret); } else { LOG_I("Ftm0 init OK."); } ret = FTM_DRV_InitPwm(INST_FLEXTIMER_PWM_1, &flexTimer_pwm_1_PwmConfig); if(ret != STATUS_SUCCESS) { LOG_E("Ftm0 pwm init failed %x.",ret); } else { LOG_I("Ftm0 pwm init OK."); } return 1; } INIT_BOARD_EXPORT_LEVEL1(pwm_init);
运行后PTB5 引脚按照预期的输出PWM 1MHZ 50% 占空比的信号
添加如下代码更新占空比配置
/******************************************************************************************************** * Private Function Declarations * *******************************************************************************************************/ unsigned int pwm(char argc,char *argv[]) { uint16_t duty; uint16_t firstEdge; status_t ret; if(argc == 2) { duty = atoi(argv[1]); firstEdge = FTM_MAX_DUTY_CYCLE*duty*100/10000; ret = FTM_DRV_UpdatePwmChannel(INST_FLEXTIMER_PWM_1,5U,FTM_PWM_UPDATE_IN_DUTY_CYCLE,firstEdge,0U,true); if(ret != STATUS_SUCCESS) { LOG_E("Ftm0 pwm update failed %x.",ret); } else { LOG_I("Ftm0 pwm update OK."); } } return 0; }
pwm 配置为25% 后查看PWM 波形已经按照预期的配置为25%