输出PWM如果需要动态的修改PWM频率,配置不当会导致PWM波形有一段时间无输出的情况。
正确的配置如下。拿PWM1模块举例。
1.初始化PWM1
- void PWM1_GenerateFrequency(void)
- {
- uint16_t preScaler = 0,channelValue;
- float duty = 0;
- /*
- 初始化PWM模块为边沿对齐(PWM_PWMMODE_EDGEALLIGNED),高有效(PWM_PWM_HIGHTRUEPULSE)
- 输出模式有三种配置模式:
- 1. EPWM(边沿对齐)模式 PWM_PWMMODE_EDGEALLIGNED
- EPWM(边沿对齐) 周期由MCVR - CNTIN + 1确定,占空比由CHnV - CNTIN确定
- 边沿对齐PWM频率的计算公式 = PWM时钟频率 / (PWM计数器的模数值 - CNTIN + 1) / (PWM时钟分频值 + 1)
- freqValue = CLK / (MOD_PWM - CNTIN+ 1) / (PRESCALER_PWM + 1)
- 备注:默认CNTIN为0,如果没有特意去设置CNTIN值,计时公式可简写为:
- freqValue = CLK / (MOD_PWM + 1) / (PRESCALER_PWM + 1)
- 2.CPWM(中心对齐)模式 PWM_PWMMODE_CENTERALLIGNED
- CPWM(中心对齐) 周期由2x(MCVR - CNTIN)确定,占空比由2x(CHnV - CNTIN)确定。MCVR必须保持在0x0001至0x7FFF范围内。
- 中心对齐PWM频率的计算公式 = (PWM时钟频率 / (PWM计数器的模数值 - CNTIN + 1) / (PWM时钟分频值 + 1)) / 2
- freqValue = CLK / (MOD_PWM - CNTIN+ 1) / (PRESCALER_PWM + 1) / 2
- 3.Combine模式 PWM_PWMMODE_COMBINE
- 组合模式周期由(MCVR - CNTIN + 1)确定,占空比由(|CH(n+1)V - CH(n)V|)确定。
- 组合模式PWM频率的计算公式 = PWM时钟频率 / (PWM计数器的模数值 - CNTIN + 1) / (PWM时钟分频值 + 1)
- freqValue = CLK / (MOD_PWM - CNTIN + 1) / (PRESCALER_PWM + 1)
- 组合模式两个通道的输出默认为互补输出。可配置为非互补输出。如何配置?
-
- 有效极性配置:
- PWM_PWM_HIGHTRUEPULSE:高有效,如果占空比设为25%,是指的高有效电平占比25%
- PWM_PWM_LOWTRUEPULSE:低有效,如果占空比设为25%,是指的低有效电平占比25%
- */
- PWM_PWMInit(PWM1, PWM_PWMMODE_EDGEALLIGNED, PWM_PWM_HIGHTRUEPULSE);
- /*
- 设置MCVR寄存器。及设置PWM计数器的模数值。当PWM计数值达到MCVR值后,
- 溢出标志(CNTOF)在下一个时钟置起,计数器的下一个值取决于所选的计数方法。
- */
- PWM_SetModValue(PWM1, MOD_PWM);
- // 占空比计算方式
- /*
- 注意:如下计算方式仅限于边沿对齐和中心对齐模式,组合模式的占空比由(|CH(n+1)V - CH(n)V|)确定。
- */
- duty = 0.25; //25%占空比
- channelValue = (MOD_PWM +1) * duty;//
- //设置CH0占空比
- PWM_SetChannelValue(PWM1, PWM_CHANNEL_CHANNEL0, channelValue);
- duty = 0.60; //60%占空比
- channelValue = (MOD_PWM +1) * duty;//
- //设置CH1占空比
- PWM_SetChannelValue(PWM1, PWM_CHANNEL_CHANNEL1, channelValue);
- preScaler = (APB_CLK / (MOD_PWM + 1) / FREQ) - 1;
- PWM_ClockSet(PWM1, 1, preScaler);
- }
2.配置同步寄存器
- void setPWM1SyncMode(void)
- {
- PWM_SetPWMEnhanced(PWM1);
- PWM1->MODESEL |= PWM_MODESEL_PAIR0SYNCEN_Msk ; //对应通道同步使能
- PWM1->SYNCONF |= PWM_SYNCONF_SWVSWSYNC_Msk | PWM_SYNCONF_SYNCMODE_Msk | PWM_SYNCONF_SWOC_Msk;
- PWM1->SYNC |= PWM_SYNC_MAXSYNCP_Msk;//加载点为PWM计数器达到其最大值(MCVR 寄存器)时。
- PWM1->SYNCONF |= PWM_SYNCONF_OMVSWSYNC_Msk | PWM_SYNCONF_SYNCMODE_Msk ;
- PWM1->SYNCONF |= PWM_SYNCONF_CNTVSWSYNC_Msk | PWM_SYNCONF_PWMSVSWSYNC_Msk; ////SW Trig MCVR and CHnV
- }
3.修改MOD和CHnV后触发软件同步
- void testFreq(void)
- {
- mdelay(1);
- PWM_SetModValue(PWM1, 99);
- PWM_SetChannelValue(PWM1, PWM_CHANNEL_CHANNEL1, 50);
- PWM_SoftwareSync(PWM1);
- mdelay(1);
- PWM_SetModValue(PWM1, 999);
- PWM_SetChannelValue(PWM1, PWM_CHANNEL_CHANNEL1, 500);
- PWM_SoftwareSync(PWM1);
- }
4.测试代码
- int main(void)
- {
- InitDebug();
- InitDelay();
- printf("\nRunning the PWM module sample code.\r\n");
- PWM_GpioInit();
- PWM1_GenerateFrequency();
- setPWM1SyncMode();
- while (1)
- {
- testFreq();
-
- }
- }
|