《基于PID算法的恒温控制系统设计(共18页).docx》由会员分享,可在线阅读,更多相关《基于PID算法的恒温控制系统设计(共18页).docx(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上课程设计说明书题目:基于PID算法的恒温控制系统设计 学号:姓名:指导教师: 日期: 专心-专注-专业目录一、设计题目基于PID算法的恒温控制系统设计二、设计要求1. 利用DS18B20采集温度并显示;2. 利用单片机I/O管角输出PWM控制功率电阻发热;3. 基于PID算法实现恒温控制。三、设计思路本设计要求实时采集温度并实现恒温控制,根据设计要求,本次设计拟采用AT89C52单片机作为控制芯片,采集部分使用DS18B20温度传感器,显示部分采用数码管显示实时温度,功率电阻作为控制对象。在PID算法的基础上完成恒温控制系统的设计。四、 实验设备单片机开发试验仪1台A
2、T89C52单片机芯片1个DS18B20温度传感器1个C9013三极管1个1W功率二极管1个五、 硬件介绍DS18B20:DS18B20是常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20的主要特征: 全数字温度转换及输出。 先进的单总线数据通信。 最高12位分辨率,精度可达土0.5摄氏度。 12位分辨率时的最大工作周期为750毫秒。 可选择寄生工作方式。 检测温度范围为55C +125C (67F +257F) 内置EEPROM,限温报警功能。 64位光刻ROM,内置产品序列号,方便多机挂接。 多样封装形式,适应不同硬件系统。DS18B20数据采集过程 GN
3、D 地信号 DQ 数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源。 VDD 可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。由于DS18B20采用的是1Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。 由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序
4、。所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。数据和命令的传输都是低位在先。六、 硬件接线图AT89C52恒温控制系统硬件连接图八位七段码显示P0P1P2.0P3.7 1W C9013 DS18B20硬件部分分别也P0口和P1口作为八位七段码的段选和位选的控制端口,DS18B20连接至P3.1口作为控制线,P2.0口作为PWM波输出口,经过C9013信号放大后接功率电阻作为被控对象。通过温度传感器采集电阻上的温度反馈给系统,构成闭环调节系统,构成恒温控制系统。
5、七、 软件流程图、A/DD/A被控对象开始计算采样初值设初值e(k-1)=e(k-2)=0本次采样输入c(k)计算偏差量e(k)=r(k)-c(k)计算控制增量u(k)u(k)=q0e(k)-q1e(k-1)+q2e(k-2)输出u(k)为下一时刻做准备e(k)=e(k-1),e(k-1)=e(k-2)采样时刻到否PID算法流程图软件部分采用PID算法,其中数据采集与显示部分不属于本设计的主要部分在此不再赘述。PID算法的参数有实验确定,遵循先比例,后积分,再微分的原则,从最小看是逐步调试,最终取得最佳的PID参数。八、PID参数确定PID算法运用比例、积分、微分算法,来对回路中的偏差进行修正
6、,通过执行器调节参数,使测量值稳定在设定值附近,达到控制某一参数的目的。 必须先明白P,I,D各自的含义及控制规律比例P:比例项部分其实就是对预设值和反馈值差值的发大倍数。积分I:顾名思义,积分项部分其实就是对预设值和反馈值之间的差值在时间上进行累加。当差值不是很大时,为了不引起振荡。可以先让电机按原转速继续运行。当时要将这个差值用积分项累加。当这个和累加到一定值时,再一次性进行处理。从而避免了振荡现象的发生。可见,积分项的调节存在明显的滞后。而且I值越大,滞后效果越明显。微分D:微分项部分其实就是求电机转速的变化率。也就是前后两次差值的差而已。也就是说,微分项是根据差值变化的速率,提前给出一
7、个相应的调节动作。可见微分项的调节是超前的。并且D值越大,超前作用越明显。可以在一定程度上缓冲振荡。比例项的作用仅是放大误差的幅值,而目前需要增加的是“微分项”,它能预测误差变化的趋势,这样,具有比例+微分的控制器,就能够提前使抑制误差的控制作用等于零,甚至为负值,从而避免了被控量的严重超调其次进行参数调整a.确定比例增益P 确定比例增益P 时,首先去掉PID的积分项和微分项,一般是令Ti=0、Td=0,PID为纯比例调节。输入设定为系统允许的最大值的60%70%,由0逐渐加大比例增益P,直至系统出现振荡;再反过来,从此时的比例增益P逐渐减小,直至系统振荡消失,记录此时的比例增益P,设定PID
8、的比例增益P为当前值的60%70%。比例增益P调试完成。b.确定积分时间常数Ti比例增益P确定后,设定一个较大的积分时间常数Ti的初值,然后逐渐减小Ti,直至系统出现振荡,之后在反过来,逐渐加大Ti,直至系统振荡消失。记录此时的Ti,设定PID的积分时间常数Ti为当前值的150%180%。积分时间常数Ti调试完成。c.确定积分时间常数Td积分时间常数Td一般不用设定,为0即可。若要设定,与确定 P和Ti的方法相同,取不振荡时的30%。九、 实验总结本次课程设计的题目为基于PID算法的恒温控制系统。在接到这个题目的同时,我们就开始思考如何去设计这个系统。首先是硬件电路的设计与器件的选择。其中温度
9、采集与显示部分的设计,我们在单片机课程上已经有所涉及,在这里我们就可以直接拿来用了。硬件部分需要我们设计的就是被控对象。为了试验方便我们选择了1W的功率电阻作为被控对象,然后通过DS18B20温度传感器去测量电阻附近的温度变化。从而实现系统的控制与反馈。考虑到单片机I/O口的驱动能力不足,不足以驱动功率二极管,我们在I/O口与功率二极管之间串入一个C9013最为驱动与开关器件,用以对二极管的驱动和控制。软件部分采用了PID控制算法,其中最重要的环节为PID控制参数的确定,一开始我们准备利用计算法来确定,可是在实施的过程终发现,计算法所需要的原始数据难以确定,而且在实际测量中也有很大的不确定性。
10、最终,经过我们的分析研究,得出实验法确定参数是一个比较切实可行的办法。然后就通过实验一步一步测试出所需要的参数,经过我们几天的而艰苦奋战,终于测试好了参数。最后在进行系统的整体调试,最终完成这次课程设计,并顺利通过老师的验收。这次的课程设计,让我有了很多的收获和感受。首先,让我认识到了,在学习的过程中仅仅有理论知识是不足的,必须要理论与实践相结合起来。有的东西看起来非常简单,可是到了实现环节,就会变得异常困难。在实现的过程中可能会出现各种各样的状况,需要在现场分析解决。在最任何事情的时候都必须认真细致,有时一个小小的环节出现问题,都会导致结果出现巨大的差异。在最任何是的过程中遇到困难都是正常的
11、,我们需要做的就是去面对它,通过自己的分析理解,最终找到解决方法,克服困难。附件:实验程序/* * 微机控制课程设计-* 实 验 名 : 基于PID算法的恒温控制系统设计* 实验说明 : 通过DS18B20采集温度,反馈给系统,构成闭环调节系统* 连接方式 : 见连接图* 注 意 : */#include#includetemp.h/-定义使用的IO-/#define GPIO_DIG P0#defineGPIO_PLACE P1sbit PWM=P20;/-定义全局变量unsigned char code DIG_PLACE8 = 0xfe,0xfd,0xfb,0xf7,0xef,0xdf,
12、0xbf,0x7f;/位选控制 查表的方法控制unsigned char code DIG_CODE17 = 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71;/0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char DisplayData8;unsigned char timer1;unsigned int count=0;/用来存放要显示的8位数的值/定义PID参数 float uk,uk1,uk2;float ek,ek1,ek2;flo
13、at x;float t,Auk;float Kp,Ki,Kd;/-声明全局函数-/float LcdDisplay(int);void DigDisplay();void Time1Config();float AD_init(void);void PID_init(void);void DA_init(void);/void delay();unsigned int j,m;unsigned int d;/* 函 数 名 : main* 函数功能 : 主函数* 输 入 : 无* 输 出 : 无*/main() int m;m=Auk/10; Time1Config();Ds18b20Ini
14、t(); uk=0,uk1=0,uk2=0;ek=0,ek1=0;ek2=0;x=40;Kp=2.83,Ki=0.59,Kd=5.41;while(1)AD_init();PID_init();DA_init(); LcdDisplay(Ds18b20ReadTemp();/delay();float AD_init() float temp;temp=LcdDisplay(Ds18b20ReadTemp(); return(temp);void PID_init()t=AD_init();ek=x-t;Auk=Kp*(ek-ek1);if(x=35&x=0) count+; if(Auk=5
15、) count=count+5; if(Auk100) /PWM周期为100*0.5mstimer1=0;if(timer1 count)/改变30这个值可以改变直流电机的速度PWM=1;elsePWM=0;/* 函 数 名 : LcdDisplay()* 函数功能 : LCD显示读取到的温度* 输 入 : v* 输 出 : 无*/*void delay()for(j=0;j1000;j+)for(m=0;m100;m+); */float LcdDisplay(int temp) /lcd显示 float tp; if(temp 0)/当温度值为负数 DisplayData0 = 0x40;
16、 /因为读取的温度是实际温度的补码,所以减1,再取反求出原码temp=temp-1;temp=temp;tp=temp;temp=tp*0.0625*100+0.5;/留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点/后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就/算由?.5,还是在小数点后面。 else DisplayData0 = 0x00;tp=temp;/因为数据处理有小数点所以将温度赋给一个浮点型变量/如果温度是正的那么,那么正数的原码就是补码它本身temp=tp*0.0625*100+0.5;/留两个小
17、数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点/后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就/算加上0.5,还是在小数点后面。DisplayData1 = DIG_CODEtemp / 10000;DisplayData2 = DIG_CODEtemp % 10000 / 1000;DisplayData3 = DIG_CODEtemp % 1000 / 100 | 0x80;DisplayData4 = DIG_CODEtemp % 100 / 10;DisplayData5 = DIG_CODEtemp % 10;
18、DigDisplay();return(temp); /扫描显示/* 函 数 名 : DigDisplay* 函数功能 : 使用数码管显示* 输 入 : 无* 输 出 : 无*/void DigDisplay()unsigned char i;unsigned int j;for(i=0; i0; y-)for(x=110; x0; x-);/* 函 数 名 : Ds18b20Init* 函数功能 : 初始化* 输 入 : 无* 输 出 : 初始化成功返回1,失败返回0*/uchar Ds18b20Init()uchar i;DSPORT = 0; /将总线拉低480us960usi = 70
19、;while(i-);/延时642usDSPORT = 1;/然后拉高总线,如果DS18B20做出反应会将在15us60us后总线拉低i = 0;while(DSPORT)/等待DS18B20拉低总线Delay1ms(1);i+;if(i5)/等待5MSreturn 0;/初始化失败return 1;/初始化成功/* 函 数 名 : Ds18b20WriteByte* 函数功能 : 向18B20写入一个字节* 输 入 : com* 输 出 : 无*/void Ds18b20WriteByte(uchar dat)uint i, j;for(j=0; j= 1;/* 函 数 名 : Ds18b2
20、0ReadByte* 函数功能 : 读取一个字节* 输 入 : com* 输 出 : 无*/uchar Ds18b20ReadByte()uchar byte, bi;uint i, j;for(j=8; j0; j-)DSPORT = 0;/先将总线拉低1usi+;DSPORT = 1;/然后释放总线i+;i+;/延时6us等待数据稳定bi = DSPORT; /读取数据,从最低位开始读取/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/byte = (byte 1) | (bi 7); i = 4;/读取完之后等待48us再接着读取下一个数while(i-);
21、return byte;/* 函 数 名 : Ds18b20ChangTemp* 函数功能 : 让18b20开始转换温度* 输 入 : com* 输 出 : 无*/void Ds18b20ChangTemp()Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc);/跳过ROM操作命令 Ds18b20WriteByte(0x44); /温度转换命令/Delay1ms(100);/等待转换成功,而如果你是一直刷着的话,就不用这个延时了 /* 函 数 名 : Ds18b20ReadTempCom* 函数功能 : 发送读取温度命令* 输 入 : com* 输
22、 出 : 无*/void Ds18b20ReadTempCom()Ds18b20Init();Delay1ms(1);Ds18b20WriteByte(0xcc); /跳过ROM操作命令Ds18b20WriteByte(0xbe); /发送读取温度命令/* 函 数 名 : Ds18b20ReadTemp* 函数功能 : 读取温度* 输 入 : com* 输 出 : 无*/int Ds18b20ReadTemp()int temp = 0;uchar tmh, tml;Ds18b20ChangTemp(); /先写入转换命令Ds18b20ReadTempCom();/然后等待转换完后发送读取温度命令tml = Ds18b20ReadByte();/读取温度值共16位,先读低字节tmh = Ds18b20ReadByte();/再读高字节temp = tmh;temp = 8;temp |= tml;return temp;