class="markdown_views prism-github-gist">
关于直流稳压源软件的实现
在电力电子中,主要的核心知识点就是稳压稳流和稳功率,就像实验室中的稳压直流电源一样,你设定输出多少伏,比如25v,直流稳压电源就是25v,无论你接什么负载,都是25v,也不可能说是24.9v或者25.1v,要体现在一个
稳定上面。
实验室的直流稳压电源大概基本组成电路就是一个整流模块和一个
SG3525同采样电路实现的硬件闭环电路组成,不过要做到高精度也并非易事,这里博主我就分享一下自己用软件实现的这一个过程。
1、基础电路
博主所有单片机为stm32f4系列的核心版,所需要的硬件电路大概就是输入的滤波电路,IR2184buck电路,采电压电流电流。
1.1 滤波电路
滤波电路是由比较大容值的滤波电容组成,比如63v 2200uF的大电容,主要是减少输入电压的波动。
我们用的是大的滤波电容和钽电容一起混合组成的,不过,要注意电容的耐压值,输入电压不要超过电容的耐压值,不然电容就会爆炸!!!
1.2 IR2184驱动电路
这个相信做电力电子的同学应该都知道这款驱动芯片,熟练这款驱动芯片的使用完全可以在电力电子电流上面掌握大片江山,交流方面掌握IR2210驱动芯片有同样能掌握半壁江山。
这里博主就把电路图展示出来了,想学的人,自己出现问题的,仔细琢磨琢磨,学到的会更多,让我们一起对伸手党说不!
这里IR2184电路大致功能就是你给多少输入,他就多少输出乘以你给定的PWM输出。相当有良心。
1.3 采样电路
这个采样电路,一个是电压采样,一个是电流采样。
1.3.1 电压采样电路
电压采样电路基本上就是一个电阻分压电路了。不过你要仔细校对这个采样系数,到时候写道你们软件里面去
1.3.2电流采样电路
电流采样,这里不涉及交流电流和电压,不需要外加偏置,电流采样基本上就是你串进去一个采样电阻,然后通过测量电阻两端的电压,通过电压除以刚刚的已知电阻就是电流。如果电流太小了,就要通过放大芯片去放大电流,然后测量出这个线性放大关系。一般的比如10m欧的电阻你放大100倍就刚刚好了。
软件模块组成
2、PWM输出模块
pwm输出就是用来控制输出频率的,虽然,对于直流电路来说,没必要关心频率,但当电路运用到特定地方,比如需要用FFT分析等等之类的,这里pwm也是按照stm32正常配置一样。
//初始化TIM2 Channe2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时模式;TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2,ENABLE);ARPE使能
TIM_Cmd(TIM2, ENABLE); //使能TIM2
2.1 配置pwm输出频率和预装载值
TIM2_PWM_Init(400-1,7-1);
定时器2挂在APB1上,APB1是84M的主频
有 84M/7=12Mh计数频率,重装载值为400,所以pwm的频率为12M/400=30kHz
2.2 控制pwm占空比
定义一个叫duty的变量表示占空比控制pwm的占空比为
if(duty>395)duty=200;
if(duty<5)duty=200;
TIM_SetCompare2(TIM2,duty);
3、按键控制模块
按键的话,也就是你设定输出电压的值,中间涉及大小步进,稳压,稳流模式的切换,显示屏幕的切换。还有控制一些其他等等
下面是一个按键控制不同步进的实现:
void key_action(void){
key=KEY_Scan(0);
if(key!=lastkeyvalue){
if(key!=0){
switch(key){
... ...
case 10:if(goal_voltage<24)goal_voltage+=index_goal;key=0;break;
case 11:if(goal_voltage>0)goal_voltage-=index_goal;key=0;break;
case 12:if(index_goal==0.05f)
index_goal=0.2f;
else if(index_goal==0.2f)
index_goal=1;
else if(index_goal==1)
index_goal=0.05f;
key=0;break;
... ...
default:break;
}
}
}
lastkeyvalue=key;
}
4、采样处理模块
其实这个采直流就比较随意的,随便采,滤波处理也不多,不过我们还是同步采比较好,我们可以在一个大循环里面单独控制时间,这里博主我借用pwm输出这个定时器的计数时间来采样。
void sample_process(void)//AD采样处理模块
{
if(TIM_GetCounter(TIM2)>=360)
{
u8 j,k;
u32 adc_getvalue[4];
memset(&adc_getvalue,0,sizeof(adc_getvalue));
for(j=0;j<40;j++)
{
for(k=0;k<4;k++)
adc_getvalue[k] += adc_filter(10,aADCConvertedValue[k]);
}//PC3--[1] PC1--[3] PC2--[0] PA5--[2]
voltage1_calculate= (float)adc_getvalue[1]*33/(400*4096);
//voltage2_calculate= (float)adc_getvalue[2]*33/(400*4096);
current1_calculate= (float)adc_getvalue[0]*33/(400*4096);
//current2_calculate= (float)adc_getvalue[3]*33/(400*4096);
memset(&adc_getvalue,0,sizeof(adc_getvalue));
//线差,之前采样电路的实现
//adc_voltage1=6.157f*voltage1_calculate+0.06f;
adc_voltage1=6.222f*voltage1_calculate+0.012f;
adc_voltage2=voltage2_calculate;
adc_current1=current1_calculate;
adc_current2=current2_calculate;
}
5、软起动,PI处理
在电路有大幅度的变化过程中,我们一开始并不希望就直接PI调节,因为PI一开始调节幅度相当大,希望存在一个缓慢的但又不失调节作用的过程,这个过程我们可以用软起动来实现。
5.1 给标志位
什么时候软起动,什么时候PI调节,顺着上面的,当在大幅度范围变化时软起动,比较小的时候,进行PI调节稳定电压电流
//给标志处理
if(adc_voltage1-goal_voltage<=-0.3f || adc_voltage1-goal_voltage>=0.3f)
soft_flag=1;
if(adc_voltage1-goal_voltage<0.15f || adc_voltage1-goal_voltage>-0.15f)
PID_flag=1;
5.2 开闭环
之所以有开环,只是为了方便调节和校准之前的系数,当功能基本实现后们就可以不开闭环标志去掉了。
//开环模式
if(close_open_flag==1)
{
if(duty-expect_open_duty<-5)duty+=1;
if(duty-expect_open_duty>5)duty-=1;
if(duty-expect_open_duty<-2)duty+=0.05f;
if(duty-expect_open_duty>2)duty-=0.05f;
}
else if(close_open_flag==0)//闭环模式
{
if(soft_flag==1)
{
if(adc_voltage1-goal_voltage<-0.5f)duty+=1;
if(adc_voltage1-goal_voltage>0.5f)duty-=1;
soft_flag=0;
}
if(PID_flag==1)
{
pid.ActualSpeed = adc_voltage1;
duty += PID_realize(goal_voltage);
PID_flag=0;
}
}
可能有要求,软起动要一秒等等之类的,这时候只要改部分系数就好了。
6、显示+过流短路保护
6.1 显示部分
取决于你所用的显示器,博主我用的是OLED显示屏,像这些经常用的比如按键函数,显示函数等等功能明显,常用的自己一定要把它函数化,写成自己喜欢的形式。下面是博主我的部分显示:
void Oled_show(void)
{
... ...
OLED_Refresh_Gram();
OLED_ShowString(0,16,"goalInde:",16);
OLED_ShowFloatNum(72,16,index_goal,7,16);
OLED_ShowString(0,32,"goal_val:",16);
OLED_ShowFloatNum(72,32,goal_voltage,7,16);
OLED_ShowString(0,48,"real_val:",16);
OLED_ShowFloatNum(72,48,adc_voltage1,7,16);
... ...
}
6.2 过流保护短路保护
这里过流短路测试点都在电流大小上,可以软件实现也可以硬件实现,硬件电路可以用LM393比较电路,检测上升沿
软件实现的话,就只要判断电流是不是过大了。
if(adc_current1>=curr_given)
{
A_Over=1;
GPIO_ResetBits(GPIOD,GPIO_Pin_1);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
}else
{
duty=duty;
cnt=100;
A_Over=0;
GPIO_SetBits(GPIOD,GPIO_Pin_1);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
过流保护短路都需要挂断一段时间,注意这个时间上的控制。
下篇文章中,博主也会讲解
稳流源,稳功率电源的制作,但这一篇是最为重要的,希望能加强理解,下面是stm32源程序的下载链接,感兴趣的同学可以下载来看一下。