关于PWM,使用主定时器产生,并在每秒定时器中进行周期和占空比的修改。 目前发现在每秒修改的时候,即使周期和占空比数据不变,输出的波形也会变化。
需要确认的是,在定时器关闭,更新占空比后,再开启。计数值是继续还是从0开始?
我是否需要在关闭的时候,先获取计数值,再在更新占空比后,讲计数值写回,再开启定时器。
这样是否可以从上次继续。
同时关闭开启是否保持之前电平,是否需要检查电平,在和初始电平一致的时候,进行改写?
有没有建议?
关于PWM,使用主定时器产生,并在每秒定时器中进行周期和占空比的修改。 目前发现在每秒修改的时候,即使周期和占空比数据不变,输出的波形也会变化。
需要确认的是,在定时器关闭,更新占空比后,再开启。计数值是继续还是从0开始?
我是否需要在关闭的时候,先获取计数值,再在更新占空比后,讲计数值写回,再开启定时器。
这样是否可以从上次继续。
同时关闭开启是否保持之前电平,是否需要检查电平,在和初始电平一致的时候,进行改写?
有没有建议?
进一步测试:
尝试改写周期的时候。我先将原周期和当前计数值读取到全局变量, 随后根据新的周期值,等比例缩放计数值。
将新周期和缩放的计数值写入定时器,目的是让PWM在原来为完成的波形继续输出。 但是实际测试,重开后,PWM从0开始,计数值感觉没有被写入。
PWMPeriod_OLD=R32_TMR3_CNT_END; //读取当前周期
Current_Count=TMR3_GetCurrentCount(); //读取当前计数值
PWMPREIOD=Meter_PWM_Pam(Meter_Imp_const3,TempPower); //计数新周期
TMR3_PWMCycleCfg( PWMPREIOD ); //写新周期
NEW_PWM_COUNT=PWMPREIOD;
NEW_PWM_COUNT=NEW_PWM_COUNT*Current_Count/PWMPeriod_OLD;//根据周期,等比例缩放计数值,保持剩余计数在周期的中占比不变
TMR3_Disable();
R32_TMR3_COUNT=NEW_PWM_COUNT; //更新计数值
TMR3_PWMActDataWidth( PWMPREIOD/2 ); // 占空比 50%, 修改占空比必须暂时关闭定时器
TMR3_Enable();
R32_TMR3_COUNT=NEW_PWM_COUNT; //更新计数值
感觉这语句没有效果。 是否这个寄存器无法写入。开启后,默认从0开始计数
尝试赋值计数,放在开启定时器后,马上改写,也是不行。
询问专家,是否无法改变这个当前计数值这个寄存器? 因为在之前其他M0中可以实现这个功能。
否则在每次改写周期的时候,会有一个明细的宽度加长。
定时器关闭,再开启, 定时器cnt值从0开始;
更新定时器的周期(period) 建议在定时器的CNT 刚过0时候更新,
如果同时更新占空比(dutycycle),需要先更新占空比(dutycycle),再更新周期(period)
因为占用比的更新,是写fifo,fifo只有当定时器从0 开始时候,才会被加载进去,
这意味着, 可以这样去更新占空比,和周期,这样可以大大避免切换时候引起的抖动:
uint32_t period= should_set; uint32_t dutycycle= period/2; while(R32_TMR3_COUNT>20); //wait if timer cnt > 20 TMR3_PWMActDataWidth(dutycycle); //update dutycycle to fifo while(R32_TMR3_COUNT<21); //wait while(R32_TMR3_COUNT>20); //wait if timer cnt > 20 TMR3_PWMCycleCfg(period); //update period
另外注意:
1,上诉代码加入放在ram中运行会比放在flash中 抖动弱;
2,原则上,上述代码不可被打断;
这个代码是放在哪里?主循环中吗? 如何保证计数值可以正确发现? 主频60M, 计数20的时间很短。 会不会因为其他认为错过更新
已经理解,多谢
接着上面的问题,我按照这个方式,对周期的影响可以明显减小。
但是发现一个问题,在这个过程中,会产生一次PWM中断。而导致主循环无法进入。(感觉中断一直再进)。
我在这代码前关闭中断使能, 完成后开启中断。可以解决异常。 但是这样会丢失一次中断。
是否有什么设置方法,可以不关闭中断,而不影响。
我在初始化的时候,开启中断,周期设置为67100000
GPIOPinRemap(ENABLE,RB_PIN_TMR2);
GPIOB_ResetBits( GPIO_Pin_11 ); // 配置PWM口 PB11
GPIOB_ModeCfg( GPIO_Pin_11, GPIO_ModeOut_PP_5mA );
TMR2_PWMInit( High_Level, PWM_Times_1 );
TMR2_ClearITFlag( TMR0_3_IT_CYC_END );
PFIC_EnableIRQ(TMR2_IRQn);
TMR2_ITCfg( ENABLE, TMR0_3_IT_CYC_END);
PWMPREIOD=67100000;
TMR2_PWMCycleCfg( PWMPREIOD );
TMR2_Disable();
TMR2_PWMActDataWidth( PWMPREIOD/2 ); // 占空比 50%, 修改占空比必须暂时关闭定时器
TMR2_Enable();
最后在每秒钟更新:更新周期调试下,为31304
PWMPREIOD=31304;
Width_PWM=PWMPREIOD/2;
// PFIC_DisableIRQ(TMR2_IRQn);
while(R32_TMR2_COUNT>20); //wait if timer cnt > 20
TMR2_PWMActDataWidth(Width_PWM); //update dutycycle to fifo
while(R32_TMR2_COUNT<21); //wait
while(R32_TMR2_COUNT>20); //wait if timer cnt > 20
TMR2_PWMCycleCfg(PWMPREIOD); //update period
// PFIC_EnableIRQ(TMR2_IRQn);
在进入这个代码后,主循环每秒点灯不亮。
再关闭中断使能后,可以正常工作。
从原理上,在这个代码过程中,会产生PWM中断,是否因为中断导致了整个PWM机制异常。 如果无法避免,那是否需要手动增加一次中断计数。
另外,其他如定时器中断,是否有关系。
继续请求帮助:
这个代码在正常的时候,验证了波形有明显的改善。
事实上,程序会出现死机,R32_TMR3_COUNT这个值一直保持在一个异常数据状态,数值为0X8E2317FD. 不再增加计数。
理论上计数值最高位始终是0.
在这个过程中,是否有概率出现跨过计数周期,而没有清零计数的可能。
在计数从0开始的时候,FIFO更新,但没有生效。 随后更新了周期。 这个时候占空比采用上周期的值,而周期已经更新。如果占空比>周期,是否会发生上诉死机问题?
内部的比较是否必须先达到占空比值