[方案相关] 关于HC32F460 输出可调占空比PWM波遇到的问题记录

[复制链接]
 楼主| yellow555 发表于 2023-4-26 16:20 | 显示全部楼层 |阅读模式
问题记录

芯片:HC32F460系列
功能:PWM电机调速
最近产品开发,需要用到HC32的PWM输出来控制电机的转速。参考官方的例程很快就完成了相关的功能,但是,后面在测试,重复开关电机的时候,发现电机的转速时大时小。
一、问题分析

一开始,怀疑是相关寄存器的设置出错导致的问题。因此在设置PWM输出时加上LOG打印,上机测试并没有发现问题。

342936448dec67ac9b.png

评论

———————————————— 版权声明:本文为CSDN博主「Top0_0lll」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_39597546/article/details/121661981  发表于 2023-4-26 16:20
 楼主| yellow555 发表于 2023-4-26 16:24 | 显示全部楼层
用示波器抓取波形,这是正常状态下的波形(上电默认配置成5kHz,70%占空比输出)
QQ截图20230426162352.jpg
 楼主| yellow555 发表于 2023-4-26 16:25 | 显示全部楼层
这是转速较小时的波形输出
QQ截图20230426162437.jpg

 楼主| yellow555 发表于 2023-4-26 16:25 | 显示全部楼层
翻看用户手册,并没有找到有用的信息。
代码是直接参考官方例程 timera_triangular_wave_compare_output 写的,计数模式同样也是三角波计数模式。
 楼主| yellow555 发表于 2023-4-26 16:25 | 显示全部楼层
下面是代码关于这部分的初始化:
  1. static void Timera_Config(void)
  2. {
  3.     stc_timera_base_init_t stcTimeraInit;
  4.     stc_timera_compare_init_t stcTimerCompareInit;
  5.     stc_irq_regi_conf_t stcIrqRegiConf;
  6.     stc_timera_hw_startup_config_t stcTimeraHwConfig;
  7.     stc_port_init_t stcPortInit;

  8.     /* configuration structure initialization */
  9.     MEM_ZERO_STRUCT(stcTimeraInit);
  10.     MEM_ZERO_STRUCT(stcIrqRegiConf);
  11.     MEM_ZERO_STRUCT(stcTimerCompareInit);
  12.     MEM_ZERO_STRUCT(stcTimeraHwConfig);
  13.     MEM_ZERO_STRUCT(stcPortInit);

  14.     /* Configuration peripheral clock */
  15.     PWC_Fcg2PeriphClockCmd(TIMERA_UNIT1_CLOCK, Enable);

  16.     /* Configuration TIMERA compare pin */
  17.     PORT_SetFunc(TIMERA_UNIT1_CH4_PORT, TIMERA_UNIT1_CH4_PIN, TIMERA_UNIT1_CH4_FUNC, Disable);

  18.     /* Configuration timera unit 1 base structure */
  19.     stcTimeraInit.enClkDiv = TimeraPclkDiv32;
  20.     stcTimeraInit.enCntMode = TimeraCountModeTriangularWave;
  21.     stcTimeraInit.enCntDir = TimeraCountDirUp;
  22.     stcTimeraInit.enSyncStartupEn = Disable;
  23.     stcTimeraInit.u16PeriodVal = 0x106u;                //freq:5kHz
  24.     TIMERA_BaseInit(TIMERA_UNIT1, &stcTimeraInit);

  25.     /* Configuration timera unit 1 compare structure */
  26.     stcTimerCompareInit.u16CompareVal = stcTimeraInit.u16PeriodVal * 3u / 10u;        //占空比70%
  27.     stcTimerCompareInit.enStartCountOutput = TimeraCountStartOutputLow;
  28.     stcTimerCompareInit.enStopCountOutput = TimeraCountStopOutputLow;
  29.     stcTimerCompareInit.enCompareMatchOutput = TimeraCompareMatchOutputReverse;
  30.     stcTimerCompareInit.enPeriodMatchOutput = TimeraPeriodMatchOutputKeep;
  31.     stcTimerCompareInit.enSpecifyOutput = TimeraSpecifyOutputInvalid;        //该寄存器可用于实现PWM输出占空比0%或100%
  32.     /* Configure Channel 1 */
  33.     TIMERA_CompareInit(TIMERA_UNIT1, TIMERA_UNIT1_CH4, &stcTimerCompareInit);
  34.        
  35.     TIMERA_CompareCmd(TIMERA_UNIT1, TIMERA_UNIT1_CH4, Disable);
  36.         TIMERA_Cmd(TIMERA_UNIT1, Disable);
  37. }

 楼主| yellow555 发表于 2023-4-26 16:26 | 显示全部楼层
初始化后,外部再通过定时器和PWM的输出使能位来控制电机的开启和关闭

QQ截图20230426162613.jpg
QQ截图20230426162613.jpg
 楼主| yellow555 发表于 2023-4-26 16:27 | 显示全部楼层
库函数调用
  1. TIMERA_CompareCmd(TIMERA_UNIT1, TIMERA_UNIT1_CH4, Enable);
  2. TIMERA_Cmd(TIMERA_UNIT1, Enable);
 楼主| yellow555 发表于 2023-4-26 16:27 | 显示全部楼层
二、解决方法

在手册上并没有找到对应的解决方法,但是我们可以从上面的两张波形图可以看到,当PWM输出出现问题时,输出的波形刚好同正常波形的占空比是互补关系。
上网百度了下HC32 PWM 输出的相关内容后,最终在21IC论坛上找到了解决方法[技术问答] hc32f460系列输出可调占空比的PWM波
 楼主| yellow555 发表于 2023-4-26 16:28 | 显示全部楼层
 楼主| yellow555 发表于 2023-4-26 16:29 | 显示全部楼层
QQ截图20230426162853.jpg 将PWM输出的计数模式从原先的三角波计数模式改为锯齿波计数模式后,重复测试,问题没有再复现
 楼主| yellow555 发表于 2023-4-26 16:29 | 显示全部楼层
最后代码修改如下:
  1. /**
  2. *******************************************************************************
  3. ** \brief Configure Timera peripheral function
  4. **
  5. ** \param [in] None
  6. **
  7. ** \retval None
  8. **
  9. ******************************************************************************/
  10. static void Timera_Config(void)
  11. {
  12.     stc_timera_base_init_t stcTimeraInit;
  13.     stc_timera_compare_init_t stcTimerCompareInit;
  14.     stc_irq_regi_conf_t stcIrqRegiConf;
  15.     stc_timera_hw_startup_config_t stcTimeraHwConfig;
  16.     stc_port_init_t stcPortInit;

  17.     /* configuration structure initialization */
  18.     MEM_ZERO_STRUCT(stcTimeraInit);
  19.     MEM_ZERO_STRUCT(stcIrqRegiConf);
  20.     MEM_ZERO_STRUCT(stcTimerCompareInit);
  21.     MEM_ZERO_STRUCT(stcTimeraHwConfig);
  22.     MEM_ZERO_STRUCT(stcPortInit);

  23.     /* Configuration peripheral clock */
  24.     PWC_Fcg2PeriphClockCmd(TIMERA_UNIT1_CLOCK, Enable);

  25.     /* Configuration TIMERA compare pin */
  26.     PORT_SetFunc(TIMERA_UNIT1_CH4_PORT, TIMERA_UNIT1_CH4_PIN, TIMERA_UNIT1_CH4_FUNC, Disable);

  27.     /* Configuration timera unit 1 base structure */
  28.     stcTimeraInit.enClkDiv = TimeraPclkDiv32;
  29.     stcTimeraInit.enCntMode = TimeraCountModeSawtoothWave;//TimeraCountModeTriangularWave;
  30.     stcTimeraInit.enCntDir = TimeraCountDirUp;
  31.     stcTimeraInit.enSyncStartupEn = Disable;
  32.     stcTimeraInit.u16PeriodVal = 0x20Cu;                //freq:5kHz                //0xCD0u;        //freq: 100Hz
  33.     TIMERA_BaseInit(TIMERA_UNIT1, &stcTimeraInit);

  34.     /* Configuration timera unit 1 compare structure */
  35.     stcTimerCompareInit.u16CompareVal = stcTimeraInit.u16PeriodVal * 3u / 10u;        //占空比70%
  36.     stcTimerCompareInit.enStartCountOutput = TimeraCountStartOutputLow;
  37.     stcTimerCompareInit.enStopCountOutput = TimeraCountStopOutputLow;
  38.     stcTimerCompareInit.enCompareMatchOutput = TimeraCompareMatchOutputHigh;//TimeraCompareMatchOutputReverse;
  39.     stcTimerCompareInit.enPeriodMatchOutput = TimeraCompareMatchOutputLow;//TimeraPeriodMatchOutputKeep;
  40.     stcTimerCompareInit.enSpecifyOutput = TimeraSpecifyOutputInvalid;        //该寄存器可用于实现PWM输出占空比0%或100%
  41.     stcTimerCompareInit.enCacheEn = Enable;
  42.     stcTimerCompareInit.enTriangularTroughTransEn = Enable;
  43.     stcTimerCompareInit.enTriangularCrestTransEn = Disable;
  44.     stcTimerCompareInit.u16CompareCacheVal = stcTimerCompareInit.u16CompareVal;
  45.     /* Configure Channel 1 */
  46.     TIMERA_CompareInit(TIMERA_UNIT1, TIMERA_UNIT1_CH4, &stcTimerCompareInit);
  47.        
  48.     TIMERA_CompareCmd(TIMERA_UNIT1, TIMERA_UNIT1_CH4, Disable);
  49.         TIMERA_Cmd(TIMERA_UNIT1, Disable);
  50. }

 楼主| yellow555 发表于 2023-4-26 16:29 | 显示全部楼层
总结

关于遇到的问题的解决方法暂时介绍到这里,至于为什么三角波计数模式下会出现占空比互补现象,个人感觉倒像是芯片本身的问题,用户手册上也找不到解释,这里也就不在深究 。
Henryko 发表于 2023-5-12 23:44 | 显示全部楼层
手册里应该有说明吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

40

主题

469

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部