Boost PFC 调试与软件程序容错性的思考
2021-10-14 11:03 斑鸠,一生。 阅读(584) 评论(0) 编辑 收藏 举报最近做了一个数字电源,本意是使用单片机控制PFC。这个问题的现象引起我对软件程序容错性的思考。
软件的容错性:当硬件故障的时候,程序不跑飞的能力。
目前就有这样的一个案例,它的逻辑代码是这样的:
通过检测输入电压的过零点,然后每检测到一个过零点,计数值重置为零,否则再定时器中断里面递增。
硬件电路:
分析:
交流电是50Hz,也就是100个过零点。每两个周期是10ms。受电网供电质量与硬件电路的延时的影响,送到单片机的过零检测波形会有一点点的不对称。
理想情况下,Vac2_AD处的波形应该是占空比为50%的方波。
现实情况下,受电网供电质量的影响、Q5的影响,Vac2_AD的波形不是50%。
程序实现:
//Calculate the input current reference for (i = 0 ; i < 1000; i++){ I_ref[i] = (32767*sin(pi/1000.0f*i)+0.5f); } //每次检测到Vac2_AD波形的边沿,计数值Count置零。 void __attribute__ ((__interrupt__,__no_auto_psv__)) _CNInterrupt(void){ IFS1bits.CNIF = 0; //Clear the interrupt flag Count = 0; ADCPC0bits.SWTRG1 = 1; } //定时器10us,递增一次。 Count++; IL1_Err = I_ref[Count] - IL1_Real;
上面程序是在理想的情况下,Count是在小于1000的情况下,每次计数到1000,也就是10ms,外部刚好检测到过零点,Count又被置零。
那么,当检测外部过零点延时到来的时候,Count>1000,那么数组溢出,I_ref[1500]是一个随机数,程序跑飞。
下面的程序将Count取余,并且在20ms,才置零一次。提高了程序的容错性。
//Calculate the input current reference for (i = 0 ; i < 1000; i++){ I_ref[i] = (32767*sin(pi/1000.0f*i)+0.5f); } //每次检测到Vac2_AD波形的边沿,计数值Count置零。 void __attribute__ ((__interrupt__,__no_auto_psv__)) _CNInterrupt(void){ IFS1bits.CNIF = 0; //Clear the interrupt flag if(Count > 1980)Count = 0; ADCPC0bits.SWTRG1 = 1; } //定时器10us,递增一次。 Count++; IL1_Err = I_ref[Count%1000] - IL1_Real;
实验验证:
分别将上述代码,在 Boost PFC程序中验证。
代码一:存在输入电流正负半周不对称的情况。(负半周期的I_ref不正常,错位和溢出)
代码二:正负半周对称。
另外,Boost变换器经常需要做过压保护。当输出电压超过设定最大电压时,关闭开关管的占空比,过压标志位置1。
if(Vbus_AD > Vbus_430) { PFC_OverVoltage_Flag = 1; PDC2 = 0; SDC2 = 0; }
然而:
这段代码,在变换器插入电网的时候,常常出现启动不正常的现象。或者出现150Vac启动正常,220Vac启动就不正常。
原因就是:开机启动的时候,母线电容上是没有储能的,刚接上输入电压的时候,立即给母线电压充电,很可能出现母线电压达到最大保护值的情况。
进入保护后,母线电压下降,但是这段代码不能做到自恢复。
下面这段代码就加入了自恢复的措施。当输出母线电压低于自动保护后,自动退出保护,自动启动闭环控制程序。
if(Vbus_AD > Vbus_430) { PFC_OverVoltage_Flag = 1; PDC2 = 0; SDC2 = 0; }else{ PFC_OverVoltage_Flag = 0; }
以上的两个实验现象。主要想说明数字电源,控制不仅仅要考虑到程序逻辑的正确性,程序的容错性也是在设计需要考虑的问题。
保护电路很重要,如何退出保护,回归正常也是很重要的。