本开发板载的是MCX N947,封装为184VFBGA,采用M33内核,主频可以达到150MHz。 MCUXpressoIDE集成了配置工具: 时钟配置: 打开例程对应的时钟配置如下: 主频为150MHz,PRO_HF为48M,通过测试可以得知定时器所用的高频时钟为48M。 引脚配置: 例程中使用的是P0_10作为PWM输出引脚,该引脚同时是LED的控制引脚。 一、设置PWM功能流程(在例程中添加一路PWM输出) 1、配置系统时钟 1. /* attach FRO 12M to FLEXCOMM4 (debug console) */ 2. CLOCK_SetClkDiv(kCLOCK_DivFlexcom4Clk, 1u); 3. CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); 4. 5. /* Use FRO HF clock for some of the Ctimers */ 6. CLOCK_SetClkDiv(kCLOCK_DivCtimer0Clk, 1u); 7. CLOCK_AttachClk(kFRO_HF_to_CTIMER0); 2、配置引脚 打开配置工具的查看引脚功能,P0_10配置为CTIMER0的PWM通道1; 来到代码中可以看到如下初始化: 1. /* Enables the clock for PORT0 controller: Enables clock */ 2. CLOCK_EnableClock(kCLOCK_Port0); 3. 4. const port_pin_config_t LED_RED = {/* Internal pull-up/down resistor is disabled */ 5. kPORT_PullDisable, 6. /* Low internal pull resistor value is selected. */ 7. kPORT_LowPullResistor, 8. /* Fast slew rate is configured */ 9. kPORT_FastSlewRate, 10. /* Passive input filter is disabled */ 11. kPORT_PassiveFilterDisable, 12. /* Open drain output is disabled */ 13. kPORT_OpenDrainDisable, 14. /* Low drive strength is configured */ 15. kPORT_LowDriveStrength, 16. /* Pin is configured as CT0_MAT0 */ 17. kPORT_MuxAlt4, 18. /* Digital input enabled */ 19. kPORT_InputBufferEnable, 20. /* Digital input is not inverted */ 21. kPORT_InputNormal, 22. /* Pin Control Register fields [15:0] are not locked */ 23. kPORT_UnlockRegister}; 24. /* PORT0_10 (pin B12) is configured as CT0_MAT0 */ 25. PORT_SetPinConfig(BOARD_INITPINS_LED_RED_PORT, BOARD_INITPINS_LED_RED_PIN, &LED_RED); 26. 27. /* PORT0_11 (pin B11) is configured as CT0_MAT1 */ 28. PORT_SetPinMux(PORT0, 11U, kPORT_MuxAlt4); 29. 30. PORT0->PCR[11] = ((PORT0->PCR[11] & 31. /* Mask bits to zero which are setting */ 32. (~(PORT_PCR_IBE_MASK))) 33. 34. /* Input Buffer Enable: Enables. */ 35. | PORT_PCR_IBE(PCR_IBE_ibe1)); 3、配置定时器及通道 板级的初始化已经完成,我们需要通过将我们添加的引脚与对应的定时器添加上。 1. /* Get the PWM period match value and pulse width match value of 20Khz PWM signal with 20% dutycycle */ 2. CTIMER_GetPwmPeriodValue(20000, 20, timerClock); 3. CTIMER_SetupPwmPeriod(CTIMER, kCTIMER_Match_3, kCTIMER_Match_0, g_pwmPeriod, g_pulsePeriod, false); 4. CTIMER_GetPwmPeriodValue(20000, 50, timerClock); 5. CTIMER_SetupPwmPeriod(CTIMER, kCTIMER_Match_2, kCTIMER_Match_1, g_pwmPeriod, g_pulsePeriod , false); 6. CTIMER_StartTimer(CTIMER); 测试结果正常。 以上为NXP提供的例程中的Ctimer的PWM输出的例子,咱们将在一个空白的工程从0开始创建PWM输出。 二、从零配置Ctimer的PWM输出 1、添加外设 点击“Peripheral drivers”旁边的“+”,选择“Ctimer”,最后确定创建一个外设; 想要得到PWM,分别需要配置定时器和通道信息; 我们看到了一个警告信息,定时器通道没有关联对应的引脚,这种情况我们可以通右键这个警告信息,可以快速进行问题处理: 选择想要关联的引脚就可以了,非常方便。 没有错误以及警告后,更新源代码就可以了,到这里我们就创建了新的外设,以及相关的引脚配置。 2、在主程序中填写如下代码: 1. srcClock_Hz = CLOCK_GetCTimerClkFreq(0U); 2. PRINTF("srcClock_Hz: %d\n",srcClock_Hz); 3. timerClock = 2000000; 4. /* Get the PWM period match value and pulse width match value of 20Khz PWM signal with 20% dutycycle */ 5. CTIMER_GetPwmPeriodValue(20000, 20, timerClock); 6. CTIMER_SetupPwmPeriod(CTIMER0, kCTIMER_Match_3, kCTIMER_Match_0, g_pwmPeriod, g_pulsePeriod, false); 7. CTIMER_StartTimer(CTIMER0); 单路PWM输出效果如下: 在本次的CTimer产生PWM的测试中,主要关注的数据是定时器中的prescaler参数(实际),PWM的pwmPeriod和pulsePeriod,其中定时器中的prescaler要设定的远大于pwmPeriod,理论上越大精度越高。三者关系如下: 1. timerClock_Hz = srcClock_Hz/(prescaler + 1U); 2. /* Calculate PWM period match value */ 3. pwmPeriod = (timerClock_Hz / pwmFreqHz) - 1U; 4. 5. /* Calculate pulse width match value */ 6. pulsePeriod = (pwmPeriod + 1U) * (100 - dutyCyclePercent) / 100; 接下来再加一路: 添加代码如下: 1. CTIMER_GetPwmPeriodValue(20000, 50, timerClock); 2. CTIMER_SetupPwmPeriod(CTIMER0, kCTIMER_Match_2, kCTIMER_Match_1, g_pwmPeriod, g_pulsePeriod, false); 注意两路的的目标频率要一致。 效果如下: 这里可以看到Ctimer输出的双路是边沿对齐的。
|