单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12466|回复: 55
收起左侧

基于51单片机+PID恒温控制器制作

  [复制链接]
离谱 发表于 2017-7-5 22:26 | 显示全部楼层 |阅读模式
制作一个简易的恒温控制器学习PID。
使用到ds18b20 5V加热器(TB有卖) 场效应管IRF 640N用于开通和关断加热器。
设置预设值,通过PID不断矫正加热器输出,达到预设温度。 IMG_20170705_221614_HHT.jpg

引脚分配    lcd    lcddata:    P0
            lcd_e:        P2^7
            lcd_rs:        P2^6
            lcd_rw:        P2^5
        
        设置按键    limit_choise:        P    //温度上下限选择按键
                increase_temperature        P    //增加温度限值按键
                reduce_temperature        P    //减少温度限值按键
        
        蜂鸣器报警    warning        P   

        温度传感器    temperature_sensor    P

        制热    heatting    P

        制冷    refrigerating    P

        LED显示        normal        P    //正常温度指示灯
                high_temperature    P    //高温指示灯
                low_temperature        P    //低温指示灯   

单片机源程序如下:
  1. #include <main.h>
  2. extern unsigned char time_value;
  3. extern bit flag;
  4. int   PWM=0;
  5. int  PWM_I,PWM_P;
  6. unsigned char time_value=0;
  7. bit  flag;
  8. uint temp_m1=0;
  9. int temp_m=0;  //温度放大100倍后的中转值
  10. int set_temp=0; //设置温度*100
  11. void InitTimer0(void)
  12. {
  13.     TMOD = 0x01;
  14.     TH0 = 0x0EC;
  15.     TL0 = 0x078;
  16.     EA = 1;
  17.     ET0 = 1;
  18.     TR0 = 1;
  19. }
  20. void main()//主函数
  21. {
  22.     init();//初始化函数
  23.         pid_init (&temp_PID);
  24.         InitTimer0();
  25.     temp_PID.Proportion =120;              //  Set PID Coefficients
  26.     temp_PID.Integral   =5;
  27.     temp_PID.Derivative =2;
  28.    
  29.         
  30.         
  31.   while(1)
  32.         {
  33.                 temp_control();//控制按键函数
  34.                 if(time_value<PWM)      { heatting=1;}else { heatting=0;}
  35.                
  36.                  if(time_value==30)            
  37.                 {
  38.                
  39.                 display_real_tenp(temp_m1);
  40.                 }//显示函数        
  41.                 if(time_value==60)      temp_m=unnormal_proccessing(temp_m1);//温度转换函数*100
  42.                   if(time_value==100)
  43.          {
  44.                   
  45.                    if(set_temp-temp_m>250)
  46.                    {
  47.                                       PWM=PWM_MAX;
  48.                    }
  49.                    else
  50.                    {
  51.            PWM_I=pid_calc(&temp_PID,temp_m);
  52.            PWM  =PWM_I ;
  53.            if( PWM>=100)PWM=100;
  54.            else if(PWM<=PWM_MIN)  PWM=PWM_MIN;
  55.                    }
  56.                   
  57.                   
  58.                   }
  59.                    if(time_value==120)
  60.          {                PWM_P=PWM/2;
  61.                         LcdWriteCom(0x80+0X40+0x0C);
  62.                                 LcdWriteData('0'+PWM_P/100);
  63.                                  LcdWriteCom(0x80+0X40+0x0D);
  64.                                 LcdWriteData('0'+PWM_P%100/10);
  65.                                 LcdWriteCom(0x80+0X40+0x0E);
  66.                                 LcdWriteData('0'+PWM_P%10);
  67.                  }
  68.         }               
  69. }

  70. void init()//初始化函数
  71. {
  72.         uint i,j;
  73.         //函数初始化
  74.         LcdInit();//LCD初始化函数
  75.         Ds18b20Init();
  76.         
  77.         //I/O口初始化
  78.         heatting=0;//不制热

  79.         
  80.         //LCD初始化显示
  81.         LcdWriteCom(0x80);//第一行显示
  82.         j=strlen(num1);
  83.         for(i=0; i<j; i++)
  84.         {
  85.                 LcdWriteData(num1[i]);        
  86.                 delay_ms(1);
  87.         }
  88.         LcdWriteCom(0x80+0x40);//第二行显示
  89.         j=strlen(num2);
  90.         for(i=0; i<j; i++)
  91.         {
  92.                 LcdWriteData(num2[i]);        
  93.                 delay_ms(1);
  94.         }
  95.         LcdWriteCom(0x04);  //关闭写一个指针加1
  96. }

  97. uint get_temp(uint temp)//计算温度函数
  98. {
  99.         float tp;
  100.         
  101.         tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
  102.         //如果温度是正的那么,那么正数的原码就是补码它本身
  103.         temp=tp*0.0625*100+0.5;        
  104.         //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
  105.         //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
  106.         //算加上0.5,还是在小数点后面。
  107.         return temp;
  108. }

  109. void display_real_tenp(uint temp)//实时温度显示函数
  110. {
  111.         uchar datas[] = {0, 0, 0, 0}; //定义数组

  112.         datas[0] = temp % 10000 / 1000;
  113.         datas[1] = temp % 1000 / 100;
  114.         datas[2] = temp % 100 / 10;
  115.         datas[3] = temp % 10;

  116.         LcdWriteCom(0x80+0x0a);                 //写地址 80表示初始地址
  117.         LcdWriteData('0'+datas[0]); //十位

  118.         LcdWriteCom(0x80+0x0b);        //写地址 80表示初始地址
  119.         LcdWriteData('0'+datas[1]); //个位

  120.         LcdWriteCom(0x80+0x0d);         //写地址 80表示初始地址
  121.         LcdWriteData('0'+datas[2]); //显示小数点  

  122.         LcdWriteCom(0x80+0x0e);                 //写地址 80表示初始地址
  123.         LcdWriteData('0'+datas[3]); //显示小数点  

  124. }

  125. void temp_control()//控制温度上下限函数
  126. {
  127.         if(limit_choise==0)//选择按键
  128.         {
  129.                 delay_ms(5);
  130.                 if(limit_choise==0)
  131.                 {
  132.                         while(!limit_choise);
  133.                         limit_choise_num++;
  134.                         if(limit_choise_num>=2)
  135.                         {
  136.                                 limit_choise_num=0;
  137.                         }
  138.                 }
  139.         }
  140.         if(limit_choise_num==0)//正常显示
  141.         {
  142.                 LcdWriteCom(0x0c);//关闭光标
  143.         
  144.         }
  145.                         
  146.         if(limit_choise_num==1)//调节上限温度
  147.         {
  148.                 LcdWriteCom(0x80+0X40+2);
  149.                 LcdWriteCom(0x0f);//开启光标
  150.                 if(increase_temperature==0)//增加温度
  151.                 {
  152.                         delay_ms(5);
  153.                         if(increase_temperature==0)
  154.                         {
  155.                                 while(!increase_temperature);
  156.                                 up_limit_temp++;
  157.                                 if(up_limit_temp>=100)
  158.                                 {
  159.                                         up_limit_temp=0;
  160.                                 }
  161.                                 //写入新数据
  162.                                 LcdWriteCom(0x80+0X40+0x03);
  163.                                 LcdWriteData('0'+up_limit_temp/10);
  164.                                 LcdWriteCom(0x80+0X40+0x04);
  165.                                 LcdWriteData('0'+up_limit_temp%10);
  166.                                 LcdWriteCom(0x80+0X40+2);//光标回写
  167.                         }
  168.                 }
  169.                 if(reduce_temperature==0)//减少温度
  170.                 {
  171.                         delay_ms(5);
  172.                         if(reduce_temperature==0)
  173.                         {
  174.                                 while(!reduce_temperature);
  175.                                 up_limit_temp--;
  176.                                 if(up_limit_temp<0)
  177.                                 {
  178.                                         up_limit_temp=99;
  179.                                 }
  180.                                 //写入新数据
  181.                                 LcdWriteCom(0x80+0X40+0x03);
  182.                                 LcdWriteData('0'+up_limit_temp/10);
  183.                                 LcdWriteCom(0x80+0X40+0x04);
  184.                                 LcdWriteData('0'+up_limit_temp%10);
  185.                                 LcdWriteCom(0x80+0X40+2);//光标回写
  186.                         }
  187.                 }

  188.         }
  189.          set_temp=up_limit_temp*100;
  190.         temp_PID.SetPoint   =set_temp;
  191.         
  192. }

  193. int unnormal_proccessing(uint temp)//温度转换函数
  194. {
  195.         uchar datas[] = {0, 0, 0, 0}; //定义数组
  196.         int temp1=0;

  197.         datas[0] = temp % 10000 / 1000;
  198.         datas[1] = temp % 1000 / 100;
  199.         datas[2] = temp % 100 / 10;
  200. ……………………

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

所有资料51hei提供下载:
PID恒温控制器.zip (104.42 KB, 下载次数: 586)

评分

参与人数 6黑币 +133 收起 理由
水木之 + 6
karo + 5 赞一个!
nipi + 5 赞一个!
zkele + 10 共享资料的黑币奖励!赞一个!高手
tieq1952 + 7 赞一个!
admin + 100 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

不倒翁.WZT 发表于 2017-7-12 06:22 | 显示全部楼层

RE: 基于51单片机+PID恒温控制器制作

楼主朋友:请教一下,
pp->SumError=-500;  中pp->是什么意思?  pp是什么意思?
temp_PID.SetPoint=set_temp;中的“.”是什么意思?set_temp值究竟赋给了谁?我做过实验,如果本句修改为SetPoint=set_temp;  或  temp_PID=set_temp;  SetPoint=set_temp;两句,程序总体好用,当温度回降到脉宽接近100%输出时,有一段时间无输出,当温度回降到脉宽输出为100%时输出恢复正常。谢谢楼主。
回复

使用道具 举报

莫德尔 发表于 2018-8-22 16:33 | 显示全部楼层
你里面的左移  右移是不是弄错了  或者你注释有误                  byte = (byte >> 1) | (bi << 7);        这一段的注释是不是有误   你看看   但是这个PID算法  还是满真确的  而且用到了 结构体指针    感觉非常高大上                                       

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

莫德尔 发表于 2018-8-22 16:36 | 显示全部楼层
不倒翁.WZT 发表于 2017-7-12 06:22
楼主朋友:请教一下,
pp->SumError=-500;  中pp->是什么意思?  pp是什么意思?
temp_PID.SetPoint=set_ ...

此乃结构体指针 pp->SumError=-500; 相当于(*pp).SumError    为了方便用pp->代替(*pp)

评分

参与人数 1黑币 +40 收起 理由
admin + 40 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

faridzled 发表于 2017-7-6 04:40 | 显示全部楼层
thanks for sharing
回复

使用道具 举报

bbxyzzj 发表于 2017-7-6 08:16 | 显示全部楼层
感谢分享!
回复

使用道具 举报

lq3698 发表于 2017-7-6 09:12 | 显示全部楼层
兄弟没视频吗
回复

使用道具 举报

raymondau 发表于 2017-7-6 09:22 | 显示全部楼层
楼主是否能提供一下相关电路图,谢谢
回复

使用道具 举报

 楼主| 离谱 发表于 2017-7-6 13:23 | 显示全部楼层
raymondau 发表于 2017-7-6 09:22
楼主是否能提供一下相关电路图,谢谢

电路图太丑  不要介意

WENKONG.rar

19.62 KB, 下载次数: 130, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

 楼主| 离谱 发表于 2017-7-6 13:25 | 显示全部楼层

没有视频,这个控制可以在设置温度上下0.3度浮动。有时间的可以慢慢调
回复

使用道具 举报

raymondau 发表于 2017-7-6 16:31 | 显示全部楼层
离谱 发表于 2017-7-6 13:23
电路图太丑  不要介意

谢谢楼主,请问能发一下电路图吗?您发的这个是PCB图啊
回复

使用道具 举报

 楼主| 离谱 发表于 2017-7-6 16:49 | 显示全部楼层
raymondau 发表于 2017-7-6 16:31
谢谢楼主,请问能发一下电路图吗?您发的这个是PCB图啊

找了很久才找到

电路图

电路图

PID温度控制.zip

13.8 KB, 下载次数: 123, 下载积分: 黑币 -5

回复

使用道具 举报

raymondau 发表于 2017-7-6 20:16 | 显示全部楼层
离谱 发表于 2017-7-6 16:49
找了很久才找到

收到了,谢谢
回复

使用道具 举报

donny_y 发表于 2017-8-26 15:39 | 显示全部楼层
我下载了一次 第二次 还要花钱?
回复

使用道具 举报

海里没有大鲨鱼 发表于 2017-11-21 16:32 | 显示全部楼层
有仿真吗?兄弟
回复

使用道具 举报

linrumiao 发表于 2017-12-11 10:05 | 显示全部楼层
收到了,支持
回复

使用道具 举报

gdfg 发表于 2017-12-27 20:39 | 显示全部楼层
在这里面,算法起到了什么样的作用??
回复

使用道具 举报

tieq1952 发表于 2017-12-28 07:56 | 显示全部楼层
有实用价值
回复

使用道具 举报

 楼主| 离谱 发表于 2017-12-31 23:37 | 显示全部楼层
gdfg 发表于 2017-12-27 20:39
在这里面,算法起到了什么样的作用??

自动控制输出,保持设定温度
回复

使用道具 举报

 楼主| 离谱 发表于 2017-12-31 23:38 | 显示全部楼层

互相学习
回复

使用道具 举报

vista2008 发表于 2018-3-11 16:59 | 显示全部楼层
学习了
回复

使用道具 举报

2307393235 发表于 2018-3-23 15:19 | 显示全部楼层
学习一下PID
回复

使用道具 举报

顾新鑫 发表于 2018-3-26 14:28 | 显示全部楼层
请问在这基础上,怎么增加遥控控制温度增减开关。
回复

使用道具 举报

顾新鑫 发表于 2018-3-26 14:36 | 显示全部楼层
在此基础上,怎么增加遥控控制温度
回复

使用道具 举报

201730645473 发表于 2018-4-16 22:28 | 显示全部楼层
厉害了!!学习!!
回复

使用道具 举报

tuojianzhi 发表于 2018-4-19 09:58 | 显示全部楼层
可否告知下楼主QQ,谢谢
回复

使用道具 举报

数码家园 发表于 2018-4-23 07:12 | 显示全部楼层
谢谢分享!学习了
回复

使用道具 举报

yzh123 发表于 2018-4-24 08:45 来自手机 | 显示全部楼层
学习了,学习pid
回复

使用道具 举报

qq984304095 发表于 2018-4-28 19:12 | 显示全部楼层
老哥,你的5V加热器是多少瓦的,使用什么给他供电
回复

使用道具 举报

 楼主| 离谱 发表于 2018-5-15 17:20 | 显示全部楼层
qq984304095 发表于 2018-4-28 19:12
老哥,你的5V加热器是多少瓦的,使用什么给他供电

2W   可以用充电宝供电
回复

使用道具 举报

 楼主| 离谱 发表于 2018-5-15 17:21 | 显示全部楼层
顾新鑫 发表于 2018-3-26 14:36
在此基础上,怎么增加遥控控制温度

遥控只需要设置一个变量,远程数据传过来的时候使用这个变量接收就好
回复

使用道具 举报

AAAA7 发表于 2018-5-16 16:40 | 显示全部楼层
楼主还在不。
回复

使用道具 举报

15290037438 发表于 2018-6-24 12:15 | 显示全部楼层
可以学习了
回复

使用道具 举报

1170183671 发表于 2018-6-26 12:05 | 显示全部楼层
感谢楼主的分享
回复

使用道具 举报

lq3698 发表于 2018-6-26 20:54 | 显示全部楼层
无法下载了????
回复

使用道具 举报

33332 发表于 2018-6-28 14:54 | 显示全部楼层
thank you。能不能有电路图一起学习学习,小白一个
回复

使用道具 举报

TabHu 发表于 2018-7-5 18:08 | 显示全部楼层
好东西 ,学习了
回复

使用道具 举报

蔬木果 发表于 2018-7-12 22:53 | 显示全部楼层
学习PID
回复

使用道具 举报

村口王师傅 发表于 2018-8-20 20:31 | 显示全部楼层
非常好!
回复

使用道具 举报

小星是么 发表于 2018-8-27 14:30 | 显示全部楼层
可以
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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