標(biāo)題: PID控制的單片機爐溫控制系統(tǒng)源碼和Proteus仿真 [打印本頁]

作者: smileml115    時間: 2017-6-4 15:04
標(biāo)題: PID控制的單片機爐溫控制系統(tǒng)源碼和Proteus仿真
功能要求:
1)    采用液晶顯示器顯示溫度測量值。
2)    檢測的溫度范圍為0~128
3)    溫度超過警戒值時能報警提示。
4)  能通過鍵盤輸入設(shè)定溫度并顯示。
5)  用PID控制溫度,控溫精度≦±2。
DS18B20溫度顯示仿真如圖,DS18B20的值可以任意調(diào)整,模擬溫度的采集,LCD的顯示值隨DS18B20的溫度值變化而變化。當(dāng)溫度超過界限,LED亮,同時SOUNDER響,模擬警報系統(tǒng)。當(dāng)按下k1,顯示溫度的最高位光標(biāo)開始閃爍,進(jìn)入設(shè)定溫度調(diào)整,按下k2,光標(biāo)右移,按下k3數(shù)值加1,按下k4數(shù)值減1

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載):



PID控制仿真如圖,電加熱爐OVEN輸出的模擬量經(jīng)ADC0804轉(zhuǎn)化成數(shù)字量,再送到LCD顯示。OVEN的溫度與設(shè)定溫度在單片機內(nèi)進(jìn)行PID運算,PID輸出量控制晶閘管的導(dǎo)通,從而控制OVEN的加熱。



下面是51單片機的源碼:                  
  1. #include<reg52.h>
  2. #include<math.h>
  3. float R;
  4. float Kp;
  5. float T;
  6. float Ti;
  7. float Td;
  8. float e2;
  9. float e1,e;
  10. float a0,a1,a2;
  11. #define ui unsigned int
  12. #define uc unsigned char
  13. sbit bj=P2^4;                             //低電平報警模塊工作
  14. sbit lcden=P2^7;                         //LCD E
  15. sbit lcdrs=P2^6;                         //LCD    RS
  16. sbit lcdrw=P2^5; //                         //LCD RW
  17. sbit control=P2^3;                         //加熱模塊相關(guān)。低電平啟動
  18. char lshi,lge,hshi,hge;
  19. uc num,flag;
  20. ui temp;
  21. sbit dsio=P3^7;                            //DS18B20輸入口
  22. //延時
  23. void delay(ui z)
  24. {
  25.     uc x,y;
  26.     for(x=z;x>0;x--)
  27.         for(y=110;y>0;y--);
  28. }
  29. //DS18B20控制
  30. void dsinit()
  31. {
  32.     uc i;
  33.     dsio=0;
  34.     i=70;
  35.     while(i--);
  36.     dsio=1;
  37.     i=4;
  38.     while(i--);
  39. }
  40. void dswritebyte(uc dat)
  41. {
  42.     uc i,j;
  43.     for(j=0;j<8;j++)
  44.     {
  45.         dsio=0;
  46.         i++;
  47.         dsio=dat&0x01;
  48.         i=6;
  49.         while(i--);
  50.         dsio=1;
  51.         dat>>=1;
  52.     }
  53. }
  54. uc dsreadbyte()
  55. {
  56.     uc i,j,byte,b;
  57.     for(j=0;j<8;j++)
  58.     {
  59.         dsio=0;
  60.         i++;
  61.         dsio=1;
  62.         i++;i++;
  63.         b=dsio;
  64.         byte=(byte>>1)|(b<<7);
  65.         i=4;
  66.         while(i--);
  67.     }
  68.     return byte;
  69. }
  70. void dschangetemp()
  71. {
  72.     dsinit();
  73.     delay(1);
  74.     dswritebyte(0xcc);
  75.     dswritebyte(0x44);

  76. }
  77. void dsreadtemp()
  78. {
  79.     dsinit();
  80.     delay(1);
  81.     dswritebyte(0xcc);
  82.     dswritebyte(0xbe);
  83. }
  84. ui gettemp()
  85. {
  86.     int temp;
  87.     uc h,l;
  88.     dschangetemp();
  89.     dsreadtemp();
  90.     l=dsreadbyte();
  91.     h=dsreadbyte();
  92.     temp=h;
  93.     temp<<=8;
  94.     temp|=l;
  95.     temp=temp*0.0625*100+0.5;
  96.     return temp;
  97. }
  98. //LCD控制程序
  99. void lcdwritecom(uc com)
  100. {
  101.     lcdrs=0;
  102.     P0=com;
  103.     delay(10);
  104.     lcden=1;
  105.     delay(10);
  106.     lcden=0;
  107. }
  108. void lcdwritedata(uc date)
  109. {
  110.     lcdrs=1;
  111.     P0=date;
  112.     delay(10);
  113.     lcden=1;
  114.     delay(10);
  115.     lcden=0;
  116. }
  117. void lcdinit()
  118. {
  119.     lcdrw=0;
  120.     lcden=0;
  121.     lcdwritecom(0x38);
  122.     lcdwritecom(0x0c);
  123.     lcdwritecom(0x06);
  124.     lcdwritecom(0x01);
  125. }
  126. //LCD顯示
  127. void lcddisplay(int temp)
  128. {
  129.     ui  tab[]={0,0,0,-2,0,0};
  130.     lcdwritecom(0x80);
  131.     lcdwritedata('+');
  132.     tab[0]=temp/10000;
  133.     tab[1]=temp%10000/1000;
  134.     tab[2]=temp%1000/100;
  135.     tab[4]=temp%100/10;
  136.     tab[5]=temp%10;
  137.     lcdwritecom(0x81);
  138.     for(num=0;num<6;num++)
  139.     {
  140.         lcdwritedata('0'+tab[num]);
  141.     }
  142. }

  143. void adjust()
  144. {
  145.     delay(100);
  146.     flag++;
  147.     if(flag==5)flag=1;
  148.     if(flag==1)
  149.     {
  150.         lcdwritecom(0x80+0x44);
  151.         lcdwritecom(0x0f);   
  152.      }
  153.      if(flag==2)
  154.     {
  155.         lcdwritecom(0x80+0x45);
  156.         lcdwritecom(0x0f);   
  157.      }
  158.     if(flag==3)
  159.     {
  160.         lcdwritecom(0x80+0x47);
  161.         lcdwritecom(0x0f);   
  162.      }
  163.     if(flag==4)
  164.     {
  165.         lcdwritecom(0x80+0x48);
  166.         lcdwritecom(0x0f);   
  167.      }
  168. }
  169. void inc()
  170. {
  171.     delay(100);
  172.     switch(flag)
  173.     {
  174.         case 1:lshi++; if(lshi==10)lshi=0;
  175.                         lcdwritedata('0'+lshi);
  176.                         lcdwritecom(0x10);
  177.                         break;
  178.         case 2:lge++; if(lge==10)lge=0;
  179.                         lcdwritedata('0'+lge);
  180.                         lcdwritecom(0x10);
  181.                         break;
  182.         case 3:hshi++; if(hshi==10)hshi=0;
  183.                         lcdwritedata('0'+hshi);
  184.                         lcdwritecom(0x10);
  185.                         break;
  186.         case 4:hge++; if(hge==10)hge=0;
  187.                         lcdwritedata('0'+hge);
  188.                         lcdwritecom(0x10);
  189.                         break;
  190.     }
  191. }
  192. void dec()
  193. {
  194.     delay(100);
  195.     switch(flag)
  196.     {
  197.         case 1:lshi--; if(lshi<0)lshi=9;
  198.                         lcdwritedata('0'+lshi);
  199.                         lcdwritecom(0x10);
  200.                         break;
  201.         case 2:lge--; if(lge<0)lge=9;
  202.                         lcdwritedata('0'+lge);
  203.                         lcdwritecom(0x10);
  204.                         break;
  205.         case 3:hshi--; if(hshi<0)hshi=9;
  206.                         lcdwritedata('0'+hshi);
  207.                          lcdwritecom(0x10);
  208.                         break;
  209.         case 4:hge--; if(hge<0)hge=9;
  210.                         lcdwritedata('0'+hge);
  211.                          lcdwritecom(0x10);
  212.                         break;
  213.     }
  214. }
  215. //鍵盤掃描
  216. void keyscan()
  217. {
  218.     uc test,num;
  219.     num=0;
  220.     test=P1;
  221.     if(test!=0xff)
  222.     delay(5);
  223.     test=P1;
  224.     if(test==0xf7)
  225.    
  226.     {
  227.         while(P1!=0xff);
  228.         num++;
  229.         while(1)
  230.         {
  231.             test=P1;
  232.             if(test!=0xff)
  233.             delay(5);
  234.             test=P1;
  235.             if(test!=0xff)
  236.             {
  237.                 if(test==0xf7)
  238.                     num++;
  239.                     if(num==2)
  240.                     {    lcdwritecom(0x0c);
  241.                         break;}
  242.                 switch(test)
  243.                 {
  244.                     case 0xfe:adjust();   
  245.                             break;
  246.                     case 0xfd:inc();
  247.                             break;
  248.                     case 0xfb:dec();
  249.                             break;
  250.                 }
  251.              }
  252.             while(P1!=0xff);
  253.         
  254.         }
  255.         }
  256. }
  257. //PID
  258. void PIDinit()
  259. {
  260.       
  261.        Kp=2;Ti=4;Td=1;T=1;R=25;
  262.        a0=Kp*(1+T/Ti+Td/T);
  263.        a1=-Kp*(1+(2*Td)/T);
  264.        a2=Kp*(Td/T);
  265.        e2=e1=0;
  266. }
  267. void PIDdeal()
  268. {
  269.     float y    ,u ;
  270.     y=gettemp();
  271.     e=y/100-R;
  272.     u=a0*e+a1*e1+a2*e2;
  273.     e2=e1;e1=e;
  274.     if(u>0.5||u<-0.5)
  275.     control=0;
  276.     else control=1;
  277. }
  278. void main()
  279. {
  280.     uc code tab2[]="SET:20~80C";
  281.     uc i;
  282.     TMOD=0x01;
  283.     TH0=(65535-10900)/256;
  284.     TL0=(65535-10900)%256;
  285.     ET0=1;
  286.     TR0=1;
  287.     lcdinit();
  288.     lcdwritecom(0x87);
  289.     lcdwritedata('C');
  290.     lcdwritecom(0x80+0x40);
  291.     for(i=0;i<10;i++)
  292.         lcdwritedata(tab2[i]) ;
  293.     lshi=2;lge=0;hshi=5;hge=0;
  294.     while(1)
  295.     {
  296.         lcddisplay(gettemp());
  297.         keyscan() ;
  298.         EA=1; while(1);
  299.     }
  300. }
  301. void t0() interrupt 1
  302. {   
  303.     uc i;
  304.     TH0=(65535-10900)/256;
  305.     TL0=(65535-10900)%256;
  306.     i++;
  307.     if(i==100)
  308.     {
  309.        void PIDinit();
  310.        void PIDdeal();
  311.     }
  312. }
復(fù)制代碼

上文是網(wǎng)上轉(zhuǎn)載的給大家學(xué)習(xí)參考的,附件里面是我自己弄的,目前不成功,調(diào)試了好幾天了,搞不定,求大神指導(dǎo)如何修改?
仿真失敗的程序,求大神幫忙指導(dǎo)修改.7z (236.78 KB, 下載次數(shù): 1201)


作者: 3760609865    時間: 2017-6-5 00:34
謝謝分享,學(xué)習(xí)學(xué)習(xí)pID控制。
作者: alphacrux    時間: 2017-8-27 16:54
Node #00087 not found whilst binding pin V+ of U4_U10_ADC#0001!
仿真出現(xiàn)上述錯誤,請問是什么原因呢?
我的proteus版本是7.8
作者: CZP1234    時間: 2017-8-28 10:41
源程序有問題
作者: lijn    時間: 2017-11-4 09:48
樓主 pid在單片機中的運算,講講。
作者: 海里沒有大鯊魚    時間: 2017-11-21 16:22
CZP1234 發(fā)表于 2017-8-28 10:41
源程序有問題

怎么解決?

作者: 海里沒有大鯊魚    時間: 2017-11-21 16:27
CZP1234 發(fā)表于 2017-8-28 10:41
源程序有問題

樓主 是不是少了什么原件?

作者: 海里沒有大鯊魚    時間: 2017-11-21 16:29
alphacrux 發(fā)表于 2017-8-27 16:54
Node #00087 not found whilst binding pin V+ of U4_U10_ADC#0001!
仿真出現(xiàn)上述錯誤,請問是什么原因呢 ...

你是怎么解決這個問題的?

作者: 哈哈哈WJ    時間: 2017-12-20 21:02
海里沒有大鯊魚 發(fā)表于 2017-11-21 16:29
你是怎么解決這個問題的?

解決了嗎
作者: aqb3322    時間: 2018-1-16 22:09
這個資料真好。可以做成品了。
作者: nishiy    時間: 2018-1-23 11:09
為什么程序運行不了,仿真也運行不了
作者: whs123456    時間: 2018-4-9 11:37
怎么自動調(diào)節(jié)啊
作者: walt740    時間: 2018-4-13 00:37
好資料,51黑有你更精彩!!!
作者: 小貓小兔    時間: 2018-5-7 21:26
謝謝樓主的分享,我試試看能不能仿真出來。
作者: 295735223    時間: 2018-5-11 00:15
好資料,51黑有你更精彩!!!
作者: liyongan_1985    時間: 2018-5-11 08:57
果然是好資料,打算下載下倆看看
作者: kaili    時間: 2018-5-17 13:31
運行后無法設(shè)置溫度,加熱裝置也不工作,蜂鳴器一直在報警
作者: zengzengbin    時間: 2018-5-22 13:47
程序有問題。
作者: 六月六月    時間: 2018-5-22 19:32
alphacrux 發(fā)表于 2017-8-27 16:54
**** 作者被禁止或刪除 內(nèi)容自動屏蔽 ****

運行不了是因為下載回來的protues圖中adc0804有幾個引腳的網(wǎng)絡(luò)標(biāo)號沒有標(biāo)上,可以參照樓主的截圖自行添加
作者: zengzengbin    時間: 2018-5-23 16:56
這個有問題。
作者: 川大學(xué)子    時間: 2018-5-23 21:04
正好需要,就是不知道能不能完成整個仿真
作者: liuxiaoxiong    時間: 2018-6-19 20:42
能運行,lcd不顯示,有哪位可以解釋一下嗎?
作者: liuxi1206    時間: 2019-1-10 21:03
謝謝分享,學(xué)習(xí)學(xué)習(xí)pID控制。
作者: 123xianbei    時間: 2019-1-16 15:17
樓主能不能注釋下代碼!PIDInit()和PIDDeal()看不懂什么意思,和平常的PID函數(shù)不太一樣
作者: wacsl    時間: 2019-3-24 13:37
感謝分享,更想學(xué)習(xí)了
作者: recoo    時間: 2019-3-25 00:26
樓主精神可嘉啊
作者: lichangle    時間: 2019-4-23 17:13
這仿真有問題, 不會獲取溫度
估計樓主屏蔽了或者刪除了一部分代碼
作者: xiaobai1990    時間: 2019-5-7 22:19
樓主沒有找到ADC0804的代碼。
作者: ZOUZHUO    時間: 2019-5-8 12:40
CZP1234 發(fā)表于 2017-8-28 10:41
源程序有問題

哪里有

作者: lyfe    時間: 2019-5-8 22:24
可以向大家咨詢下關(guān)于PID控溫的其他問題嗎?我的問題是:為什么protues仿真中l(wèi)cd不顯示呢?求幫助,謝謝您了
作者: 123@4    時間: 2019-5-23 20:24
程序有點問題,按鍵也沒有進(jìn)行定義
作者: 某偶像練習(xí)生    時間: 2019-6-5 13:57
大神厲害 剛好需要用到
作者: 煙花易冷    時間: 2019-6-16 18:15
編譯代碼沒問題,一仿真就出現(xiàn)23 ERROR(S),都是ERROR L121: IMPROPER FIXUP.怎么解決啊,在線等,急
作者: 煙花易冷    時間: 2019-6-17 12:07
煙花易冷 發(fā)表于 2019-6-16 18:15
編譯代碼沒問題,一仿真就出現(xiàn)23 ERROR(S),都是ERROR L121: IMPROPER FIXUP.怎么解決啊,在線等,急

這個問題解決了,把工程設(shè)置中Options里的ROM改為large就行了。
可是仿真成功后,按鍵設(shè)置無反應(yīng),電熱爐也不加熱,LCD顯示也不改變。
作者: yusan12342019    時間: 2019-6-17 15:08
值得學(xué)習(xí)
作者: 夏娜不灼眼    時間: 2019-6-17 18:16
LCD顯示不成功啊
作者: Robust59    時間: 2019-6-19 08:37
樓主,出現(xiàn)關(guān)鍵性錯誤是怎么回事
作者: ljb6869118    時間: 2019-6-19 11:44
kaili 發(fā)表于 2018-5-17 13:31
運行后無法設(shè)置溫度,加熱裝置也不工作,蜂鳴器一直在報警

請問怎么解決了

作者: wgykk    時間: 2019-12-24 13:37
好資料,前來學(xué)習(xí)
作者: MIGRAINE    時間: 2019-12-29 22:34
用oven那個圖的程序在哪。
作者: puyong    時間: 2020-3-26 10:09
不能用,慎重下載
作者: lele5211314    時間: 2020-4-4 11:12
程序不能用,下載的程序里面沒有關(guān)于ADC0804的代碼
作者: 請問請4    時間: 2020-5-12 21:48
基于AT89S51單片機爐溫控制系統(tǒng)的模塊電路設(shè)計
作者: tangjun    時間: 2020-6-9 17:26
馬克 ,攢夠積分再來。
作者: hyfwyy    時間: 2020-6-28 12:48
樓主,請問可以分享一下adc的程序嘛?或者請問一下oven模塊輸出電壓和實際溫度的關(guān)系,謝謝
作者: 51hei電控200522    時間: 2020-8-2 22:00
alphacrux 發(fā)表于 2017-8-27 16:54
**** 作者被禁止或刪除 內(nèi)容自動屏蔽 ****

附件應(yīng)該是忘記保存最后新的了,需要把adc0804的電源的數(shù)據(jù)輸出口全部都接上,具體可以參照樓主截圖。
作者: 51hei電控200522    時間: 2020-8-2 22:01
ADC0804的程序和OVEN的控制程序都沒有上傳先看PID動態(tài)效果的不建議下載了哦
作者: zyx@    時間: 2020-8-12 11:18
垃圾吧,仿真沒一個成功的,按鍵沒反應(yīng),第二個仿真也有錯誤
作者: zyx@    時間: 2020-8-12 12:01
能不能認(rèn)真點,仿真液晶屏顯示第一張中,功能不是設(shè)置最高溫和最低溫嗎,你上面就顯示一個溫度設(shè)置個錘子
作者: zyx@    時間: 2020-8-12 14:42
CZP1234 發(fā)表于 2017-8-28 10:41
源程序有問題

絕對有問題,又一個進(jìn)坑了,擦
作者: 阿giao    時間: 2020-9-10 20:01
仿真出現(xiàn)錯誤 咋整 有改好的沒
作者: Highnose    時間: 2020-10-22 21:49
電路沒連完,網(wǎng)頁圖里是對的,仿真原理圖是錯的,程序也不對蛋
作者: qzsulin    時間: 2020-11-12 11:47
程序不完整,沒辦法用
作者: 51hei電控200522    時間: 2021-4-13 23:01
這個仿真不推薦大家下載了,認(rèn)真查看過之后并沒有晶閘管驅(qū)動oven加熱的代碼,沒有adc084的代碼。良心建議。。!
作者: c51單片機小白    時間: 2021-4-14 18:43
51hei電控200522 發(fā)表于 2021-4-13 23:01
這個仿真不推薦大家下載了,認(rèn)真查看過之后并沒有晶閘管驅(qū)動oven加熱的代碼,沒有adc084的代碼。良心建議! ...

要是早看到就好了老哥你也在寫pid溫控嗎?能交流下嗎
作者: luobog    時間: 2021-4-22 22:48
c51單片機小白 發(fā)表于 2021-4-14 18:43
要是早看到就好了老哥你也在寫pid溫控嗎?能交流下嗎

老哥你寫的咋樣了?能討論討論嗎
作者: Ux.。    時間: 2021-6-2 20:31
謝謝分享 對51單片機PID調(diào)控有更好認(rèn)識

作者: woyaodwn    時間: 2021-12-28 10:05
這個搞起來了嗎
作者: zxw517    時間: 2023-4-18 00:14
學(xué)習(xí)了,PID的模糊運算有點不容易




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