TIDA-010062提供的图腾柱无桥PFC的PWM状态机实现原理介绍
TIDA-010062提供的图腾柱无桥PFC的PWM状态机实现原理介绍
maileyang_pe_2022
电力电子的数字与模拟控制的实用技术分享与交流
前言:这是2020年学习TIDA参考设计做的一些记录,整理了TI的参考设计在无桥图腾柱的控制上的一些思考和实现方法。(最近有不少人问过我正向东西)。
MCU的资源使用说明:
首先注意这个结构体定义,它设定了图腾柱PFC在PWM的多个状态,并根据AC电网的电压来实现状态机种各个子状态的切换。可以看到的是从正到负或者是从负到正都经历了三个状态,避免发生错误,而且也方便引入控制功能进去。
typedef union {
enum
{
pwmSwState_normalOperation = 0 ,
pwmSwState_positiveHalf = 1 ,
pwmSwState_negativeZeroCrossing1 = 2 ,
pwmSwState_negativeZeroCrossing2 = 3 ,
pwmSwState_negativeZeroCrossing3 = 4 ,
pwmSwState_negativeHalf = 5 ,
pwmSwState_positiveZeroCrossing1 = 6 ,
pwmSwState_positiveZeroCrossing2 = 7 ,
pwmSwState_positiveZeroCrossing3 = 8 ,
pwmSwState_defaultState = 9 ,
} enum_pwmSwState ;
int32_t pad ;
} TTPLPFC_pwmSwState ;
extern TTPLPFC_pwmSwState TTPLPFC_pwm_SwState ;
下面是PWM状态机函数,是放在每个开关周期的中断控制函数种执行,接受电流环输出的duty数据,并直接写入到PWM模块的寄存器里面实现占空比输出。 下面我会在函数里面用简单的用中文注释里面说明以下TI的实现方法和思考。
#pragma FUNC_ALWAYS_INLINE ( TTPLPFC_pwmDriver )
static inline void TTPLPFC_pwmDriver ()
{
#if TTPLPFC_DC_CHECK == 0
switch ( TTPLPFC_pwm_SwState . enum_pwmSwState )
{
/*First state after B2 Tasks initialization*/
case pwmSwState_normalOperation :
//
// Wait for positive zero crossing: pwmSwState_positiveZeroCrossing1
//PWM state get into positive zero crossing state1 when Vin<0.
//TTPLPFC_threshold_PZC2=0.01,
//
/* 在MCU复位后的全局变量初始化时,会把这个状态机放在pwmSwState_normalOperation的初始位置,通常在这个情况下会把所有PWM的输出拉到,为了保险起见还会设置一个PWM TZ FLAG的故障位标志,让PWM模块也维持在输出为低的故障模式,如果外部有管理PWM的逻辑器件,也会拉低PWM的输出,防止错误的时序损坏开关器件。*/
/* 从上面的代码可见,已经是进入了开始PWM工作的流程,并且等待电网电压相位的过零穿越,需要注意的是它是要等电网从负到正穿越,并且把PZC2这个阈值的比较点是设置为0.01。那么PZC2是需要跟谁进行比较呢? 很显然是跟电网锁相环的输出值进行比较,为了避免干扰,通常会用锁相环输出的完美正弦波来进行相位的过零穿越的判定 。*/
/* 下面这行代码就是开始比较AC电网的锁相环的值了,这里TTPLPFC_acSine_Prev 是把锁相环的当前输出滞后了一拍,起到双层判定的效果。如果通过这里if判定,那么可以把状态机转移到下一个状态了。*/
if ( TTPLPFC_acSine < TTPLPFC_threshold_PZC2
&& TTPLPFC_acSine_Prev < 0 )
{
//
//State switch.
//
/* 切换状态到正向穿越,并且直接强迫限制此时的duty到最小值,为了防止意外发出的PWM损坏开关管 */
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_positiveZeroCrossing1 ;
//
//Limit PU of duty.
//
TTPLPFC_dutyPU = 0.004f ;
//
//Force PWM output low by AQ(LOW_FREQ) and DB(HIGH_FREQ)
//
/* 这里使用宏定义直接强迫了PWM的动作寄存器输出H/L都是低电平,
是用在图腾柱的低频桥臂,然后强迫设置PWM寄存器的死区模块的上升/下降沿死区模块为TTPLPFC_PFC_PWM_PERIOD值,也就是死区长达达到一个周期,那就是把PWM的有效输出全部用死区吃掉了,是禁用PWM的输出的一种简单方法*/
TTPLPFC_AQ_SW_FORCE_PWMxA_LOW_PWMxB_LOW (
TTPLPFC_LOW_FREQ_PWM_BASE );
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
//
//Limit output of current loop PI regulator.
//
/* 初始化电流环的PI参数,清除PI控制器的内部数据和输出,防止影响到duty控制*/
TTPLPFC_gi . i10 = 0 ;
TTPLPFC_gi . i6 = 1 ;
TTPLPFC_gi_out = 0 ;
//
//Clear trip flags twice.
//This flag has been cleared in B2 Tasks.
/* 分别清除两个桥臂的PWM故障,为后面开启发波做准备,前面提到的是在初始状态强制设置了PWM TZ FLAG故障的标志,这里检查到零穿越后,在转移函数种清除掉标志位 */
TTPLPFC_HAL_clearPWMTripFlags ( TTPLPFC_LOW_FREQ_PWM_BASE );
TTPLPFC_HAL_clearPWMTripFlags ( TTPLPFC_HIGH_FREQ_PWM_BASE );
//
//Initialize current loop reference.
//
TTPLPFC_ac_cur_ref_inst_pu = 0.00f ;
//
//Set close loop flags. Begin close loop actions.
//
TTPLPFC_closeGiLoop = 1 ;
TTPLPFC_closeGvLoop = 1 ;
}
break ;
/*Positive half state*/
case pwmSwState_positiveHalf :
//
//Set LOW_FREQ PWM output to control current direction.
//Set DBRED to allow HIGH_FREQ PWM output.
//
/* 进入电网正相位工作,这里用宏开启低频桥臂的低端开关位高,高端开关位低。同时减少高频桥臂的开关的的上升沿死区到正常工作范围,下降沿死区依然位周期长度,没做修改*/
TTPLPFC_AQ_SW_FORCE_PWMxA_LOW_PWMxB_HIGH ( TTPLPFC_LOW_FREQ_PWM_BASE );
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_dbRED_SetValue_ticks );
#if TTPLPFC_CONTROL_RUNNING_ON == CLA_CORE
if (TTPLPFC_guiPrms_W > 480 && TTPLPFC_highPowerTrans_flag == 0 )
{
TTPLPFC_gi . Kp = TTPLPFC_GI_PI_KP_CLAH;
TTPLPFC_gi_pi_ki = TTPLPFC_GI_PI_KI_CLAH;
TTPLPFC_gi . Ki = TTPLPFC_gi_pi_ki;
TTPLPFC_highPowerTrans_flag = 1 ;
}
else if (TTPLPFC_guiPrms_W < 430 && TTPLPFC_highPowerTrans_flag == 1 )
{
TTPLPFC_gi . Kp = TTPLPFC_GI_PI_KP_CLAL;
TTPLPFC_gi_pi_ki = TTPLPFC_GI_PI_KI_CLAL;
TTPLPFC_gi . Ki = TTPLPFC_gi_pi_ki;
TTPLPFC_highPowerTrans_flag = 0 ;
}
#endif
//
//TTPLPFC_threshold_NZC1=0.01,
//when TTPLPFC_ac_sign_filtered == 0, Vin is negative.
//
/* 检查到锁相环的输出开始转移到从正到负的穿越点 */
if ( TTPLPFC_acSine < TTPLPFC_threshold_NZC1 ||
TTPLPFC_ac_sign_filtered == 0 )
{
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_negativeZeroCrossing1 ;
//
//AQCSFRC xA LOW, xB LOW
//
/* 转移到pwmSwState_negativeZeroCrossing1状态,并且首先强迫把低频桥臂的开关拉低,也就说还没等到穿越到负向,就提前关闭了低频桥臂开关。防止低频桥臂的开关体二极管影响的反向恢复在过零点产生电流噪音。*/
TTPLPFC_AQ_SW_FORCE_PWMxA_LOW_PWMxB_LOW (
TTPLPFC_LOW_FREQ_PWM_BASE );
}
break ;
/*NZC state1:*/
case pwmSwState_negativeZeroCrossing1 :
//
//TTPLPFC_stateSlew++;
//Force high_freq PWM output low by DB(HIGH_FREQ).
//
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
//
//Limit PU of duty.
//
TTPLPFC_dutyPU = 0.004f ;
/* 转移到负向穿越的NZC1后,同时也关闭了高频桥臂的PWM输出,这里还是通过把死区增加到周期长度的方法来实现,同时也断开了电流环的输出,占空比强制写为0.004 */
if ( TTPLPFC_acSine <= 0 )
{
//
//State switch.
//
/* 由于NZC1的判断点是锁相环的acSIN是0.01,还没有到零点以下的负相位,所有这里继续等待AC电网正式穿越到零以下*/
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_negativeZeroCrossing2 ;
}
break ;
/*NZC state2:*/
case pwmSwState_negativeZeroCrossing2 :
//
//TTPLPFC_stateSlew++;
//Limit PU of duty.
//
/* 继续等待电网相位往负向穿越,当判定到电网锁相环小于-0.01后,转移状态到NZC3 */
TTPLPFC_dutyPU = 0.004f ;
if ( TTPLPFC_acSine < TTPLPFC_threshold_NZC2 )
{
//
//Initialize two flags. Use in control DBFED in NZC3.
//
TTPLPFC_stateSlew = 0 ;
TTPLPFC_softStartDuty_ticks = 0 ;
/* 初始化过零duty软起计数器和软启duty变量 */
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_negativeZeroCrossing3 ;
//
//Enable xA xB Swap
//
/* 需要重点说明的是,这里通过调整PWM模块的DB模块内部的SWAP来交换PWMA和PWMB的输出逻辑,在前面我们得知,EPWM3A是作为HG驱动,EPWM3B是LG的驱动,这里把A/B交换驱动位置后,PWM模块参数的DUTY和互补的输出则就是进行交换后的输出*/
TTPLPFC_ENABLE_SWAP_DEADBAND_OUTPUT ( TTPLPFC_HIGH_FREQ_PWM_BASE );
//
//PI parameter use in PZC3 state.
// 清除电流环的PI控制器内部数据
TTPLPFC_gi . i10 = 0 ;
TTPLPFC_gi . i6 = 1 ;
TTPLPFC_gi . Ki = 0 ;
TTPLPFC_gi_out = 0 ;
}
break ;
/*NZC state3:*/
case pwmSwState_negativeZeroCrossing3 :
//
//Control DBFED.
//
/* 这里在每次进入中断后位过零后软启动占空比强制加1,来实现软启动由于在前面交换了A/B的输出位置,因此这里操作FED下降沿的死区其实是在操作HG的驱动脉宽,可见下面FED的死区由周期最大值逐渐减少到10。因为前面duty强制写入了0.004,因此HG的输出占空比是最小的,对应AHC(有源互补输出模式)的配置,LG的占空比是达到96%这么大的。因此,这里的实现就是把上管的占空比从0增到最大值96%,同时还维持下管为低电平关闭状态*/
TTPLPFC_softStartDuty_ticks = TTPLPFC_softStartDuty_ticks + 1 ;
TTPLPFC_softStartDeadBandFED_ticks = TTPLPFC_PFC_PWM_PERIOD
- TTPLPFC_softStartDuty_ticks * 50 ;
//
//Limit DBFED.
//TTPLPFC_dbFED_SetValue_ticks=10
//
if ( TTPLPFC_softStartDeadBandFED_ticks <
TTPLPFC_dbFED_SetValue_ticks )
{
TTPLPFC_softStartDeadBandFED_ticks =
TTPLPFC_dbFED_SetValue_ticks ;
}
//
//Set DBFED=500?.
//
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_softStartDeadBandFED_ticks );
//
//Count work times in PZC3.
//
TTPLPFC_stateSlew ++;
//
// if( fabsf(TTPLPFC_dutyPU) < 0.004f)
// {
// if(TTPLPFC_dutyPU > 0) TTPLPFC_dutyPU = 0.004;
// else TTPLPFC_dutyPU = -0.004;
// }
//
//
//TTPLPFC_stateSlew>10&&Vin<0
/* 软启动这里强迫进入10次,并且VAC确实是在负向相位,则正式进入负向区域工作模式 */
if ( TTPLPFC_stateSlew > TTPLPFC_stateSlewMax
&& TTPLPFC_ac_sign_filtered == 0 )
{
//
//PI parameter use in PZC3 state.
// 重新写入PI参数
TTPLPFC_gi . i10 = 0 ;
TTPLPFC_gi . i6 = 1 ;
TTPLPFC_gi . Ki = TTPLPFC_gi_pi_ki ;
TTPLPFC_gi . Umax = TTPLPFC_GI_PI_MAX ;
TTPLPFC_gi . Umin = TTPLPFC_GI_PI_MIN ;
TTPLPFC_gi_out = 0 ;
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState = pwmSwState_negativeHalf ;
//
//Set DBFED=10
// 设置正常工作的死区时间
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_dbFED_SetValue_ticks );
//
//Reset flags.
// 清除过零软启动flag,为正向穿越做准备
TTPLPFC_softStartDuty_ticks = 0 ;
TTPLPFC_stateSlew = 0 ;
}
break ;
/*Negative half state*/
case pwmSwState_negativeHalf :
//
//Set LOW_FREQ PWM output to control current direction.
//Set DBRED to allow HIGH_FREQ PWM output.
/* 设置低频桥臂驱动为HG为H,LG为LOW,同时设置上升沿死区为正常工作时间,进入正常工作模式*/
TTPLPFC_AQ_SW_FORCE_PWMxA_HIGH_PWMxB_LOW ( TTPLPFC_LOW_FREQ_PWM_BASE );
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_dbRED_SetValue_ticks );
/* 监测到负向到正向穿越后,关闭低频桥臂驱动,高频桥臂还没关*/
if ( TTPLPFC_acSine > TTPLPFC_threshold_PZC1
|| TTPLPFC_ac_sign_filtered == 1 )
{
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_positiveZeroCrossing1 ;
//
//AQCSFRC xA LOW, xB LOW
//
TTPLPFC_AQ_SW_FORCE_PWMxA_LOW_PWMxB_LOW (
TTPLPFC_LOW_FREQ_PWM_BASE );
}
break ;
/*PZC state1:*/
case pwmSwState_positiveZeroCrossing1 :
//
//TTPLPFC_stateSlew++; //DONOTUSE
//Force high_freq PWM output low by DB(HIGH_FREQ).
/* 关闭高频桥臂的驱动输出,强迫死区为最大值*/
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
//
//Limit PU of duty.
//
TTPLPFC_dutyPU = 0.004f ;
if ( TTPLPFC_acSine >= 0 )
{
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_positiveZeroCrossing2 ;
}
break ;
/*PZC state2:*/
case pwmSwState_positiveZeroCrossing2 :
//
//TTPLPFC_stateSlew++;//DONOTUSE
//Limit PU of duty.
//
TTPLPFC_dutyPU = 0.004f ;
if ( TTPLPFC_acSine > TTPLPFC_threshold_PZC2 )
{
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState =
pwmSwState_positiveZeroCrossing3 ;
//
//Initialize two flags. Use in control DBFED in PZC3.
//
TTPLPFC_stateSlew = 0 ;
TTPLPFC_softStartDuty_ticks = 0 ;
//
//Dead band output swap disabled.
// 恢复正常开关的逻辑,禁用SWAP功能
TTPLPFC_DISABLE_SWAP_DEADBAND_OUTPUT (
TTPLPFC_HIGH_FREQ_PWM_BASE );
//
//PI parameter use in PZC3 state.
//
TTPLPFC_gi . i10 = 0 ;
TTPLPFC_gi . i6 = 1 ;
TTPLPFC_gi_out = 0 ;
TTPLPFC_gi . Ki = 0 ;
}
break ;
/*PZC state3:*/
case pwmSwState_positiveZeroCrossing3 :
//
//Control DBFED.
// TTPLPFC_PFC_PWM_PERIOD = 1000
/*与负向穿越一样通过在该区域操作PWM3A的下降沿来实现对实现过零软启动。不同的地方是,这里让上管维持低电平关闭,将下管的占空比从0增加到最大,实现过零后软启动*/
TTPLPFC_softStartDuty_ticks = TTPLPFC_softStartDuty_ticks + 1 ;
TTPLPFC_softStartDeadBandFED_ticks = TTPLPFC_PFC_PWM_PERIOD -
TTPLPFC_softStartDuty_ticks * 50 ;
//
//Limit DBFED.
//
if ( TTPLPFC_softStartDeadBandFED_ticks <
TTPLPFC_dbFED_SetValue_ticks )
{
TTPLPFC_softStartDeadBandFED_ticks =
TTPLPFC_dbFED_SetValue_ticks ;
}
//
//Set DBFED=500?.
//
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_softStartDeadBandFED_ticks );
//
//Count work times in PZC3.
//
TTPLPFC_stateSlew ++;
//
// if( fabsf(TTPLPFC_dutyPU) < 0.004f)
// {
// if(TTPLPFC_dutyPU > 0) TTPLPFC_dutyPU = 0.004;
// else TTPLPFC_dutyPU = -0.004;
// }
//
//
//TTPLPFC_stateSlew>10&&Vin>0
//
if ( TTPLPFC_stateSlew > TTPLPFC_stateSlewMax
&& TTPLPFC_ac_sign_filtered == 1 )
{
//
//PI parameters use in positive half.
//
TTPLPFC_gi . i10 = 0 ;
TTPLPFC_gi . i6 = 1 ;
TTPLPFC_gi_out = 0 ;
TTPLPFC_gi . Ki = TTPLPFC_gi_pi_ki ;
//
//State switch.
//
TTPLPFC_pwm_SwState . enum_pwmSwState = pwmSwState_positiveHalf ;
//
//Set DBFED=10
//
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_dbFED_SetValue_ticks );
//
//Reset flags.
//
TTPLPFC_stateSlew = 0 ;
TTPLPFC_softStartDuty_ticks = 0 ;
}
break ;
/*Protect state: OCP OVP*/
case pwmSwState_defaultState :
//
//Limit PU of duty.
//
TTPLPFC_dutyPU = 0.01f ;
//
//Force PWM output low by AQ(LOW_FREQ) and DB(HIGH_FREQ).
/* 初始化后,直接把高频低频PWM全部关闭*/
TTPLPFC_AQ_SW_FORCE_PWMxA_LOW_PWMxB_LOW ( TTPLPFC_LOW_FREQ_PWM_BASE );
TTPLPFC_SET_PWM_DBRED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
TTPLPFC_SET_PWM_DBFED ( TTPLPFC_HIGH_FREQ_PWM_BASE ,
TTPLPFC_PFC_PWM_PERIOD );
break ;
default :
TTPLPFC_pwm_SwState . enum_pwmSwState = pwmSwState_defaultState ;
}
#endif
}
PWM状态机应用在PFC上的测试视频:
感谢观看,谢谢支持,本人能力有效,如有错误恳请帮忙指正,谢谢。
更多PFC介绍:
1、 降低单相PFC的ithd的几个点子
请杨帅锅喝杯咖啡☕
微信扫一扫赞赏作者
赞赏
发送给作者
人赞赏
长按二维码向我转账
请杨帅锅喝杯咖啡☕
受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。
-
2023年血糖新标准公布,不是3.9-6.1,快来看看你的血糖正常吗? 2023-02-07
-
2023年各省最新电价一览!8省中午执行谷段电价! 2023-01-03
-
GB 55009-2021《燃气工程项目规范》(含条文说明),2022年1月1日起实施 2021-11-07
-
PPT导出高分辨率图片的四种方法 2022-09-22
-
2023年最新!国家电网27家省级电力公司负责人大盘点 2023-03-14
-
全国消防救援总队主官及简历(2023.2) 2023-02-10
-
盘点 l 中国石油大庆油田现任领导班子 2023-02-28
-
我们的前辈!历届全国工程勘察设计大师完整名单! 2022-11-18
-
关于某送变电公司“4·22”人身死亡事故的快报 2022-04-26