找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4590|回复: 2
收起左侧

半导体制冷片温度控制课程设计说明书(含单片机源码 wrod格式文档)

[复制链接]
ID:310129 发表于 2018-4-17 15:57 | 显示全部楼层 |阅读模式
课程设计说明书

题    目:半导体制冷片温度控制

摘  要
温度是工业中非常关键的一项物理量,在农业,现代科学研究和各种高新技术的开发和研究中也是一个非常普遍和常用的测量参数。温度控制的原理主要是:将随温度变化而变化的物理参数,通过温度传感器转变成电信号,传给计算机,与给定温度相减后得到偏差,经过控制器后输出给控制对象达到控温的目的。
半导体制冷片是利用半导体材料的Peltier效应,当直流电通过两种不同半导体材料串联成的电偶时,在电偶的两端即可分别吸收热量和放出热量,可以实现制冷的目的。制冷速度与通过的电流大小成正比。
本设计针对用半导体对水箱的制冷模型设计了相应模糊PI控制器对水箱进行计算机恒温控制。

引言
1  课程设计概述
1.1 课程设计题目
1.2 主要仪器设备
2  硬件设计
2.1 单片机部分
2.2 串行接口部分
2.3驱动电路部分
3 软件设计
3.1 流程图设计
3.1.1 温度控制主程序流程图
3.2 控制算法设计
3.2.1 控制对象模型
3.2.2 PI控制器设计
3.2.3 控制器的设计
4  系统调试
4.1 单片机程序仿真
4.2 STC12C5A08S2单片机系统电路调试
4.3 驱动电路调试
4.4 系统调试
5  总结与改进展望
6  谢辞
引言  
   温度作为一项热工参数,在工业现场和过程控制中具有至关重要的作用。半导体制冷相对于传统制冷方式,有着体积小,重量轻,无制冷剂而不污染环境,作用速度快,使用寿命长,且易于控制。本文介绍了使用DS18B20作为温度传感器的PWM半导体制冷控制系统。
1  课程设计概述1.1 课程设计题目
设计半导体制冷片的线性驱动电路和热敏元件的测温电路,再设计PI控制器来调节制冷电压,实现温度控制,控制范围15~25度,控制精度±0.5度,通过键盘进行温度设置,实际温度可以实时显示。
*附加要求:通过RS232或RS485接口与PC机通信,在PC机上进行参数显示和设置。

1.2 主要仪器设备
半导体制冷片(连水箱)    1台
示波器           1台
直流稳压电源 1台
数字万用表     1块
PC机         1台

2  硬件设计
整个系统以单片机STC12C5A08S2为核心部件。在08S2最小系统外围添加了按键,显示,与PC机的通信接口,以及光电耦合PC817和MOS管IRF9540构成的驱动电路。
2.1 单片机部分
本设计选择的单片机芯片是STC12C5A08S2,其原理图如2-1所示。该芯片的P0.0-P0.3用作键盘数字量输入,加入了上拉电阻按键未按下时始终处于高电平状态,读按键值前先给P0口赋值为0;
P1.0作为DS18B20的数据输入端口;
P2.0-P2.7作LCD1602的数据输出端口;
P4.4-P4.6作LCD1602的控制信号;
P1.3作为光耦合的控制信号;
P3.0和P3.1是STC12C5A08S2的串口,实现上电复位程序下载。

图 2-1 STC12C5A08S2最小系统原理图

2.2 串行接口部分
MAX232通过内部电压倍增及电压反向电路,把TTL电平与RS232电平互换,实现单片机与PC机的串口通信。
图 2-2  MAX232及串行接口原理图
2.3驱动电路部分
JPWM为P1.3口的PWM信号输入,作为光耦PC817的触发导通信号,从而产生MOS管IRP9540导通的触发信号,实现对右端负载的控制。如图2-3所示,本电路中还加入了拨动开关可对系统进行开关控制。

图 2-3  驱动部分原理图
3 软件设计3.1 流程图设计3.1.1 温度控制主程序流程图
温度控制主程序流程图设计如图 3-1所示
STC12C5A08S2中的主程序需要完成下几个工作:
  • 调用子函数对系统初始化,其中包括对自身的定时器T0,T1,I/O口,PWM口(P1.3),串口的初始化,以及对外部器件DS18B20和LCD1602的初始化;延时2S钟显示欢迎屏幕,等整个系统电压稳定后读取开机时的温度;
  • 调用子函数读取当前温度值
  • 调用子函数把当前读取的温度以及设定值通过串口送入PC机显示;
  • 调用子函数判断PC机是否有新的数据传送到单片机;
  • 调用子函数,把设定值与当前值相比较,对输出PWM进行控制;
  • 调用子函数刷新当前页面;
  • 调用子函数进行按键判断,依据按键值调用不同的子函数进行翻页或者设置;

图 3-1温度控制主程序流程图

3.2 控制算法设计3.2.1 控制对象模型
制冷片的水箱模型可近似地认为成一阶惯性环节,从而测量系统阶跃响应可模拟出系统的数学模型,G(s)=1/(T*s+1),其中T等于阶跃响应中调节时间Ts的四分之一。给电流I=0.5A时阶跃响应数据记录如下,其中t=0时,温度约为27℃;t=100时,温度约为24℃。取终值11KΩ的98%,Ts约为54min=3240s,则G(s)=1/(810*s+1)。
              1.由此看出,制冷系统是大惯性系统,制冷需要一段时间之后温度才开始下降;
2.至停止制冷后,温度还会有小幅度的下降,而设定温度越低,下降的幅度越小;
3.由于与外界的热交换,温度越低时,水箱的自然升温速度越快。

图 3-2 对象阶跃响应拟合曲线

3.2.2 PI控制器设计
PI调节器的微分方程为:y(t)=Kp[e(t)+1/Ti*∫e(t)dt]。控制器有两种算法,位置型和增量型。位置型算法时,计算每次实际值与设定值的偏差为e0,上次的偏差为e1,则控制量u=kp*e0+ki*(e0+e1)。增量型算法时,u+=e0*ki+(e1-e0)*kp。本次系统中选用的是位置型算法。
3.2.3 控制器的设计
     根据制冷片的滞后特点,为了使制冷片能迅速达到设定的温度,应该在离设定温度较远时给负载加上最大功率;又为了防止制冷片的大惯性的特性使系统产生严重的超调,需要提前在一定的范围内进行PI控制以达到最佳效果;而最后阶段,需要预先判断系统的停止工作点,让制冷片的温度扩散的整个水箱,此时停止制冷。
              若设定温度大于当前温度时,系统也将停止制冷,等温度慢慢回升。
现设定开始进入PI控制的温度上限为设定值T+1℃,而停止制冷的温度,根据多次实验建立的数据库如下:
设定值温度范围T℃
停止制冷温度t℃
23<=T
T*0.006
19<=T<23
T+0.7
T<19
T
4  系统调试4.1 单片机程序仿真
              由于PROTEUS中没有我们选用的STC12C5A08S2型号的单片机,因此使用AT89S2的单片机代替。仿真电路如下图所示,仿真时除初始化时当前温度显示为85℃以外,一切工作正常。

图 4-1 系统控制电路仿真电路图

4.2 STC12C5A08S2单片机系统电路调试
    STC12C5A08S2最小系统包括晶振和复位电路,按键电路,LCD显示,以及通信下载接口。
由于以前没有使用过这个型号的单片机,也没有做过串口下载器,所以先把串口接口芯片MAX232及其外部电容和单片机的晶振电路接在面包板上,通过串口与单片机连接调试下载功能,由于一开始电源和地之间没有接电容,因此系统不是很稳定,有时可以下载,有时不可以,接入电容之后系统比较稳定了。
依据插在面包板的电路图画原理图以及PCB,板子做出来之后,用万用表测试各点的连接特性,正常。上电,电源指示灯偏暗,把10K的限流电阻换为1K的之后指示灯工作正常。
由于STC12C5A08S2单片机运算速度比89S52快,因此程序中延时子函数一律乘以12。修改管脚使其适应实际的电路板,重新编译后下载程序。液晶没有显示,调节液晶显示偏压信号端的电压,使其接近地,液晶显示正常。接上DS18B20,温度显示正常。用按键进行翻页及设置,按键功能正常。据此,单片机系统板及程序完全工作正常。
4.3 驱动电路调试
驱动电路板做好后进行测试。用外用表测量,各点连接特性正常。分别把PWM输入端接地和接VCC,用示波器观察负载输出电压,输出电压对应为零和为12伏,工作正常,接入PWM信号后,输出变为零,不正常。
用示波器观察MOS管G极电压,发现为锯齿波,上升部分倾斜,下降部分竖直。分析原因为MOS管的S极与电源之间的电阻太大,使通过MOS管的电流太小,MOS管的电容特性使其在一定充电时间内电压不能达到导通,因此输出恒为零。把电阻调小,锯齿波顶部逐渐变平,电阻继续调小,输出的最低电压开始升高不为零。此时继续调节电阻已没有意义,在程序中把PWM输出的波形频率降低,降到最低14HZ。此时G极波形已为方波,继续减小电阻,直到G极输出的最低电压恰好为零,使其能通过更高频率的信号。最后稍微增大该电阻,使其电压被允许在一定范围内波动。
测量连接负载的D极,D极波形为与输入的PWM反向的方波,驱动电路工作正常。
4.4 系统调试
各个部分的调试完成以后,对整个系统进行调试,从室温约27.5℃开始,设置水箱的温度分别为26℃,23℃,20℃。
具体记录的数据如下所示。
表 6-5-1
设定值℃
最小值℃
最大值℃
超调量%
误差范围%
26
25.82
26.18
0.69
±0.69
23
22.88
23.18
0.52
±0.78
20
19.94
20.06
0.3
±0.3

加入算法后,超调量被控制在1%以下,温度下降速度较快,较稳定。
5          总结与改进展望
本次设计中,我完成了包括资料收集,系统设计及仿真,程序编写,电路图与PCB板的绘制腐蚀焊接及调试的全过程,整个系统完成测试后,性能稳定,基本达到了预期的目标。
                 水箱温度在29~10摄氏度范围内可控(设置值不大于当前室温),LCD液晶温度显示稳定,与之前购买的温度计有大约恒定1℃的温差。传送到PC机的数据显示正常,可以从PC机接收数据对各个参数进行设置。
    温度控制算法的设计,在原模糊分段控制的基础上,加上了PI控制,虽然最后由于时间关系,参数中只使用了P,但是可以证明,加入了PI控制的模糊算法比单纯的模糊分段控制取得了更好的效果。
              在本次设计中,也存在着可以改进的地方。例如程序中有部分程序段是几乎重复使用的,但在各种情况下,只使用了switch函数分情况讨论,没有总结出特定的函数对所有的情况进行处理,这导致了程序过长,应该还有可以压缩的空间。还有对于参数的调整,只使用了P,没有用到I,而且对于停止控制的位置,也还应该重新配合。这都是需要作出调整的,而且DS18B20检测温度只能精确到0.0625℃,若要再进一步提升各种指标的话,最好换一个精度更高的温度检测手段。
6  谢辞
本次设计能够完成得到了许多帮助,首先感谢赵学军老师,李平老师以及龙超老师的悉心指导,为我们提供了设计的思路,为我们指出了设计的各种不足指出,并一次次为我们解决了调试过程中出现的各种问题。正是有了他们的指导,我的设计才得以顺利完成。
感谢一同进行设计的同学们,是他们在我对着板子一筹莫展地时候给我指出了可能的错误,在调试过程中给予我各种意见,并且测量数据时给予我各种帮助,没有他们的帮助,我的设计不能得以完善。  
感谢一直教导我的任课老师,是任课老师的谆谆教导,使得我们可以学以致用,完成本次设计一定是基于扎实的理论课基础的。
最后感谢在本次设计中所有帮助过我的老师同学们。


附  录

主要电路PCB:

STC89C5A08S2最小系统
驱动电路
STC12C5A08S2单片机源程序如下:
  1. #include<STC_NEW_8051.h>
  2. #include<DS18B20.h>
  3. #include<LCD1602.h>
  4. #define keys P0
  5. sbit PWM=P1^3;
  6. uchar settemp[12]={'S','e','t',':',' ','2','6','.','0',' ',0xdf,'C'};
  7. ucharnowtemp[12]={'N','o','w',':','0','2','6','.','5','0',0xdf,'C'};
  8. uchar welcome[16]="Welcome! O(^_^)O";
  9. uchar number[13]="0800320101 CC";
  10. uchar e[4]={0,0,0,0};            
  11. uchar us[4]={0,0,0,0};
  12. uchar shou[4];
  13. uchar TL,TH,page,num=0,whi=0;
  14. int  fub=100,ki=0,kp=50;
  15. uchar fus[8]="Fu: 100 ",kps[8]="Kp: 050 ",kis[8]="Ki: 000 ";
  16. int TN,TD,Ntemp100,Stemp100=2600,e1=0,e0=0,u=0;
  17. bit busy;

  18. /***************显示设置**********************/
  19. void page0()//初始化欢迎页
  20. {
  21.               int i;
  22.               _1602_init();
  23.               _1602_writecode(0x00+0x80);//设置显示地址
  24.               for(i=0;i<16;i++)  //显示欢迎
  25.                             _1602_writedata(welcome[i]);
  26.               _1602_writecode(0x40+0x80);//设置显示地址
  27.               for(i=0;i<13;i++)  //显示学号姓名
  28.                             _1602_writedata(number[i]);
  29.               for(i=0;i<40;i++)
  30.                             delay(5000);
  31. }

  32. void page1()                 //温度显示页
  33. {
  34.               int i;
  35.               _1602_writecode(0x00+0x80);//设置显示地址
  36.               for(i=0;i<12;i++)  //显示设定温度
  37.                             _1602_writedata(settemp[i]);
  38.               _1602_writecode(0x40+0x80);//设置显示地址
  39.               for(i=0;i<12;i++)  //显示现在温度
  40.               if(Stemp100>2300)              stop=Stemp100*3/500;              //关断值的模糊控制
  41.               else if(1900<Stemp100<=2300) stop=7;
  42.               else stop=0;
  43.               e1=e0;
  44.               e0=Ntemp100-Stemp100;
  45.               e[3]=e0%10;
  46.               e[2]=(e0/10)%10;
  47.               e[1]=(e0/100)%10;
  48.               e[0]=(e0/1000);            
  49.               _1602_writecode(0x0c+0x80);//设置显示地址
  50.               for(i=0;i<4;i++)  //显示误差
  51.                             _1602_writedata(e[i]+0x30);
  52.               if(stop<e0<fub)//PI运算
  53.               {            
  54.                             u=e0*kp/10;
  55.                             u+=(e1+e0)*ki/10;
  56.                             if(u>255) u=255;
  57.                             if(u<0) u=0;
  58.               }
  59.               if(e0>=fub) u=0xff; //全开
  60.               if(e0<=stop) u=0x00;//关断
  61.               us[3]=u%10;
  62.               us[2]=(u/10)%10;
  63.               us[1]=(u/100)%10;
  64.               us[0]=(u/1000);
  65.               _1602_writecode(0x4c+0x80);//设置显示地址
  66.               for(i=0;i<4;i++)  //显示控制量
  67.                             _1602_writedata(us[i]+0x30);
  68.               CCAP0H=u;
  69. }
  70. /***********数据处理,控制********************/
  71. //改变占空比:CCAP0H=0xff-0xff*占空比/100=0xff-51/20*占空比              ;0x00,输出100%,停止制冷;
  72. /************按键判断处理********************/
  73. uchar keyin(void)              //单按键值判断,1--setting,2--up,4--down,8--enter
  74. {
  75.               uchar key,come=0;
  76.               keys=0x00;
  77.               delay(2);
  78.               key=keys&0x0f;
  79.               if(key!=0)              //防抖
  80.               s=settemp[6]-0x30;
  81.               x=seting2(0x06,s);
  82.               settemp[6]=x+0x30;
  83.               Stemp100+=x*100;

  84.               s=settemp[8]-0x30;
  85.               x=seting2(0x08,s);
  86.               settemp[8]=x+0x30;
  87.               Stemp100+=x*10;
  88. }
  89. void setingc(uchar n) //按键的参数设置
  90. {
  91.               uchar s,i;
  92.               switch(n)
  93.               {
  94.                             case 0:{              fub=0;                                                        //模糊量
  95.                                                                       for(i=4;i<7;i++)
  96.                                                                       {
  97.                                                                                     s=fus[i]-0x30;
  98.                                                                                     s=seting2(i,s);
  99.                                                                                     fub=fub*10+s;
  100.                                                                                     fus[i]=s+0x30;
  101.                                                                       }
  102.                                                                                     break;
  103.                                                         }
  104.                             case 1:{              kp=0;                                                                        
  105.                                                                       for(i=4;i<7;i++)
  106.                                                                       {
  107.                                                                                     s=kps[i]-0x30;
  108.                                                                                     s=seting2(i+0x40,s);
  109.                                                                                     kp=kp*10+s;
  110.                                                                                     kps[i]=s+0x30;
  111.                                                                       }
  112.                                                                                     break;
  113.                                                         }
  114.                             case 2:{              ki=0;
  115.                                                                       for(i=4;i<7;i++)
  116.                                                                       {
  117.                                                                                     s=kis[i]-0x30;
  118.                                                                                     s=seting2(i+0x48,s);
  119.                                                                                     ki=ki*10+s;
  120.                                                                                     kis[i]=s+0x30;
  121.                                                                       }
  122.                                                                                     break;
  123. {
  124.                                                                                                   kps[i+3]=shou[i];
  125.                                                                                                   s=shou[i]-0x30;
  126.                                                                                                   kp=kp*10+s;
  127.                                                                                     }
  128.                                                                                     shou[0]=0;
  129.                                                                                     break;
  130.                                                                       }
  131.                             case 'I':              {                                                                                    //变量ki
  132.                                                                                     ki=0;
  133.                                                                                     for(i=1;i<4;i++)
  134.                                                                                     {
  135.                                                                                                   kis[i+3]=shou[i];
  136.                                                                                                   s=shou[i]-0x30;
  137.                                                                                                   ki=ki*10+s;
  138.                                                                                     }
  139.                                                                                     shou[0]=0;
  140.                                                                                     break;
  141.                                                                       }
  142.               }
  143. }
  144. /***********按键判断处理**********************/
  145. /*************PWM初始化********************/
  146. void PWM_init()              //PWM初始化
  147. {
  148.               TMOD=0x22;//T0工作在方式2,8位重装
  149.               TH0=0x00;
  150.               TR0=1; //开始计数
  151.               CCON=0x00;//关PCA
  152.               CH=0; CL=0;              //计数寄存器清零
  153.               CMOD=0x04;//始终工作;f=定时器0溢出频率;PWM模式禁止中断
  154.               CCAPM0=0X42; //PCA0工作在PWM模式
  155.               PCA_PWM0=0x00; //若此为为0x02,则输出恒为0;若要调整占空比,需赋值为0;
  156.               CCAP0H=0x00;//输出占空比100%
  157.               CR=1;  //开始计数
  158. }

  159. /**************PWM初始化*******************/
  160. /*************串口初始化********************/
  161. void Uart_init(void)
  162. {
  163.               IE=0x90;
  164.               void main()
  165. {
  166.               uchar key,i;
  167.               P4SW=0x70;//P4为IO口
  168.               page=1;                                                        //默认页为第一页
  169.               PWM_init();
  170.               _1602_init();
  171.               Uart_init();                            //串口初始化
  172.               page0();                              //显示初始化欢迎页
  173.               _1602_writecode(0x01);//清屏
  174.               delay(50);//清屏后若无延时则第一个字符显示不出
  175.               sent_pc(welcome,16);
  176.               sent_pc_byte('\r');  //13,10合起来为回车
  177.               sent_pc_byte('\n');
  178.               sent_pc(settemp,10);
  179.               sent_pc(nowtemp,10);
  180.               while(1)
  181.               {
  182. k1:                            gets();                                                        //读取当前温度
  183.                             sent_pc_byte('\r');  //13,10合起来为回车
  184.                             sent_pc_byte('\n');
  185.                             sent_pc(settemp,10);   //给PC机送设定温度以及当前温度
  186.                             sent_pc(nowtemp,10);
  187.                             control();                                          //进行控制
  188.                             if(page==1)
  189.                             {
  190.                                           page1();              //显示当前温度页
  191.                                           key=keyin();//判断键值
  192.                                           switch(key)
  193.                                           {
  194.                                                         case 1:              {CCAP0H=0x00;setingt(); goto k1;} //进行设置
  195.                                                         case 2:                                          
  196.                                                         case 4: {              _1602_writecode(0x01);
  197.                                                                                     delay(50);//清屏
  198.                                                                                     page=2; }  //上下翻页
  199.                                           }
  200.                             }
  201.                             if(page==2)
  202.                             {
  203.                                           page2();              //显示参数设定页
  204.                                           key=keyin();//判断键值
  205.                                           switch(key)
  206. _1602_writedata(nowtemp[i]);
  207. }
  208. void page2()//参数显示页
  209. {
  210.                  int i;
  211.                  _1602_writecode(0x00+0x80);//设置显示地址
  212.                  for(i=0;i<8;i++)  //显示Fuzzy
  213.                             _1602_writedata(fus[i]);
  214.               _1602_writecode(0x40+0x80);//设置显示地址
  215.                  for(i=0;i<8;i++)  //显示kp
  216.                             _1602_writedata(kps[i]);
  217.               for(i=0;i<8;i++)  //显示ki
  218.                             _1602_writedata(kis[i]);
  219.               _1602_writecode(0x0c+0x80);//设置显示地址
  220.               _1602_writedata(whi+0x30);
  221.               _1602_writedata(' ');
  222.               _1602_writedata(' ');
  223.               _1602_writedata(' ');
  224. }
  225. /**************显示设置*********************/
  226. ……………………

  227. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

完整的Word格式文档51黑下载地址:
半导体制冷片温度控制.doc (228.5 KB, 下载次数: 98)
回复

使用道具 举报

ID:142268 发表于 2020-5-4 22:21 | 显示全部楼层
代码可打包发下吗

回复

使用道具 举报

ID:791503 发表于 2020-7-15 11:29 | 显示全部楼层
我看到驱动部分还有H桥的,这几种驱动有啥区别呢?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表