SRPWM和ACMP的Blanking应用指南
文档编号:AN0009
功能说明
Blanking直译即为消隐。在ET600X系列中,不同外设对Blanking功能的定义有所区别,需要根据对应模块,使用Blanking功能。
SRPWM的Blanking
本文SRPWM的Blanking位于FPP(异常信号预处理)单元内。功能定义为:Blanking区间指产生一个数据处理有效区域,只处理该区域内出现的fault信号,在有效区域之外的fault信号将被忽略,不做处理,即在这个区间内,才会根据配置项对传入的异常信号做相应的处理。以下为Blanking的F PP单元在外设中的位置。
Blanking对传入FPP单元的异常信号做可选处理。在ET600X系列中,FPP可以接收来自XBAR的6bit的信号,可以理解为接收来自外部的6种信号。我们可以对输入的6种信号全部做Blanking配置,也可以对部分信号做Blanking配置。Blanking支持以下配置:
开始时刻选择
结束时刻选择
开始时刻延时
结束时刻延时
Blanking功能是否开启
Blanking模式选择
SRPWM_FPP_BLK_MODE_NONE:无Blanking
SRPWM_FPP_BLK_MODE_NORMAL:普通Blanking
SRPWM_FPP_BLK_MODE_LATCH:锁存Blanking
SRPWM_FPP_BLK_MODE_RESERVE:预留
通过开始时刻和结束时刻的选择,我们可以构建出一个blanking区域。ET600X的开始时刻和结束时刻提供了多种事件可选,具体可选的事件可以在对应的用户手册、寄存器手册或者在SDK驱动库中找到。根据实际场景的需要,我们可以选择对Blanking区域的开始和结束时刻做延时配置,实际的Blanking区 域将对应移相。
注意
如果Blanking模式选择了普通Blanking或者锁存Blanking模式,那么Blanking功能必须选择使能,相应的配置才会生效。
配置的blanking窗口实际上有2clk的滞后,该情况的应用,将在后文描述。
普通Blanking
指只处理blanking区间以内出现的Fault信号,区域之外的信号忽略,如下图所示:
锁存Blanking
指在Blanking区域产生之前如果出现过一次或者多次Fault脉冲信号,即将会锁存第一次出现的fault信号,直到Blanking有效区域出现之后,并将此锁存信号当做在Blanking区域内出现的Fault信号处理,同时,这个锁存信号会在blanking起始时刻开 始出现1个clk的时间之后便会消失。如下图所示:
ACMP的Blanking
ET600X的ACMP支持对输出的比较结果做Blanking消隐处理。
ACMP的Blanking功能定义:在该Blanking区域内无视输出结果,即在该区域内,如果产生比较结果,将不会作为有效输出。
ACMP的模拟DAC电平转换时,会在触发时刻点产生不稳定状态,所以需要根据实际情况进行Blanking处理,把不稳定状态过滤掉。具体时序图如下:
由软件配置Blanking消隐使能信号,若使能,消隐源触发会产生消隐脉冲,同时消隐脉冲的脉冲宽度还可以进行展宽;若不使能,消隐源触发不会产生消隐脉冲。
ACMP的比较结果,在Blanking窗口之后,将会送外其他模块。例如送外XBAR模块的输入,再由XBAR模块的PFXB子单元作为输出,送外SRPWM进行封波处理。
场景应用
在PCM峰值电流型场景应用中,可能会有Blanking的使用需求,同时结合上述章节注意事项中,SRPWM的Blanking窗口实际滞后2clk的情况,进行说明。
波形产生需求
从图中可以看到,我们需要的波形配置为:
时基计数方向为:向上计数
过零事件置高PWM
异常信号POS置低PWM。
本文将假设使用ACMP的内部Ramp波作为负端和外部输入的信号作为ACMP的正端比较,从而产生比较结果送外SRPWM作为异常信号POS。
异常信号的有效区间管理需求
显然,如果是互补死区配置的波形,作为PWM脉冲置低的异常信号POS事件和过零事件的事件间隔应该大于死区宽度,否则会导致高电平脉宽过小,高电平完全被死区“吃掉”,最终没有该电平输出的情形。
此外,在PWM置高后可能出现短时间的电流谐波,此时模拟比较器的输出结果不可用,用于置低PWM的异常信号POS事件也应该避开此时段。
提示
产生波形置低PWM的异常信号POS事件和下一周期置高PWM的事件不应靠近。因为异常信号POS的产生存在事件延迟,可能导致该事件与下一个周期的置高事件重叠或出现在其后,造成无法正常产生异常信号POS事件的PG动作波形。其根本原因:在PG动作事件中,异常信号POS的优先级通常高于其他动作事件的优先级。即 因为动作事件优先级的存在,在实际应用当中,需要考虑到各动作事件之间的间隔。
基于上述原因,需要对异常信号POS事件做有效区间管理。从前述章节可以看出,具备两种方案实现。
方案一:采用SRPWM的Blanking实现
在SRPWM模块中建立有效区间,仅有效区间内出现的事件用于PWM的波形产生
方案二:采用ACMP的Blanking实现
在ACMP内做Blanking处理,消隐掉不希望用于SRPWM模块的比较结果
采用SRPWM的Blanking实现
在本文描述的场景中,可选用两个不同的比较事件构成Blanking窗口。
Blanking开始时刻 – SCMPA从比较A事件
Blanking结束时刻 – SCMPB从比较B事件
Blanking有效区间的开始时刻只需满足大于死区宽度,且避开PWM波打开后的谐波振荡时间即可,在此不再赘述。重点在于Blanking的结束时刻选择。
从Blanking有效区间结束时刻出现到blanking真正结束有2个SRPWM时钟的延迟。因此,当前PWM周期内的Blanking结束时刻应至少提前与下个PWM周期的相反电平动作触发事件3个PWM时钟。下图为时序关系:
若Blanking的结束事件未提前于下个周期PWM置高3clk及以上,将会出现异常信号POS事件和过零事件在时间上的重合,由于异常信号POS事件的动作优先级高于过零事件,导致PWM波无法正常拉高,在下一个周期,则会出现丢波现象。
下图为丢波现象的时序:
若Blanking的结束事件选择更靠近过零事件,比如选择周期事件作为Blanking的结束触发,则可能出现完全丢波或只产生一个clk周期PWM波的异常(5ns的窄脉冲可能会无法通过GPIO输出或者受示波器分辨率影响,出现完全丢波的现象)。
采用ACMP的Blanking实现
利用ACMP模块的Blanking功能,也可以对异常信号做有效区间管理。
下图给出了SRPWM模块和模拟比较器ACMP模块的通道连接关系。在不影响信号时序分析的前提下,图中ACMP模块中的信号处理链路做了简化示意,主要展示模拟比较结果经过消隐处理的过程。
如图所示,ACMP经过取反以及同步处理之后产生acmp_result,然后与Blanking窗口的blank_sig做相与运算后完成消隐功能产生最终的比较结果cmp_ctrip信号送往XBAR,再送外SRPWM模块,最终经过SRPWM的FPP模块后,用于SRPWM的其他功能单元.
ACMP的Blanking不能配置起始和结束时刻,只能配置窗口,并且需要被触发才能产生,本文的场景中,可以选择SRPWM模块提供的触发信号进行ACMP的Blanking触发(ACMP的Blanking触发固定为SRPWM的触发信号),从而决定了ACMP的Blanking起始时刻。
若以SRPWM的时基计数比较事件作为ACMP消隐窗口的触发信号,从时基计数比较事件出现到ACMP消隐窗口生效,有2个clk时钟周期的延迟,结合送往XBAR以及SRPWM产生异常信号上升沿的链路延时,一共需要至少4个clk的延迟,为了避免PG动作事件之间优先级的冲突,触发ACMP消隐窗口的PWM时基计 数比较事件应至少提前于下个PWM周期的相反电平的动作事件4个时钟周期及以上。下图展示了该时序关系:
若触发ACMP消隐窗口的PWM时基计数比较事件未提前于下个PWM周期的相反电平的动作事件4个时钟周期及以上,将会导致PG动作事件优先级冲突,从而出现丢波现象。如下图所示:
代码应用
通过上述章节的说明,我们可以看到,本文的示例场景可以通过ACMP和SRPWM模块各自定义的Blanking功能单元实现。
本章节将会以ET6002芯片作为演示,通过代码示例的方式,给出具体的配置。
SRPWM方案
通过ACMP模块的比较结果作为异常信号,并输出给XBAR,再通过XBAR输出给SRPWM进行作为PG动作事件置低PWM
代码分成3部分进行:ACMP配置、XBAR配置、SRPWM配置,需包含各自驱动的头文件。
ACMP配置
将GPIO0_15配置为输入,并作为XBAR的信号输入。
/**
* @brief 配置ACMP。将ACMP2_H的输出作为异常信号源
*
*/
void ACMP_Config(void)
{
ACMP_Comparator init;
ACMP_DAC_Config config;
/* init parameter structure */
init.digitalOutputPolarityReverseEn = DISABLE;
init.analogOutputPolarityReverseEn = DISABLE;
/* async path output disable */
init.asyncPathEn = DISABLE;
/* select BDAC as positive input */
init.cmpPositiveInputSelect = ACMP_INPUT_MUX_SELECT_0; /* select B2_C6*/
/* select internal DAC as negative input */
init.cmpNegativeInputSelect = ACMP_REF_MUX_DAC;
/* set init parameter to register */
ACMP_configComparator(ACMP2, ACMP_CHANNEL_H, &init);
/* set hysteresis value */
ACMP_setHysteresis(ACMP2, ACMP_CHANNEL_H, HYSTERESIS_VALUE_62MV, ACMP_HYST_RISING);
/* set cDAC value load mode */
config.loadMode = ACMP_DAC_LOADMODE_SHADOW;
config.triggerMask = UNMASKED;
config.triggerInvertEn = DISABLE;
config.triggerEn = ENABLE;
/* select cDAC value trigger */
config.triggerSel = ACMP_DAC_TRIGGER_SEL_SRPWM;
/* set trigger delay to MAX value, to generate normal wave */
config.triggerDelay = 0U;
config.outputFormat = ACMP_DAC_OUTPUT_DIRECT;
config.dacOutputReverseEn = DISABLE;
config.dacHsrcSel = ACMP_DAC_H_RAMP_OUTPUT;
config.tdatSel = ACMP_DAC_TDAT_EXTERNAL;
config.dacRefSelect = ACMP_DACREF_VDDA;
config.dacToCmpEn = ENABLE;
/* set init parameter to register */
ACMP_configDAC(ACMP2, ACMP_CHANNEL_H, &config);
ACMP_configureSyncSource(ACMP2, ACMP_CHANNEL_H, ACMP_DAC_TRIGGER_SEL_SRPWM);
ACMP_setRampClkPrescale(ACMP2, 1);
ACMP_configRamp(ACMP2, (3011<< (4UL)), (1<< (4UL)), 0);
/* enable comparator */
ACMP_enableModule(ACMP2, ACMP_CHANNEL_H);
/* init parameter structure */
init.digitalOutputPolarityReverseEn = DISABLE;
init.analogOutputPolarityReverseEn = DISABLE;
/* async path output disable */
init.asyncPathEn = DISABLE;
/* select BDAC as positive input */
init.cmpPositiveInputSelect = ACMP_INPUT_MUX_SELECT_4; /* select B0_C11*/
/* select internal DAC as negative input */
init.cmpNegativeInputSelect = ACMP_REF_MUX_DAC;
/* set init parameter to register */
ACMP_configComparator(ACMP1, ACMP_CHANNEL_L, &init);
/* set hysteresis value */
ACMP_setHysteresis(ACMP1, ACMP_CHANNEL_L, HYSTERESIS_VALUE_7MV, ACMP_HYST_RISING);
}
XBAR的配置
作为一个中转,将ACMP2_H的比较结果送往SRPWM,同时送往XBAR_OUT作为比较结果的实际观测
/**
* @brief 配置XBAR
*
*/
void XBAR_Config(void)
{
IOC_Init_TypeDef Init;
/* IO mux配置 */
GPIO_initPadConfigStruct(&Init);
Init.ds = IOC_DS_LEVEL_0;
Init.pull = IOC_PULL_NONE;
GPIO_setPadConfig(GPIO34, &Init);
GPIO_setPinConfig(GPIO34, GPIO34_MODE_OUTXBAR0);
XBAR_OutCfg_TypeDef outputCfg;
XBAR_InChMsk_TypeDef inputChMsk;
_XBAR_REG_WR_UNLOCK();
/* 1. input channel configure */
XBAR_initInputChMsk(&inputChMsk);
XBAR_addInputSource(&inputChMsk, PFXB_SRC_MUX04_CMP_EVT4);
outputCfg.outDsel = XBAR_DSEL_MUX_OUT;
outputCfg.outOEmode = XBAR_OPXB_OEMOD_VALID;
outputCfg.outPolarInvertEn = DISABLE;
outputCfg.outPulseStretchEn = DISABLE;
XBAR_PFXB_initOutputChannel(&outputCfg, BIT_MASK(0));
XBAR_PFXB_setMuxConfig(BIT_MASK(0), &inputChMsk);
XBAR_PFXB_enableOutputMux(BIT_MASK(0));
XBAR_OPXB_initOutputChannel(&outputCfg, BIT_MASK(0));
XBAR_OPXB_setMuxConfig(BIT_MASK(0), &inputChMsk);
XBAR_OPXB_enableOutputMux(BIT_MASK(0));
_XBAR_REG_WR_LOCK();
}
SRPWM的配置
将SRPWM0的过零事件置高PWM,异常信号POS2置低PWM。
注意
这个异常信号POS2的来源,是和FPXB输出的通道0对应。ET600X系列中的对应关系可能有所区别,具体可参考对应的用户手册。
/**
* @brief 配置SRPWM
*
*/
void SRPWM_Config(void)
{
#define EPWM0_TIMER_TBPRD 10000U//20K
SRPWM_TBInitTypeDef stTBInit;
SRPWM_CMPInitTypeDef stCMPInit;
SRPWM_FPPInitTypeDef stFPPInit;
IOC_Init_TypeDef Init;
/* IO mux配置 */
GPIO_initPadConfigStruct(&Init);
Init.ds = IOC_DS_LEVEL_0;
Init.pull = IOC_PULL_NONE;
GPIO_setPadConfig(GPIO30, &Init); /* PWM0_A_BAK3 mode11 GPIO2_9*/
GPIO_setPinConfig(GPIO30, GPIO30_MODE_SRPWM0_A);
/* TB初始化 */
SRPWM_initTBStruct(&stTBInit);
stTBInit.period = EPWM0_TIMER_TBPRD;
stTBInit.countMode = SRPWM_COUNTMODE_UP;
SRPWM_initTB(SRPWM0, &stTBInit);
/* CMP初始化 */
SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.scmpA = 200;
stCMPInit.scmpC = stTBInit.period - 3;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_ZERO_EVT;
SRPWM_initCMP(SRPWM0, &stCMPInit);
/* PG初始化 */
SRPWM_setPG(SRPWM0, SRPWM_A, SRPWM_PG_EVT_ZERO, SRPWM_PG_SET);
SRPWM_setPG(SRPWM0, SRPWM_A, SRPWM_PG_EVT_FPP_FAULT_POS2, SRPWM_PG_CLEAR);
/* FPP初始化 */
SRPWM_initFPPStruct(&stFPPInit);
stFPPInit.faultSigGroupMask = SRPWM_FPP_FAULT_SIG_GRP2;
stFPPInit.blkMode = SRPWM_FPP_BLK_MODE_NORMAL;
stFPPInit.blkEn = ENABLE;
stFPPInit.blkStartSigSel =SRPWM_ALLEVT_SCMPA_UP_EVT; stFPPInit.blkEndSigSel =SRPWM_ALLEVT_SCMPC_UP_EVT;
SRPWM_initFPP(SRPWM0, &stFPPInit);
/* 配置输出给ACMP的RAMP触发源 */ SRPWM_setACMPTrigger(SRPWM_CHANNEL_2, SRPWM_OUTEVT_SYNC_TIMER_SYNC0, SRPWMCOM_ACMP2_H);
/* 使能高精度旁路 */
SRPWM_enableHRPWMBypass(SRPWM0);
/* 使能指定模块 */
SRPWMCOM_enable(SRPWM_CHANNEL_0);
}
通过以上的三个外设代码配置,将可以实现本文的场景需求。
ACMP方案
通过ACMP模块的比较结果作为异常信号,并输出给XBAR,再通过XBAR输出给SRPWM进行作为PG动作事件置低PWM
代码还是分成3部分进行:ACMP配置、XBAR配置、SRPWM配置,需包含各自驱动的头文件。
ACMP配置
将GPIO0_15配置为输入,并作为XBAR的信号输入。
/**
* @brief 配置ACMP。将ACMP2_H的输出作为异常信号源
*
*/
void ACMP_Config(void)
{
ACMP_Comparator init;
ACMP_DAC_Config config;
/* init parameter structure */
init.digitalOutputPolarityReverseEn = DISABLE;
init.analogOutputPolarityReverseEn = DISABLE;
/* async path output disable */
init.asyncPathEn = DISABLE;
/* select BDAC as positive input */
init.cmpPositiveInputSelect = ACMP_INPUT_MUX_SELECT_0; /* select B2_C6*/
/* select internal DAC as negative input */
init.cmpNegativeInputSelect = ACMP_REF_MUX_DAC;
/* set init parameter to register */
ACMP_configComparator(ACMP2, ACMP_CHANNEL_H, &init);
/* set hysteresis value */
ACMP_setHysteresis(ACMP2, ACMP_CHANNEL_H, HYSTERESIS_VALUE_62MV, ACMP_HYST_RISING);
/* set cDAC value load mode */
config.loadMode = ACMP_DAC_LOADMODE_SHADOW;
config.triggerMask = UNMASKED;
config.triggerInvertEn = DISABLE;
config.triggerEn = ENABLE;
/* select cDAC value trigger */
config.triggerSel = ACMP_DAC_TRIGGER_SEL_SRPWM;
/* set trigger delay to MAX value, to generate normal wave */
config.triggerDelay = 0U;
config.outputFormat = ACMP_DAC_OUTPUT_DIRECT;
config.dacOutputReverseEn = DISABLE;
config.dacHsrcSel = ACMP_DAC_H_RAMP_OUTPUT;
config.tdatSel = ACMP_DAC_TDAT_EXTERNAL;
config.dacRefSelect = ACMP_DACREF_VDDA;
config.dacToCmpEn = ENABLE;
/* set init parameter to register */
ACMP_configDAC(ACMP2, ACMP_CHANNEL_H, &config);
ACMP_configureSyncSource(ACMP2, ACMP_CHANNEL_H, ACMP_DAC_TRIGGER_SEL_SRPWM);
ACMP_setRampClkPrescale(ACMP2, 1);
ACMP_configRamp(ACMP2, (3011<< (4UL)), (1<< (4UL)), 0);
/* 配置ACMP的Blanking窗口 */
ACMP_configBlanking(ACMP2, ACMP_CHANNEL_H, EPWM0_TIMER_TBPRD - 200, 0);
ACMP_enableBlanking(ACMP2, ACMP_CHANNEL_H);
/* enable comparator */
ACMP_enableModule(ACMP2, ACMP_CHANNEL_H);
}
XBAR的配置
作为一个中转,将ACMP2_H的比较结果送往SRPWM,同时送往XBAR_OUT作为比较结果的实际观测
/**
* @brief 配置XBAR
*
*/
void XBAR_Config(void)
{
IOC_Init_TypeDef Init;
/* IO mux配置 */
GPIO_initPadConfigStruct(&Init);
Init.ds = IOC_DS_LEVEL_0;
Init.pull = IOC_PULL_NONE;
GPIO_setPadConfig(GPIO34, &Init);
GPIO_setPinConfig(GPIO34, GPIO34_MODE_OUTXBAR0);
XBAR_OutCfg_TypeDef outputCfg;
XBAR_InChMsk_TypeDef inputChMsk;
_XBAR_REG_WR_UNLOCK();
/* 1. input channel configure */
XBAR_initInputChMsk(&inputChMsk);
XBAR_addInputSource(&inputChMsk, PFXB_SRC_MUX04_CMP_EVT4);
outputCfg.outDsel = XBAR_DSEL_MUX_OUT;
outputCfg.outOEmode = XBAR_OPXB_OEMOD_VALID;
outputCfg.outPolarInvertEn = DISABLE;
outputCfg.outPulseStretchEn = DISABLE;
XBAR_PFXB_initOutputChannel(&outputCfg, BIT_MASK(0));
XBAR_PFXB_setMuxConfig(BIT_MASK(0), &inputChMsk);
XBAR_PFXB_enableOutputMux(BIT_MASK(0));
XBAR_OPXB_initOutputChannel(&outputCfg, BIT_MASK(0));
XBAR_OPXB_setMuxConfig(BIT_MASK(0), &inputChMsk);
XBAR_OPXB_enableOutputMux(BIT_MASK(0));
_XBAR_REG_WR_LOCK();
}
SRPWM的配置
将SRPWM0的过零事件置高PWM,异常信号POS2置低PWM。
注意
这个异常信号POS2的来源,是和FPXB输出的通道0对应。ET600X系列中的对应关系可能有所区别,具体可参考对应的用户手册。
/**
* @brief 配置SRPWM
*
*/
void SRPWM_Config(void)
{
#define EPWM0_TIMER_TBPRD 10000U//20K
SRPWM_TBInitTypeDef stTBInit;
SRPWM_CMPInitTypeDef stCMPInit;
IOC_Init_TypeDef Init;
/* IO mux配置 */
GPIO_initPadConfigStruct(&Init);
Init.ds = IOC_DS_LEVEL_0;
Init.pull = IOC_PULL_NONE;
GPIO_setPadConfig(GPIO30, &Init); /* PWM0_A_BAK3 mode11 GPIO2_9*/
GPIO_setPinConfig(GPIO30, GPIO30_MODE_SRPWM0_A);
/* TB初始化 */
SRPWM_initTBStruct(&stTBInit);
stTBInit.period = EPWM0_TIMER_TBPRD;
stTBInit.countMode = SRPWM_COUNTMODE_UP;
SRPWM_initTB(SRPWM0, &stTBInit);
/* CMP初始化 */
SRPWM_initCMPStruct(&stCMPInit);
stCMPInit.scmpA = 200 - 4;
stCMPInit.cmpShadowLoadEn = ENABLE;
stCMPInit.cmpShadowLoadSel = SRPWM_SYNCEVTLOAD1_ZERO_EVT;
SRPWM_initCMP(SRPWM0, &stCMPInit);
/* PG初始化 */
SRPWM_setPG(SRPWM0, SRPWM_A, SRPWM_PG_EVT_ZERO, SRPWM_PG_SET);
SRPWM_setPG(SRPWM0, SRPWM_A, SRPWM_PG_EVT_FPP_FAULT_POS2, SRPWM_PG_CLEAR);
/* 配置输出给ACMP的RAMP触发源 */ SRPWM_setACMPTrigger(SRPWM_CHANNEL_0, SRPWM_OUTEVT_SYNC_ZERO_EVT, SRPWMCOM_ACMP2_H);
/* 配置输出给ACMP的Blanking触发源 */
SRPWM_setACMPBlankingTrigger(SRPWM_CHANNEL_0, SRPWM_OUTEVT_SYNC_SCMPA_UP_EVT, SRPWMCOM_ACMP2_H);
/* 使能高精度旁路 */
SRPWM_enableHRPWMBypass(SRPWM0);
/* 使能指定模块 */
SRPWMCOM_enable(SRPWM_CHANNEL_0);
}
可以预见,在本文的场景中,通过ACMP的blanking同样可以实现和SRPWM的Blanking应用效果。
总结
本文对SRPWM和ACMP的Blanking功能进行了详细说明,对模块当中的细节时序进行了展开描述,避免开发者在实际应用中产生的相应问题。特别是,本文以PCM峰值电流型场景应用时的丢波现象进行了阐述。
从实际代码示例中,我们可以得到基础的配置框架,以应对开发者的不同使用需求。
注意
从本文提供的两种方案中,可以看出,我们在实际应用时,均需要考虑到链路时延的影响。
综上所述
方案一:如希望采用FAULT信号的上升沿作为PWM波的拉低条件,且使用SRPWM通道内的FAULT有效区间处理该FAULT信号,则FAULT有效区间的结束触发事件应至少提前于PWM波的拉高事件3个时钟周期。
方案二:触发ACMP消隐窗口的PWM时基计数比较事件应至少提前于下一个PWM周期的脉冲置高触发信号4个时钟周期。









