基于PID控制的数字恒流源报告.docx
《基于PID控制的数字恒流源报告.docx》由会员分享,可在线阅读,更多相关《基于PID控制的数字恒流源报告.docx(25页珍藏版)》请在冰点文库上搜索。
基于PID控制的数字恒流源报告
天津工业大学
测控仪器设计报告
组号2组
组员吴东航1110340108
章一林1110340114
郭伍昌1110340109
学院机械工程学院
专业测控技术与仪器
指导教师隋修武
2015年1月16日
摘要:
针对各种低压电器校验及性能测试过程中需要高稳定、高精度的恒流源要求,在对现有主要恒流源产品设计仔细分析的基础上,设计了一种以AT89C51为核心的高稳定数控恒流源。
整个系统采用闭环PID控制,输出PWM波控制恒流源的电流。
经实际应用测试,该恒流源输出电流可在10mA左右恒定,当电源电压变化、负载电路变化时,恒流源的精度在±1mA以。
1课程设计的目的和意义
测控系统设计是测控技术与仪器专业实践教学环节的重要组成部分,是“测控系统原理与设计”课程理论教学的有益补充,“测控系统原理与设计”是测控技术与仪器专业的一门综合性专业课,在理论教学的同时,要求学生掌握传感器的选型,测控电路的分析、设计、调试,微处理器的电路与程序设计、控制算法设计、计算机的综合应用等,以便对测控系统形成完整的认识。
通过本课程设计,完成基于PID控制的数字恒流源的设计,熟悉和掌握工业生产和科学研究中的测量和控制系统的组成原理及设计方法,学会运用所学的单片机、测控电路、控制算法等方面的知识,进行综合应用,设计出完整的测控系统,实现预期功能,培养自学能力、动手能力、分析问题能力和应用理论知识解决实际问题的能力。
2设计任务
设计基于PID控制的数字恒流源,设计要求如下
1、采用8051系列单片机输出PWM波控制恒流源的电流。
2、采用PID控制算法,实现对恒流源的闭环控制。
3、恒流源的电压为5V,恒流输出10mA。
4、采用LCD液晶1602显示电流值。
5、当电源电压变化、负载电路变化时,恒流源的精度在±1mA以。
3设计背景
相对于电压源,电流源具有抗干扰能力强,信号传输不受距离影响等。
电流源是一种能向负载提供恒定电流的电路。
它既可以为各种放大电路提供偏流以稳定其静态工作点,又可以作为其有源负载以提高放大倍数,在差动放大电路、脉冲产生电路中得到了广泛应用。
一般的恒流电流源往往是固定的一种输出电流值,或仅有几挡电流值,往往存在调节围小、稳定性差等缺点,不便于通用,且所设定的输出电流值是否准确不经测试无法知道。
低纹波、高精度稳定直流电流源是一种非常重要的特种电源,在现代科学研究和工业生产中得到了越来越广泛的应用。
4总体设计方案
以AT89C51为核心,采用闭环PID控制,输出PWM波控制恒流源的电流,经信号调理后,通过A/D转换送入单片机,通过LCD显示电流。
由于单片机控制算法灵活,程序相对简单,且成本较低,故选用AT89C51单片机实现数字控制。
为实现电流模拟量到数字量的转换,故选用ADC0809实现A/D转换。
通过三极管C9014及相关电路实现电流信号的放大。
为获得稳定的电流设计一个RC滤波电路去除干扰。
具体来说,该数字恒流源主要由以下模块构成:
采样模块、滤波模块、运算放大模块、A/D转换、显示模块等。
图1为系统结构框图。
图1系统结构框图
5硬件电路设计
5.1采样模块
通过单片机输出的PWM波,由于从PWM处输出的方波通过三极管后,通过采样电阻R6,以保证IN1处的电压恒定,为了使得A/D转换标度变换计算方便,减少计算机的计算量,因此R6电阻阻值采用100欧姆,当电流输出为10mA的时候,对应电压值为1V。
为了使得输出的电压值趋于平缓,因此增加电容C4(100uF),将交流转换为直流电压输出。
当三极管工作在非线性区(即三极管工作在饱和区或截止区),此时三极管相当于开关器件。
PWM波为高电平时,三极管b-e端导通,保证IN1处输出恒定电压;PWM波为低电平时,b-e端截止,IN1出R6处无电流。
三极管采样模块电路设计如图2所示。
本设计中采用三极管C9014充当放大器件,9014是非常常见的晶体三极管,在收音机以及各种放大电路中经常看到它,应用围很广,它是NPN型小功率三极管。
图3为三极管C9014的管脚图。
图2采样模块电路设计
图3C9014管脚图
5.3运算放大模块
电阻R7和C5构成简单的滤波电路,由于标度变换使得运放为1,因此将反向输入和输出连在一起构成电压跟随器。
在这里我们选用了两个方案,第一种用OP07构成电压跟随器,OP07闭环带宽约为400~500kHz,并且当VCC给5V时,运放线性区最大输出电压一般只有3V左右,经实验测得由OP07构成的电压跟随器输出不稳定。
第二种方案选用LM324构成的电压跟随器,经实验测得满足要求。
从运放的输出端输出送入A/D转换模块。
运算放大电路如图5所示。
本设计中采用LM324四运放集成芯片,它采用14脚双列直插塑料封装。
它的部包含四组形式完全相同的运算放大器,除电源共用外,四组运放相互独立。
每一组运算放大器可用图6所示的符号来表示,它有5个引出脚,其中“+”、“-”为两个信号输入端,“V+”、“V-”为正、负电源端,“Vo”为输出端。
两个信号输入端中,Vi-(-)为反相输入端,表示运放输出端Vo的信号与该输入端的位相反;Vi+(+)为同相输入端,表示运放输出端Vo的信号与该输入端的相位相同。
图6为LM324的引脚图。
图5信号放大模块电路设计
图6LM324引脚图
5.4A/D转换模块
通过ADC0809将获得的电流转换成数字量后,送入单片机。
ADC0809是8位的逐次逼近型A/D转换器,带8个模拟输入通道,芯片带地址译码器输出带三态数据锁存器。
本例所使用的IN0通道地址为000,由于本例仅使用了IN0通道,因此电路中直接将这ADDC、ADDB、ADDA三只引脚全部接地。
A/D转换电路如图7所示。
START引脚在一个高脉冲后启动A/D转换,当EOC引脚出现一个低电平时转换结束,然后由OE引脚控制,从并行输出端读取一字节的转换结果。
转换过程中芯片所需要的时钟信号由单片机定时器中断子程序提供。
图8为ADC0800的引脚图。
图7A/D转换模块电路设计
图8ADC0809引脚图
5.6A/D参考电压模块
为了实现标度变换,采用TL431构成的可调稳压模块作为A/D的参考电压。
将参考电压调成2.55V,通过式
(1)计算得到,电压值和转换值的对应关系为100倍,这样减少了CPU的计算量,减少了失误。
参考电压模块电路图如图9。
(1)
图9可调稳压模块
5.5显示模块
采用LCD1602显示电流值。
本设计中将单片机P0口通过排阻与1602相连,构成电路的显示模块。
如图10所示。
LCD1602是工业字符型液晶,能够同时显示16x02即32个字符。
具有微功耗、体积小、显示容丰富、超薄轻巧的特点,常用在袖珍式仪表和低功耗应用系统中。
1602的各管脚功能如图10所示,1脚VSS为电源地;2脚VCC接5V电源正极;3脚V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度);4脚RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
5脚RW为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作;6脚E(或EN)端为使能(enable)端,高电平
(1)时读取信息,负跳变时执行指令;7~14脚D0~D7为8位双向数据端;15~16脚空脚或背灯电源;15脚背光正极;16脚背光负极。
图10显示模块电路设计
图11LCD1602引脚图
6软件电路设计
6.1流程图
系统软件完成以下几个功能:
(1)系统初始化,包括各外围接口芯片的初始化;
(2)用PID算法实现对恒流源的闭环控制,由PID计算后得到的输出值控制PWM波;
(3)实现A/D转换;
(4)LCD的送显功能;
(5)移动滤波部分。
主程序流程图如图12所示,LCD1602子程序流程图如图13所示,移动滤波子程序流程图如图14所示,A/D转换子程序流程图如图15所示。
图12系统主程序流程图图13LCD1602子程序流程图
图14移动滤波子程序流程图
图15A/D转换子程序流程图
6.2PID控制算法
比例、积分、微分控制(PID控制)是过程控制中应用最广泛的一种控制方式。
比例控制是一种最简单的控制方式。
其控制器的输出与输入误差信号成比例关系。
当仅有比例控制时系统输出存在稳态误差;在积分控制中,控制器的输出与输入误差信号的积分成正比关系,为了消除稳态误差,在控制器中必须引入“积分项”,积分项对误差取决于时间的积分,随着时间的增加,积分项会增大它推动控制器的输出增大使稳态误差进一步减小,直到等于零;在微分控制中,控制器的输出与输入误差信号的微分(即误差的变化率)成正比关系,自动控制系统在克服误差的调节过程中可能会出现振荡甚至失稳,应使抑制误差的作用的变化“超前”,即在误差接近零时,抑制误差的作用就应该是零,即加入微分环节。
在本系统中,采用增量式PID控制对电流偏差值进行处理,其公式如下:
如令
,
,
(式中,
为纯比例作用下的临界振荡周期),则有
这样整个问题便简化为只要一个参数
,故称其为归一参数整定法。
改变
,观察控制效果,直到满意为止,该法为实现简易的自整定控制带来方便。
在本系统中,另
,通过PID增量式得出PID=
,再加上控制目标来控制PWN波的占空比,即PWM_ON=Last_out+PID,从而通过PID控制算法,实现对恒流源的闭环控制。
6.3PWM输出
PWM波是通过定时中断实现的,定时时间为0.2ms,即每0.2ms中断一次。
PWM波的占空比经过PID控制算法,从而达到跟踪的目的。
因此,经过PID增量控制算法后得到的PWM_ON=Last_out+PID修订了的值。
将PWM波的周期设定为200个定时周期即0.2ms*200=40ms,每进一次中断服务子程序就比较一下高电平数是否到了PWM_ON,如果没到,就让输出为一个定时周期的高电平,要是高电平数到了PWM_ON,就输出(FFH-PWM_ON)个低电平,一直到200个定时周期结束为一个PWM波周期。
此时让高电平数仍从0开始加起,再看是否到了PWM_ON,从而决定输出是高电平还是低电平,可以循环。
这样就可以根据PWM_ON来改变PWM的占空比。
6.4A/D转换
通过定时中断实现A/D转换,定时时间为20ms,即每20ms中断一次。
每中断十次,进行一次A/D采样,即采样时间是20ms*10=200ms,而PWM波的周期为40ms,采样时间远大于PWM周期的2倍,符合采样定理。
7调试与仿真结果分析
在调试过程中,并不是一帆风顺的,当最初的焊接完成,烧录程序之后LCD一直显示一个错误值,并且不受控制,经过仔细的排查,发现是没有接上拉电阻并且有一根导线虚焊,解决这个问题之后,又遇到了电压跟随器没有输入却有输出的现象,经过查阅资料,在此电路中,用OP07搭建的电眼跟随器不符合要求,因此选用LM324搭建的电压跟随器。
这样输出结果接近了10mA左右,但是一直不稳定,这样我在电压跟随器的输入端加入了一个滤波电路选择适合的比例系数使得输出电压稳定下来。
电路板上显示的结果与要求的10mA存在着0.4mA的误差和送,经过分析,认为可能是由于以下几点原因造成的:
1.标准器误差,提供标准值的器件如标准电阻,标准电容等标准器件本身会带有一定的误差;
2.焊接过程中产生的误差,在焊接的过程中不可避免的会产生随机误差,这会对最终的结果产生一定的影响;
3.在对PID控制算法的过程中,
的值为估算值,可能会对结果产生一定影响。
8心得体会
在为期两周的测控系统设计里,我们组的三位成员都收获了很多。
首先大家分工明确,各司其职,在最后的调试阶段又同心协力,共同攻坚克难,最终取得了胜利。
第二,对测控系统设计有了生动的理解,不再只是停留在书本上空洞的框架里,而是通过这次的课程设计有了准确的理解和系统的认识。
第三,对PID控制算法的实际运用有了一定的了解,之前只是在理论上对PID有过接触,这次能够将PID控制算法运用在实际设计中,感觉到对PID又有了更深的认识,尤其是通过增量式PID对参数进行整定。
第四,在调试过程中会遇到各种问题,这时,不仅需要扎实的专业功底,同时更需要细心,耐心,专心,在仿真结果正确,但调试并没有达到预期的效果时,要对电路进行彻底仔细的检查,对每一部分的电压电阻等逐一进行测量,弄清每一部分的工作原理,找出问题并一一解决。
最后,感隋修武老师和辉、田松等两位研究生给予的帮助和指导。
经过两周的课程设计,我们受益良多。
在这个过程中,我们经历了选定方案、仿真调试、实验调试、最终成品几个阶段。
在此期间,我们遇到了好多问题,在不断发现问题和解决问题中不断完善我们的设计,在不断完善中取得进步!
9参考文献
[1]涵.MCS-51/96系列单片机原理及应用[M].航空航天大学,1998.
[2]传友,晓斌.测控系统原理与设计[M].航空航天大学.2008.
[3]童诗白,华成英.模拟电子技术基础[M].高等教育.2001.
[4]红,黄韬,王进华,细端.基于增量式PID控制的数控恒流源[J].现代电子技术,2011,34(20):
190-192.
[5]晓娟,庆明,唐君明.基于单片机的数控恒流源设计[J].大学自然科学学报,2008,6:
21-44.
[6]东坡.基于单片机的数控恒流源设计与实现[J].仪器仪表,2008,(6):
58-60.
附录一电路图
附录二程序
#include
#include
#include
#include
#include
#include
//--------------------相关宏定义------------------------------//
#defineuintunsignedint
#defineucharunsignedchar
#definedelay4us(){_nop_();_nop_();_nop_();_nop_();}
//-----1602端口定义-----//
sbitRS=P2^5;
sbitRW=P2^6;
sbitE=P2^7;
//------ADC0808引脚定义------//
sbitCLK=P2^4;
sbitSTART=P2^0;
sbitEOC=P2^1;
sbitOE=P2^2;
//-----PWM输出口定义-----//
sbitPWMout=P3^3;
//-----标志位及变量定义-----//
bitflag1=0;
bitflag2=0;
ucharCYCLE;//周期
ucharPWM_ON=50;//低电平时间
uintten_minute=0;
uintone_minute=0;
uchari=0;
ucharDisplay_Buffer[]="00.00mA";
ucharcodeLine1[]="CurrentValue:
";
ucharvalue_buf[10];
//-----PID参数定义------//
intd;
ucharM=0;
doubleSetPoint;//设定恒流值
doubleError=0.0;//定义偏差
doubleerror1=0.0;//前一拍误差
doubleerror2=0.0;//前两拍误差
intLast_out=0;
intdd;
doubleKp;
//-----毫秒级延时子程序-----//
voidDelayMS(uintms)//延时程序
{
ucharx,j;
for(j=0;jfor(x=0;x<=148;x++);
}
//--------------------LCD1602相关子程序--------------------//
//-----查忙-----//
bitLCD_Busy_Check()
{
bitresult;
RS=0;
RW=1;
E=1;
delay4us();
result=(bit)(P0&0x80);
E=0;
returnresult;
}
//-----写指令-----//
voidLCD_Write_Command(ucharcmd)
{
while(LCD_Busy_Check());
RS=0;
RW=0;
E=0;
_nop_();
_nop_();
P0=cmd;
delay4us();
E=1;
delay4us();
E=0;
}
//-----设置显示位置-----//
voidSet_Disp_Pos(ucharpos)
{
LCD_Write_Command(pos|0x80);
}
voidLCD_Write_Data(uchardat)//写数据
{
while(LCD_Busy_Check());
RS=1;
RW=0;
E=0;
P0=dat;
delay4us();
E=1;
delay4us();
E=0;
}
//-----LCD初始化-----//
voidLCD_Initialise()//初始化
{
LCD_Write_Command(0x38);DelayMS(5);
LCD_Write_Command(0x0c);DelayMS(5);
LCD_Write_Command(0x06);DelayMS(5);
LCD_Write_Command(0x01);DelayMS(5);
}
voidLCD_SHOW(uintb)
{
Set_Disp_Pos(0x01);
for(i=0;i<14;i++)
{
LCD_Write_Data(Line1[i]);
}
Display_Buffer[0]=b/1000+'0';//数据显示
Display_Buffer[1]=b%1000/100+'0';
Display_Buffer[3]=b%100/10+'0';
Display_Buffer[4]=b%10+'0';
Set_Disp_Pos(0x46);
for(i=0;i<7;i++)
{
LCD_Write_Data(Display_Buffer[i]);
}
}
//--------------------读AD转换结果--------------------//
ucharGet_AD_Result()
{
inttt;
START=0;
START=1;
START=0;
while(EOC==0);
OE=1;
tt=P1;
OE=0;
returntt;
}
//-------------------PID算法-------------------//
voidPIDcal(doublePoint)
{
doublePID=0;
doublea,b,c;
Error=SetPoint-Point;
a=2.45*Error;
b=3.5*error1;
c=1.25*error2;
PID=(a-b+c)*Kp;//增量计算
error2=error1;//存放误差用于下次运算
error1=Error;
PWM_ON=Last_out+PID;
if(PWM_ON>CYCLE-1)PWM_ON=CYCLE;
if(PWM_ON<1)PWM_ON=1;
Last_out=PWM_ON;
}
ucharfilter()//移动平均滤波法
{
uchari;
doublesum=0;
intvalue;
for(i=0;i<9;i++)
{
value_buf[i]=value_buf[i+1];//所有数据左移,低位扔掉
sum+=value_buf[i];
}
value_buf[9]=Get_AD_Result();//采集到的数据放入最高位
sum+=value_buf[9];
//value=sum/10;
value=sum/10.0/5/31*25;
dd=sum*10.0/5/31*25;
return(value);
}
voidTime0(void)
{
IE=0x8a;
TMOD|=0x11;//定时器设置
IP=2;
TH0=(65536-200)/256;
TL0=(65536-200)%256;//T0定时0.2mS
TH1=(65536-20000)/256;//T1定时20ms
TL1=(65536-20000)%256;
TR0=1;//定时器打开
TR1=1;
}
voidtim(void)interrupt1//定时中断
{
staticunsignedcharcount;
TH0=(65536-200)/256;
TL0=(65536-200)%256;//定时0.2mS
count++;
if(count{
PWMout=1;//电平
}
else
{
PWMout=0;
if(count==CYCLE)//与所定义周期比较
{
count=0;
}
}
CLK=~CLK;
}
voidtimer()interrupt3//定时中断//定时200Ms读AD值
{
staticucharM;
TH1=(65536-20000)/256;
TL1=(65536-20000)%256;//20ms
M++;
if(M==10)
{
d=filter();
PIDcal(d);
M=0;
}
}
voidmain()
{
Time0();
CYCLE=200;
SetPoint=10;
Kp=2.4;
LCD_Initi