问题记录
芯片:HC32F460系列
功能:PWM电机调速
最近产品开发,需要用到HC32的PWM输出来控制电机的转速。参考官方的例程很快就完成了相关的功能,但是,后面在测试,重复开关电机的时候,发现电机的转速时大时小。
一、问题分析
一开始,怀疑是相关寄存器的设置出错导致的问题。因此在设置PWM输出时加上LOG打印,上机测试并没有发现问题。
用示波器抓取波形,这是正常状态下的波形(上电默认配置成5kHz,70%占空比输出)
这是转速较小时的波形输出
翻看用户手册,并没有找到有用的信息。
代码是直接参考官方例程 timera_triangular_wave_compare_output 写的,计数模式同样也是三角波计数模式。
下面是代码关于这部分的初始化:
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);
}
初始化后,外部再通过定时器和PWM的输出使能位来控制电机的开启和关闭
库函数调用
TIMERA_CompareCmd(TIMERA_UNIT1, TIMERA_UNIT1_CH4, Enable);
TIMERA_Cmd(TIMERA_UNIT1, Enable);
二、解决方法
在手册上并没有找到对应的解决方法,但是我们可以从上面的两张波形图可以看到,当PWM输出出现问题时,输出的波形刚好同正常波形的占空比是互补关系。
上网百度了下HC32 PWM 输出的相关内容后,最终在21IC论坛上找到了解决方法[技术问答] hc32f460系列输出可调占空比的PWM波
将PWM输出的计数模式从原先的三角波计数模式改为锯齿波计数模式后,重复测试,问题没有再复现
最后代码修改如下:
/**
*******************************************************************************
** \brief Configure Timera peripheral function
**
** \param [in] 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);
}
总结
关于遇到的问题的解决方法暂时介绍到这里,至于为什么三角波计数模式下会出现占空比互补现象,个人感觉倒像是芯片本身的问题,用户手册上也找不到解释,这里也就不在深究 。