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