yellow555 发表于 2023-4-26 16:20

关于HC32F460 输出可调占空比PWM波遇到的问题记录

问题记录

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

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



yellow555 发表于 2023-4-26 16:24

用示波器抓取波形,这是正常状态下的波形(上电默认配置成5kHz,70%占空比输出)

yellow555 发表于 2023-4-26 16:25

这是转速较小时的波形输出


yellow555 发表于 2023-4-26 16:25

翻看用户手册,并没有找到有用的信息。
代码是直接参考官方例程 timera_triangular_wave_compare_output 写的,计数模式同样也是三角波计数模式。

yellow555 发表于 2023-4-26 16:25

下面是代码关于这部分的初始化:
static void Timera_Config(void)
{
    stc_timera_base_init_t stcTimeraInit;
    stc_timera_compare_init_t stcTimerCompareInit;
    stc_irq_regi_conf_t stcIrqRegiConf;
    stc_timera_hw_startup_config_t stcTimeraHwConfig;
    stc_port_init_t stcPortInit;

    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcTimeraInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(stcTimerCompareInit);
    MEM_ZERO_STRUCT(stcTimeraHwConfig);
    MEM_ZERO_STRUCT(stcPortInit);

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

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

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

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

yellow555 发表于 2023-4-26 16:26

初始化后,外部再通过定时器和PWM的输出使能位来控制电机的开启和关闭


yellow555 发表于 2023-4-26 16:27

库函数调用TIMERA_CompareCmd(TIMERA_UNIT1, TIMERA_UNIT1_CH4, Enable);
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

将PWM输出的计数模式从原先的三角波计数模式改为锯齿波计数模式后,重复测试,问题没有再复现

yellow555 发表于 2023-4-26 16:29

最后代码修改如下:/**
*******************************************************************************
** \brief Configure Timera peripheral function
**
** \param None
**
** \retval None
**
******************************************************************************/
static void Timera_Config(void)
{
    stc_timera_base_init_t stcTimeraInit;
    stc_timera_compare_init_t stcTimerCompareInit;
    stc_irq_regi_conf_t stcIrqRegiConf;
    stc_timera_hw_startup_config_t stcTimeraHwConfig;
    stc_port_init_t stcPortInit;

    /* configuration structure initialization */
    MEM_ZERO_STRUCT(stcTimeraInit);
    MEM_ZERO_STRUCT(stcIrqRegiConf);
    MEM_ZERO_STRUCT(stcTimerCompareInit);
    MEM_ZERO_STRUCT(stcTimeraHwConfig);
    MEM_ZERO_STRUCT(stcPortInit);

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

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

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

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

yellow555 发表于 2023-4-26 16:29

总结

关于遇到的问题的解决方法暂时介绍到这里,至于为什么三角波计数模式下会出现占空比互补现象,个人感觉倒像是芯片本身的问题,用户手册上也找不到解释,这里也就不在深究 。

Henryko 发表于 2023-5-12 23:44

手册里应该有说明吧
页: [1]
查看完整版本: 关于HC32F460 输出可调占空比PWM波遇到的问题记录