一、硬件
RGB LED 连接方式
二、PWM 配置流程
在 pin_mux.c 中配置引脚复用为 PWM 功能 IOCON_PIO_FUNC1 表示复用为 PWM,
核心代码实现
static void PWM_DRV_InitPwm(void) { uint16_t deadTimeVal; pwm_signal_param_t pwmSignal[2]; uint32_t pwmSourceClockInHz; uint32_t pwmFrequencyInHz = APP_DEFAULT_PWM_FREQUENCY; pwmSourceClockInHz = PWM_SRC_CLK_FREQ; /* Set deadtime count, we set this to about 650ns */ deadTimeVal = ((uint64_t)pwmSourceClockInHz * 650) / 1000000000; pwmSignal[0].pwmChannel = kPWM_PwmA; pwmSignal[0].level = kPWM_HighTrue; pwmSignal[0].dutyCyclePercent = 50; /* 1 percent dutycycle */ pwmSignal[0].deadtimeValue = deadTimeVal; pwmSignal[0].faultState = kPWM_PwmFaultState0; pwmSignal[0].pwmchannelenable = true; pwmSignal[1].pwmChannel = kPWM_PwmB; pwmSignal[1].level = kPWM_HighTrue; pwmSignal[1].dutyCyclePercent = 50; pwmSignal[1].deadtimeValue = deadTimeVal; pwmSignal[1].faultState = kPWM_PwmFaultState0; pwmSignal[1].pwmchannelenable = true; PWM_SetupPwm(FLEXPWM0, kPWM_Module_0, pwmSignal, 1, kPWM_SignedCenterAligned, pwmFrequencyInHz, pwmSourceClockInHz); PWM_SetupPwm(FLEXPWM1, kPWM_Module_2, pwmSignal, 2, kPWM_SignedCenterAligned, pwmFrequencyInHz, pwmSourceClockInHz); } pwm_config_t pwmConfig; pwm_fault_param_t faultConfig; uint32_t pwmVal1 = 2; uint32_t pwmVal2 = 4; uint32_t pwmVal3 = 5; pwmConfig.enableDebugMode = false; pwmConfig.reloadSelect = kPWM_LocalReload; pwmConfig.clockSource = kPWM_BusClock; pwmConfig.prescale = kPWM_Prescale_Divide_1; pwmConfig.initializationControl = kPWM_Initialize_LocalSync; pwmConfig.forceTrigger = kPWM_Force_Local; pwmConfig.reloadFrequency = kPWM_LoadEveryOportunity; pwmConfig.reloadLogic = kPWM_ReloadImmediate; pwmConfig.pairOperation = kPWM_Independent; PWM_GetDefaultConfig(&pwmConfig); #ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL /* Init FSL debug console. */ BOARD_InitDebugConsole(); #endif #ifdef DEMO_PWM_CLOCK_DEVIDER pwmConfig.prescale = DEMO_PWM_CLOCK_DEVIDER; #endif /* Use full cycle reload */ pwmConfig.reloadLogic = kPWM_ReloadPwmFullCycle; /* PWM A & PWM B form a complementary PWM pair */ pwmConfig.pairOperation = kPWM_ComplementaryPwmA; pwmConfig.enableDebugMode = true; /* Initialize submodule 0 */ if (PWM_Init(FLEXPWM0, kPWM_Module_0, &pwmConfig) == kStatus_Fail) { PRINTF("PWM initialization failed\n"); return 1; } if (PWM_Init(FLEXPWM1, kPWM_Module_2, &pwmConfig) == kStatus_Fail) { PRINTF("PWM initialization failed\n"); return 1; } /* Initialize submodule 1, make it use same counter clock as submodule 0. */ pwmConfig.clockSource = kPWM_Submodule0Clock; pwmConfig.prescale = kPWM_Prescale_Divide_1; pwmConfig.initializationControl = kPWM_Initialize_MasterSync; PWM_FaultDefaultConfig(&faultConfig); #ifdef DEMO_PWM_FAULT_LEVEL faultConfig.faultLevel = DEMO_PWM_FAULT_LEVEL; #endif /* Sets up the PWM fault protection */ PWM_SetupFaults(FLEXPWM0, kPWM_Fault_0, &faultConfig); PWM_SetupFaults(FLEXPWM0, kPWM_Fault_1, &faultConfig); PWM_SetupFaults(FLEXPWM0, kPWM_Fault_2, &faultConfig); PWM_SetupFaults(FLEXPWM0, kPWM_Fault_3, &faultConfig); PWM_SetupFaults(FLEXPWM1, kPWM_Fault_0, &faultConfig); PWM_SetupFaults(FLEXPWM1, kPWM_Fault_1, &faultConfig); PWM_SetupFaults(FLEXPWM1, kPWM_Fault_2, &faultConfig); PWM_SetupFaults(FLEXPWM1, kPWM_Fault_3, &faultConfig); /* Set PWM fault disable mapping for submodule 0/1/2 */ PWM_SetupFaultDisableMap(FLEXPWM0, kPWM_Module_0, kPWM_PwmA, kPWM_faultchannel_0, kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3); PWM_SetupFaultDisableMap(FLEXPWM1, kPWM_Module_2, kPWM_PwmA, kPWM_faultchannel_0, kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3); PWM_SetupFaultDisableMap(FLEXPWM1, kPWM_Module_2, kPWM_PwmB, kPWM_faultchannel_0, kPWM_FaultDisable_0 | kPWM_FaultDisable_1 | kPWM_FaultDisable_2 | kPWM_FaultDisable_3); PWM_DRV_InitPwm(); /* Set the load okay bit for all submodules to load registers from their buffer */ PWM_SetPwmLdok(FLEXPWM0, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true); PWM_SetPwmLdok(FLEXPWM1, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true); /* Start the PWM generation from Submodules 0, 1 and 2 */ PWM_StartTimer(FLEXPWM0, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2); PWM_StartTimer(FLEXPWM1, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2); int flag1 = 1; int flag2 = 1; int flag3 = 1; /* Enter an infinite loop, just incrementing a counter. */ while(1) { /* Delay at least 100 PWM periods. */ SDK_DelayAtLeastUs((1000000U / APP_DEFAULT_PWM_FREQUENCY) * 100, SDK_DEVICE_MAXIMUM_CPU_CLOCK_FREQUENCY); pwmVal1 += flag1 * 2; pwmVal2 += flag2 * 4; pwmVal3 += flag3 * 5; /* Reset the duty cycle percentage */ if (pwmVal1 == 100) flag1 = -1; if (pwmVal1 == 0) flag1 = 1; if (pwmVal2 == 100) flag2 = -1; if (pwmVal2 == 0) flag2 = 1; if (pwmVal3 == 100) flag3 = -1; if (pwmVal3 == 0) flag3 = 1; /* Update duty cycles for all 3 PWM signals */ PWM_UpdatePwmDutycycle(FLEXPWM0, kPWM_Module_0, kPWM_PwmA, kPWM_SignedCenterAligned, pwmVal1); PWM_UpdatePwmDutycycle(FLEXPWM1, kPWM_Module_2, kPWM_PwmA, kPWM_SignedCenterAligned, pwmVal2); PWM_UpdatePwmDutycycle(FLEXPWM1, kPWM_Module_2, kPWM_PwmB, kPWM_SignedCenterAligned, pwmVal3); /* Set the load okay bit for all submodules to load registers from their buffer */ PWM_SetPwmLdok(FLEXPWM0, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true); PWM_SetPwmLdok(FLEXPWM1, kPWM_Control_Module_0 | kPWM_Control_Module_1 | kPWM_Control_Module_2, true); }
三.PWM脚定义
进入引脚定义页面,对RGB灯的三个引脚进行定义,定义为FlexPWM模式。
PWM输出引脚包括PWM种类PWM0/PWM1、PWM通道A/B及PWM的子模块,P3_13引脚的路由信号相关参数如下。
四.实现效果