本人大學生一枚,最近兩天做了一下2020年省賽的B題:單項在線式不間斷電源。做PFC電路和升壓電路還算比較順利,但是在做DC-AC逆變的時候著實遇到了一些問題。
這是我搭的逆變電路
電路主體大概是一個使用STM32產生SPWM的波,經(jīng)過IR2110驅動H橋逆變,再經(jīng)由LC濾波輸出,在這里我使用了雙極性調制。共兩個電感,每個電感是1.7mH,輸出有一個2.2uF的CBB電容。
明明沒有什么問題,但是輸出的波形很奇怪。
這是逆變電路輸出空載的波形,同時功率部分有約13毫安的空載電流
當輸出接了約30W純阻性負載之后,波形又變成了這個樣子
這里,H橋的直流母線電壓為30V。
我起初懷疑是硬件電路的問題,就先用EG8010臨時搭了一個電路,結果發(fā)現(xiàn)出來的波形特別完美。
空載時電源輸出電流幾乎為0;
既然硬件電路沒啥問題,那就只能去扒一扒軟件了
在SPWM里,我使用的是查表法來產生spwm,暫時用的開環(huán)設計。
調制頻率是20kHz,基波是50Hz,表格里也應該有400個數(shù),將這400個數(shù)導出來放到EXCEL里,生成的圖表是這樣的
主PWM輸出用到了高級定時器1的T1C1、T1C1N、T1C2、T1C2N,
這個是定時器1的配置程序,輸出4路PWM,定時器1的arr = 3600., psc = 0。
void TIM1_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定時器1時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO外設和AFIO復用功能模塊時鐘
//設置該引腳為復用輸出功能,輸出TIM1 CH1 CH2的PWM脈沖波形 GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_8; //TIM_CH1 TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//初始化TIM1
TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數(shù)的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數(shù)模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位
//初始化TIM1 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1,TIM_OCPreload_Enable);
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
TIM_BDTRInitStructure.TIM_DeadTime = 5; //調節(jié)死區(qū)時間
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
TIM_ARRPreloadConfig(TIM1, ENABLE);
TIM_Cmd(TIM1, ENABLE); //使能TIM1
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
同時,用和定時器1同頻率的定時器2來更新定時器1的占空比,下邊是定時器2的中斷服務函數(shù)
//定時器2中斷服務程序
void TIM2_IRQHandler(void) //TIM2中斷
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //檢查TIM2更新中斷發(fā)生與否
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIM2更新中斷標志
//更新PWM1和PWM2的占空比
my_spwm.pwm_1++;
if(my_spwm.pwm_1 >= my_spwm.num_max)
my_spwm.pwm_1 = 0;
TIM1->CCR1 = num_list[my_spwm.pwm_1];
TIM1->CCR2 = num_list[my_spwm.pwm_1];
}
}
我還特意用了一下仿真,看了一下其中的一個互補通道
互補肯定是互補,不然表示會炸管的,但是空載有大約13毫安的電流(功率部分)
至此,我已經(jīng)徹底懵了,不知道怎么辦,我又試探著用示波器的FFT測了一下輸出,突然被發(fā)現(xiàn)在約2kHz的地方發(fā)現(xiàn)一處尖峰
這好像是LC的諧振頻率,發(fā)現(xiàn)了這個問題之后我也不知道該怎么解決,希望各位資深大佬們能給小弟一些建議