標(biāo)題: 基于51單片機(jī)+PID恒溫控制器制作 [打印本頁]

作者: 離譜    時(shí)間: 2017-7-5 22:26
標(biāo)題: 基于51單片機(jī)+PID恒溫控制器制作
制作一個(gè)簡易的恒溫控制器學(xué)習(xí)PID。
使用到ds18b20 5V加熱器(TB有賣) 場效應(yīng)管IRF 640N用于開通和關(guān)斷加熱器。
設(shè)置預(yù)設(shè)值,通過PID不斷矯正加熱器輸出,達(dá)到預(yù)設(shè)溫度。

引腳分配    lcd    lcddata:    P0
            lcd_e:        P2^7
            lcd_rs:        P2^6
            lcd_rw:        P2^5
        
        設(shè)置按鍵    limit_choise:        P    //溫度上下限選擇按鍵
                increase_temperature        P    //增加溫度限值按鍵
                reduce_temperature        P    //減少溫度限值按鍵
        
        蜂鳴器報(bào)警    warning        P   

        溫度傳感器    temperature_sensor    P

        制熱    heatting    P

        制冷    refrigerating    P

        LED顯示        normal        P    //正常溫度指示燈
                high_temperature    P    //高溫指示燈
                low_temperature        P    //低溫指示燈   

單片機(jī)源程序如下:
  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倍后的中轉(zhuǎn)值
  10. int set_temp=0; //設(shè)置溫度*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()//主函數(shù)
  21. {
  22.     init();//初始化函數(shù)
  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();//控制按鍵函數(shù)
  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.                 }//顯示函數(shù)        
  41.                 if(time_value==60)      temp_m=unnormal_proccessing(temp_m1);//溫度轉(zhuǎn)換函數(shù)*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()//初始化函數(shù)
  71. {
  72.         uint i,j;
  73.         //函數(shù)初始化
  74.         LcdInit();//LCD初始化函數(shù)
  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);  //關(guān)閉寫一個(gè)指針加1
  96. }

  97. uint get_temp(uint temp)//計(jì)算溫度函數(shù)
  98. {
  99.         float tp;
  100.         
  101.         tp=temp;//因?yàn)閿?shù)據(jù)處理有小數(shù)點(diǎn)所以將溫度賦給一個(gè)浮點(diǎn)型變量
  102.         //如果溫度是正的那么,那么正數(shù)的原碼就是補(bǔ)碼它本身
  103.         temp=tp*0.0625*100+0.5;        
  104.         //留兩個(gè)小數(shù)點(diǎn)就*100,+0.5是四舍五入,因?yàn)镃語言浮點(diǎn)數(shù)轉(zhuǎn)換為整型的時(shí)候把小數(shù)點(diǎn)
  105.         //后面的數(shù)自動(dòng)去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進(jìn)1了,小于0.5的就
  106.         //算加上0.5,還是在小數(shù)點(diǎn)后面。
  107.         return temp;
  108. }

  109. void display_real_tenp(uint temp)//實(shí)時(shí)溫度顯示函數(shù)
  110. {
  111.         uchar datas[] = {0, 0, 0, 0}; //定義數(shù)組

  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]); //個(gè)位

  120.         LcdWriteCom(0x80+0x0d);         //寫地址 80表示初始地址
  121.         LcdWriteData('0'+datas[2]); //顯示小數(shù)點(diǎn)  

  122.         LcdWriteCom(0x80+0x0e);                 //寫地址 80表示初始地址
  123.         LcdWriteData('0'+datas[3]); //顯示小數(shù)點(diǎn)  

  124. }

  125. void temp_control()//控制溫度上下限函數(shù)
  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);//關(guān)閉光標(biāo)
  143.         
  144.         }
  145.                         
  146.         if(limit_choise_num==1)//調(diào)節(jié)上限溫度
  147.         {
  148.                 LcdWriteCom(0x80+0X40+2);
  149.                 LcdWriteCom(0x0f);//開啟光標(biāo)
  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.                                 //寫入新數(shù)據(jù)
  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);//光標(biāo)回寫
  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.                                 //寫入新數(shù)據(jù)
  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);//光標(biāo)回寫
  186.                         }
  187.                 }

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

  193. int unnormal_proccessing(uint temp)//溫度轉(zhuǎn)換函數(shù)
  194. {
  195.         uchar datas[] = {0, 0, 0, 0}; //定義數(shù)組
  196.         int temp1=0;

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

  201. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
PID恒溫控制器.zip (104.42 KB, 下載次數(shù): 1186)



作者: faridzled    時(shí)間: 2017-7-6 04:40
thanks for sharing
作者: bbxyzzj    時(shí)間: 2017-7-6 08:16
感謝分享!
作者: lq3698    時(shí)間: 2017-7-6 09:12
兄弟沒視頻嗎

作者: raymondau    時(shí)間: 2017-7-6 09:22
樓主是否能提供一下相關(guān)電路圖,謝謝
作者: 離譜    時(shí)間: 2017-7-6 13:23
raymondau 發(fā)表于 2017-7-6 09:22
樓主是否能提供一下相關(guān)電路圖,謝謝

電路圖太丑  不要介意

WENKONG.rar

19.62 KB, 下載次數(shù): 252, 下載積分: 黑幣 -5


作者: 離譜    時(shí)間: 2017-7-6 13:25
lq3698 發(fā)表于 2017-7-6 09:12
兄弟沒視頻嗎

沒有視頻,這個(gè)控制可以在設(shè)置溫度上下0.3度浮動(dòng)。有時(shí)間的可以慢慢調(diào)
作者: raymondau    時(shí)間: 2017-7-6 16:31
離譜 發(fā)表于 2017-7-6 13:23
電路圖太丑  不要介意

謝謝樓主,請(qǐng)問能發(fā)一下電路圖嗎?您發(fā)的這個(gè)是PCB圖啊
作者: 離譜    時(shí)間: 2017-7-6 16:49
raymondau 發(fā)表于 2017-7-6 16:31
謝謝樓主,請(qǐng)問能發(fā)一下電路圖嗎?您發(fā)的這個(gè)是PCB圖啊

找了很久才找到

電路圖.jpg (76.17 KB, 下載次數(shù): 303)

電路圖

電路圖

PID溫度控制.zip

13.8 KB, 下載次數(shù): 233, 下載積分: 黑幣 -5


作者: raymondau    時(shí)間: 2017-7-6 20:16
離譜 發(fā)表于 2017-7-6 16:49
找了很久才找到

收到了,謝謝
作者: 不倒翁.WZT    時(shí)間: 2017-7-12 06:22
標(biāo)題: RE: 基于51單片機(jī)+PID恒溫控制器制作
樓主朋友:請(qǐng)教一下,
pp->SumError=-500;  中pp->是什么意思?  pp是什么意思?
temp_PID.SetPoint=set_temp;中的“.”是什么意思?set_temp值究竟賦給了誰?我做過實(shí)驗(yàn),如果本句修改為SetPoint=set_temp;  或  temp_PID=set_temp;  SetPoint=set_temp;兩句,程序總體好用,當(dāng)溫度回降到脈寬接近100%輸出時(shí),有一段時(shí)間無輸出,當(dāng)溫度回降到脈寬輸出為100%時(shí)輸出恢復(fù)正常。謝謝樓主。
作者: 海里沒有大鯊魚    時(shí)間: 2017-11-21 16:32
有仿真嗎?兄弟
作者: linrumiao    時(shí)間: 2017-12-11 10:05
收到了,支持
作者: gdfg    時(shí)間: 2017-12-27 20:39
在這里面,算法起到了什么樣的作用??

作者: tieq1952    時(shí)間: 2017-12-28 07:56
有實(shí)用價(jià)值
作者: 離譜    時(shí)間: 2017-12-31 23:37
gdfg 發(fā)表于 2017-12-27 20:39
在這里面,算法起到了什么樣的作用??

自動(dòng)控制輸出,保持設(shè)定溫度
作者: 離譜    時(shí)間: 2017-12-31 23:38
tieq1952 發(fā)表于 2017-12-28 07:56
有實(shí)用價(jià)值

互相學(xué)習(xí)
作者: vista2008    時(shí)間: 2018-3-11 16:59
學(xué)習(xí)了
作者: 2307393235    時(shí)間: 2018-3-23 15:19
學(xué)習(xí)一下PID
作者: 顧新鑫    時(shí)間: 2018-3-26 14:28
請(qǐng)問在這基礎(chǔ)上,怎么增加遙控控制溫度增減開關(guān)。
作者: 顧新鑫    時(shí)間: 2018-3-26 14:36
在此基礎(chǔ)上,怎么增加遙控控制溫度
作者: 201730645473    時(shí)間: 2018-4-16 22:28
厲害了。W(xué)習(xí)!
作者: tuojianzhi    時(shí)間: 2018-4-19 09:58
可否告知下樓主QQ,謝謝
作者: 數(shù)碼家園    時(shí)間: 2018-4-23 07:12
謝謝分享!學(xué)習(xí)了
作者: yzh123    時(shí)間: 2018-4-24 08:45
學(xué)習(xí)了,學(xué)習(xí)pid
作者: qq984304095    時(shí)間: 2018-4-28 19:12
老哥,你的5V加熱器是多少瓦的,使用什么給他供電
作者: 離譜    時(shí)間: 2018-5-15 17:20
qq984304095 發(fā)表于 2018-4-28 19:12
老哥,你的5V加熱器是多少瓦的,使用什么給他供電

2W   可以用充電寶供電
作者: 離譜    時(shí)間: 2018-5-15 17:21
顧新鑫 發(fā)表于 2018-3-26 14:36
在此基礎(chǔ)上,怎么增加遙控控制溫度

遙控只需要設(shè)置一個(gè)變量,遠(yuǎn)程數(shù)據(jù)傳過來的時(shí)候使用這個(gè)變量接收就好
作者: AAAA7    時(shí)間: 2018-5-16 16:40
樓主還在不。
作者: 15290037438    時(shí)間: 2018-6-24 12:15
可以學(xué)習(xí)了
作者: 1170183671    時(shí)間: 2018-6-26 12:05
感謝樓主的分享
作者: lq3698    時(shí)間: 2018-6-26 20:54
無法下載了????
作者: 33332    時(shí)間: 2018-6-28 14:54
thank you。能不能有電路圖一起學(xué)習(xí)學(xué)習(xí),小白一個(gè)
作者: TabHu    時(shí)間: 2018-7-5 18:08
好東西 ,學(xué)習(xí)了
作者: 蔬木果    時(shí)間: 2018-7-12 22:53
學(xué)習(xí)PID
作者: 村口王師傅    時(shí)間: 2018-8-20 20:31
非常好!
作者: 莫德爾    時(shí)間: 2018-8-22 16:33
你里面的左移  右移是不是弄錯(cuò)了  或者你注釋有誤                  byte = (byte >> 1) | (bi << 7);        這一段的注釋是不是有誤   你看看   但是這個(gè)PID算法  還是滿真確的  而且用到了 結(jié)構(gòu)體指針    感覺非常高大上                                       
作者: 莫德爾    時(shí)間: 2018-8-22 16:36
不倒翁.WZT 發(fā)表于 2017-7-12 06:22
樓主朋友:請(qǐng)教一下,
pp->SumError=-500;  中pp->是什么意思?  pp是什么意思?
temp_PID.SetPoint=set_ ...

此乃結(jié)構(gòu)體指針 pp->SumError=-500; 相當(dāng)于(*pp).SumError    為了方便用pp->代替(*pp)
作者: 小星是么    時(shí)間: 2018-8-27 14:30
可以

作者: 數(shù)碼家園    時(shí)間: 2018-8-30 10:36
非常感謝樓主分享,今天試了一下,還有PWM 輸出顯示,挺不錯(cuò)的
作者: little4_su    時(shí)間: 2018-9-28 20:40
精度達(dá)到±0.3嗎?
作者: dzbj2    時(shí)間: 2018-10-18 16:11
樓主,完善下 PID 算法轉(zhuǎn)成 PWM 的解說?
作者: djzoom    時(shí)間: 2018-11-23 13:08
請(qǐng)問有人做出成品么?
作者: 單片機(jī)是什么    時(shí)間: 2018-11-24 20:40
樓主,ds18b20 5V加熱器在tb上搜不到啊,只有ds18b20 5V溫度傳感器,請(qǐng)問這個(gè)加熱器可以用別的替代嗎?
作者: 3205440665    時(shí)間: 2019-1-2 14:48
正在學(xué)習(xí)pid,謝謝分享!。。。
作者: 傳說十六年    時(shí)間: 2019-1-10 23:48
結(jié)構(gòu)體在哪里定義的 我怎么看不到
作者: nihao11    時(shí)間: 2019-4-16 22:46
thanks for sharing
作者: 徐長國    時(shí)間: 2019-4-25 09:39
場效應(yīng)管可以改成繼電器嗎
作者: 徐長國    時(shí)間: 2019-4-26 10:36
徐長國 發(fā)表于 2019-4-25 09:39
場效應(yīng)管可以改成繼電器嗎

可以改成繼電器
作者: 2570235540    時(shí)間: 2019-5-7 14:51
感謝樓主,真的幫助很大謝謝了

作者: ygj    時(shí)間: 2019-5-24 10:56
徐長國 發(fā)表于 2019-4-26 10:36
可以改成繼電器

固態(tài)繼電器嗎?一般的不行吧
作者: 一切隨緣吧    時(shí)間: 2019-6-5 15:28
厲害了哦
作者: abc111111    時(shí)間: 2019-6-12 00:08
莫德爾 發(fā)表于 2018-8-22 16:36
此乃結(jié)構(gòu)體指針 pp->SumError=-500; 相當(dāng)于(*pp).SumError    為了方便用pp->代替(*pp)

感謝解答,我也有同樣的疑問
作者: a1357787200    時(shí)間: 2019-6-12 13:49
學(xué)習(xí)學(xué)習(xí)
作者: 瞞心書生    時(shí)間: 2019-6-18 16:11
真好用啊
作者: zhuhong110450    時(shí)間: 2019-7-17 15:52
T12溫控可以借鑒此PID溫控算法不?
作者: StaryLL    時(shí)間: 2019-7-22 18:33
這個(gè)可以做出來嗎?有做出來的朋友嗎?
作者: 行百里    時(shí)間: 2019-9-20 16:49
謝謝您,祝工作順利
作者: aaaaaa。    時(shí)間: 2019-10-22 13:25
DS18B20 5V加熱器沒找到,是不是PTC恒溫發(fā)熱片???
作者: 錢情錦繡    時(shí)間: 2019-12-9 00:21
學(xué)習(xí)一下,謝謝分享
作者: 1051248815    時(shí)間: 2020-4-13 09:08
感謝樓主的分享
作者: qwthh    時(shí)間: 2020-4-13 18:32
請(qǐng)問能用PROTEUS仿真嗎 電路圖里沒看到加熱啊 只有一個(gè)MOSFEI
作者: v韓國v看    時(shí)間: 2020-4-24 14:32
很喜歡,正要用這方面知識(shí)
作者: sunnyqingfeng    時(shí)間: 2020-5-26 09:35
單片機(jī)是什么 發(fā)表于 2018-11-24 20:40
樓主,ds18b20 5V加熱器在tb上搜不到啊,只有ds18b20 5V溫度傳感器,請(qǐng)問這個(gè)加熱器可以用別的替代嗎?

5V 加熱器和ds18b20不是一個(gè)東西
作者: pfdqwp    時(shí)間: 2020-5-26 12:05
贊一個(gè),正好學(xué)習(xí)下!。。。。。。。。。。。
作者: 993118812    時(shí)間: 2021-3-2 17:10
本帖下載后  keil無法打開
作者: 51hei團(tuán)團(tuán)    時(shí)間: 2021-3-2 17:53
993118812 發(fā)表于 2021-3-2 17:10
本帖下載后……

Keil4可以打開,親測

51hei.png (41.72 KB, 下載次數(shù): 685)

51hei.png

作者: wellhope    時(shí)間: 2021-3-3 11:01
如果使用市電,不加過零嗎?
作者: woyaodwn    時(shí)間: 2021-3-3 14:42
好東西,控制精度怎么樣?
作者: 1336692    時(shí)間: 2021-3-16 12:03
NB(考古)
作者: lvanangel    時(shí)間: 2021-3-30 19:13
謝謝大佬,非常有用
作者: cuijb    時(shí)間: 2021-4-2 19:54
單片機(jī)是什么 發(fā)表于 2018-11-24 20:40
樓主,ds18b20 5V加熱器在tb上搜不到啊,只有ds18b20 5V溫度傳感器,請(qǐng)問這個(gè)加熱器可以用別的替代嗎?

ds18b20是溫度傳感器, 5V加熱器搞個(gè)10Ω3-5W電阻就行
作者: weq12345    時(shí)間: 2021-4-9 10:49
樓主肯定是抄人家的,有做出成品試過沒,還有就是加入過零檢測電路沒
作者: woyaodwn    時(shí)間: 2021-12-28 10:03
高手好多啊,出個(gè)實(shí)用版本的啊,期待中




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1