找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2152|回复: 1
收起左侧

温度控制课程设计

[复制链接]
ID:193753 发表于 2017-4-26 11:12 | 显示全部楼层 |阅读模式
  1. #include<reg52.h>
  2. #include<serial.h>
  3. #include<math.h>
  4. #include <intrins.h>
  5. #define uchar unsigned char
  6. #define uint  unsigned int

  7. #define target 65                                                        //设定温度目标值
  8. int aa=0,bb=0;                                    // aa,bb是用于显示时间的变量
  9. signed long  error=0,d_error=0,dd_error=0;        //相当于公式中的e(k),e(k-1),e(k-2);
  10. int k=14,ti=5;td=16,det_t,pwm,m=0;
  11. //unsigned char YSJS=0;
  12. float t;


  13. uint tmpvalue=0, value;   //tmpvalue是暂时值 value是最终温度值
  14. int high,low;
  15. sbit P23=P2^3;
  16. sbit P22=P2^2;
  17. sbit DQ = P2^1;                 //P2.1作为连接DS18B20的I/O口
  18. sbit p0=P1^0;
  19. sbit p1=P1^1;
  20. sbit p2=P1^2;
  21. sbit p3=P1^3;                  //P1.3和P1.4作为升温电路的控制端
  22. sbit p4=P1^4;                                                                                   
  23. sbit p5=P1^5;        //P1.5~P1.7控制八个七段数码管的亮灭
  24. sbit p6=P1^6;
  25. sbit p7=P1^7;


  26.                

  27. void delayms(int o)   //用于数码管显示的延时
  28. {
  29.     unsigned char a1,b1,c1;
  30.         int x=o;
  31.         for(;o>0;o--)
  32.     for(c1=4;c1>0;c1--)
  33.         for(b1=21;b1>0;b1--)
  34.             for(a1=14;a1>0;a1--);
  35.                         }
  36. void init()                 //定时器初始化
  37. {       
  38.         TMOD=0x21;
  39.         TH0=(65536-50000)/256;
  40.         TL0=(65536-50000)%256;
  41.         EA=1;
  42.         ET0=1;
  43.         TR0=1;       
  44. }

  45. /***************八段管显示码***************/

  46. code uchar LEDmap[]  ={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};
  47. code uchar BITaddr[] ={0x0f, 0x2f, 0x4f, 0x6f, 0x8f, 0xaf, 0xdf, 0xef};                          //数码管位选地址
  48. uchar code LEDmap1[] ={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};        //带小数点数字编码

  49. /***************ds18b20的程序***************/

  50. void delay(unsigned int i)
  51. {
  52.         while(i--);
  53. }
  54. void Init_DS18B20(void)
  55. {
  56.         unsigned char x=0;
  57.         DQ = 1; //DQ复位
  58.         delay(8); //稍做延时
  59.         DQ = 0; //单片机将DQ拉低
  60.         delay(80); //精确延时 大于 480us
  61.         DQ = 1; //拉高总线
  62.         delay(14);
  63.         x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  64.         delay(20);
  65. }

  66. //读一个字节
  67. int ReadOneChar()
  68. {
  69.         unsigned char i=0;
  70.         unsigned char dat = 0;
  71.         for (i=8;i>0;i--)
  72.                 {
  73.                         DQ = 0; // 给脉冲信号
  74.                         dat>>=1;
  75.                         DQ = 1; // 给脉冲信号
  76.                         if(DQ)
  77.                         dat|=0x80;
  78.                         delay(4);
  79.                 }
  80.         return(dat);
  81. }

  82. //写一个字节
  83. void WriteOneChar(unsigned char dat)
  84. {
  85.         unsigned char i=0;
  86.         for (i=8; i>0; i--)
  87.                 {
  88.                         DQ = 0;
  89.                         DQ = dat&0x01;
  90.                         delay(5);
  91.                         DQ = 1;
  92.                         dat>>=1;
  93.                 }
  94. }

  95. //DS18B20程序读取温度
  96. void ReadTemperature()
  97. {
  98.         Init_DS18B20();
  99.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  100.         WriteOneChar(0x44); // 启动温度转换
  101.         Init_DS18B20();
  102.         WriteOneChar(0xCC); //跳过读序号列号的操作
  103.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  104.         low=ReadOneChar();
  105.         high=ReadOneChar();
  106.         tmpvalue = high;
  107.         tmpvalue =(tmpvalue<<8);
  108.         tmpvalue=tmpvalue | low;
  109.         value=tmpvalue*0.0625;
  110.         t=tmpvalue*0.625;
  111. }               
  112. /***************主函数****************/

  113. void main()
  114. {  
  115.    int i=0;       
  116.    init();                 //初始化子程序
  117.    uart_init();
  118.     P23 = 1;
  119.    P22 = 1;
  120.    delayms(9500);
  121.    P23 = 0;
  122.    P22 = 0;
  123.    while(1)
  124.                    {
  125.                                                
  126.                    if((bb%3)==0)                  //每三秒扫描一次 ,采样周期3s
  127.                                 {                       
  128.                                     dd_error=d_error;
  129.                                         d_error=error;               
  130.                                         error = (signed long)(target-value);//求e(k)             //求e(k-1)            //求e(k-2)                                                                                                                                                         
  131.                                         det_t=k*(error-d_error)+(k*3/ti)*error+(k*td/3)*(error-2*d_error+dd_error);                //增量公式           */
  132.       // det_t=20*(error-d_error)+0.15*error+10*(error-2*d_error+dd_error);                //增量公式           */


  133.                                         pwm=det_t;
  134.                                         if((error>10)||(pwm>60))pwm=60;       
  135.                                 }                                                                                               
  136.                                         ReadTemperature();                                                               
  137.                                         p5=0;p6=0;p7=0;P0=LEDmap[bb%10];delayms(1);                           //在数码管上显示时间
  138.                                         p5=1;p6=0;p7=0;P0=LEDmap[bb%100/10];delayms(1);                  
  139.                                         p5=0;p6=1;p7=0;P0=LEDmap[bb%1000/100];delayms(1);
  140.                                         p5=1;p6=1;p7=0;P0=LEDmap[bb/1000];delayms(1);                   //
  141.                                         p5=0;p6=0;p7=1;P0=LEDmap[(int)t%10];delayms(1);                   //温度小数显示
  142.                                         p5=1;p6=0;p7=1;P0=LEDmap1[value%10];delayms(1);                   //温度个位及小数点显示
  143.                                         p5=0;p6=1;p7=1;P0=LEDmap[value%100/10];delayms(1);           //温度十位显示                                                                                                                                                                               
  144.                                 if(i++>100)
  145.                         {
  146.                             Uart_SendChar(0x5a);                          
  147.                                         Uart_SendChar(value%100/10);
  148.                             Uart_SendChar(value%10);
  149.                             Uart_SendChar((int)t%10);
  150.                             Uart_SendChar(0);
  151.                             i=0;
  152.                         }               

  153.        
  154.                 }
  155. }                 

  156. void timer0()          interrupt 1
  157. {
  158.         TH0=(65536-50000)/256;
  159.         TL0=(65536-50000)%256;
  160.         aa++;
  161.         if(aa==20){aa=0;bb++;}        //计时1s
  162.         if(m<pwm){p3=1;p4=1;}        //电机启动,加热
  163.         if((m>=(pwm))||(value>=target)){p3=0;p4=0;} //电机关闭,停止加热
  164.         if(m==60)m=0;                                                               
  165.          m++;               
  166. }
复制代码

从硬件电路开始学习,然后编写程序对加热杯内的水温进行控制。能够完成水温在
65摄氏度的稳定性实验,并计算了超调和稳态误差。
升温速率可以为1--4/分钟,分阶段升温编制信号采样程序,转换显示以及在数码管上时钟显示(秒表)。达到设定温度稳定后加入扰动,控制加热算法,使其快速达到温度设定值。

回复

使用道具 举报

ID:190190 发表于 2017-5-5 12:04 | 显示全部楼层
有图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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