CH573 PWM 疑问

关于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机制异常。      如果无法避免,那是否需要手动增加一次中断计数。


另外,其他如定时器中断,是否有关系。 


继续请求帮助:

  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


这个代码在正常的时候,验证了波形有明显的改善。


事实上,程序会出现死机,R32_TMR3_COUNT这个值一直保持在一个异常数据状态,数值为0X8E2317FD.   不再增加计数。

理论上计数值最高位始终是0. 

在这个过程中,是否有概率出现跨过计数周期,而没有清零计数的可能。

在计数从0开始的时候,FIFO更新,但没有生效。  随后更新了周期。  这个时候占空比采用上周期的值,而周期已经更新。如果占空比>周期,是否会发生上诉死机问题?

内部的比较是否必须先达到占空比值



只有登录才能回复,可以选择微信账号登录