本人大学生一枚,最近两天做了一下2020年省赛的B题:单项在线式不间断电源。做PFC电路和升压电路还算比较顺利,但是在做DC-AC逆变的时候着实遇到了一些问题。
这是我搭的逆变电路
电路主体大概是一个使用STM32产生SPWM的波,经过IR2110驱动H桥逆变,再经由LC滤波输出,在这里我使用了双极性调制。共两个电感,每个电感是1.7mH,输出有一个2.2uF的CBB电容。
明明没有什么问题,但是输出的波形很奇怪。
这是逆变电路输出空载的波形,同时功率部分有约13毫安的空载电流
当输出接了约30W纯阻性负载之后,波形又变成了这个样子
这里,H桥的直流母线电压为30V。
我起初怀疑是硬件电路的问题,就先用EG8010临时搭了一个电路,结果发现出来的波形特别完美。
空载时电源输出电流几乎为0;
既然硬件电路没啥问题,那就只能去扒一扒软件了
在SPWM里,我使用的是查表法来产生spwm,暂时用的开环设计。
调制频率是20kHz,基波是50Hz,表格里也应该有400个数,将这400个数导出来放到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时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//初始化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; //调节死区时间
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的中断服务函数
//定时器2中断服务程序
void TIM2_IRQHandler(void) //TIM2中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查TIM2更新中断发生与否
{
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毫安的电流(功率部分)
至此,我已经彻底懵了,不知道怎么办,我又试探着用示波器的FFT测了一下输出,突然被发现在约2kHz的地方发现一处尖峰
这好像是LC的谐振频率,发现了这个问题之后我也不知道该怎么解决,希望各位资深大佬们能给小弟一些建议