找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 36458|回復(fù): 58
打印 上一主題 下一主題
收起左側(cè)

PID控制的單片機(jī)爐溫控制系統(tǒng)源碼和Proteus仿真

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
功能要求:
1)    采用液晶顯示器顯示溫度測(cè)量值。
2)    檢測(cè)的溫度范圍為0~128。
3)    溫度超過(guò)警戒值時(shí)能報(bào)警提示。
4)  能通過(guò)鍵盤輸入設(shè)定溫度并顯示。
5)  用PID控制溫度,控溫精度≦±2。
DS18B20溫度顯示仿真如圖,DS18B20的值可以任意調(diào)整,模擬溫度的采集,LCD的顯示值隨DS18B20的溫度值變化而變化。當(dāng)溫度超過(guò)界限,LED亮,同時(shí)SOUNDER響,模擬警報(bào)系統(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è)定溫度在單片機(jī)內(nèi)進(jìn)行PID運(yùn)算,PID輸出量控制晶閘管的導(dǎo)通,從而控制OVEN的加熱。



下面是51單片機(jī)的源碼:                  
  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;                             //低電平報(bào)警模塊工作
  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)。低電平啟動(dòng)
  18. char lshi,lge,hshi,hge;
  19. uc num,flag;
  20. ui temp;
  21. sbit dsio=P3^7;                            //DS18B20輸入口
  22. //延時(shí)
  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)

評(píng)分

參與人數(shù) 2黑幣 +110 收起 理由
a920051220 + 10 很給力!
admin + 100 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏33 分享淘帖 頂3 踩1
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:159139 發(fā)表于 2017-6-5 00:34 來(lái)自觸屏版 | 只看該作者
謝謝分享,學(xué)習(xí)學(xué)習(xí)pID控制。
回復(fù)

使用道具 舉報(bào)

板凳
ID:229561 發(fā)表于 2017-8-27 16:54 | 只看該作者
Node #00087 not found whilst binding pin V+ of U4_U10_ADC#0001!
仿真出現(xiàn)上述錯(cuò)誤,請(qǐng)問(wèn)是什么原因呢?
我的proteus版本是7.8
回復(fù)

使用道具 舉報(bào)

地板
ID:217820 發(fā)表于 2017-8-28 10:41 | 只看該作者
源程序有問(wèn)題
回復(fù)

使用道具 舉報(bào)

5#
ID:126422 發(fā)表于 2017-11-4 09:48 | 只看該作者
樓主 pid在單片機(jī)中的運(yùn)算,講講。
回復(fù)

使用道具 舉報(bào)

6#
ID:249705 發(fā)表于 2017-11-21 16:22 | 只看該作者

怎么解決?
回復(fù)

使用道具 舉報(bào)

7#
ID:249705 發(fā)表于 2017-11-21 16:27 | 只看該作者

樓主 是不是少了什么原件?
回復(fù)

使用道具 舉報(bào)

8#
ID:249705 發(fā)表于 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)上述錯(cuò)誤,請(qǐng)問(wèn)是什么原因呢 ...

你是怎么解決這個(gè)問(wèn)題的?
回復(fù)

使用道具 舉報(bào)

9#
ID:264448 發(fā)表于 2017-12-20 21:02 | 只看該作者
海里沒(méi)有大鯊魚 發(fā)表于 2017-11-21 16:29
你是怎么解決這個(gè)問(wèn)題的?

解決了嗎
回復(fù)

使用道具 舉報(bào)

10#
ID:267327 發(fā)表于 2018-1-16 22:09 | 只看該作者
這個(gè)資料真好�?梢宰龀善妨�。
回復(fù)

使用道具 舉報(bào)

11#
ID:278622 發(fā)表于 2018-1-23 11:09 | 只看該作者
為什么程序運(yùn)行不了,仿真也運(yùn)行不了
回復(fù)

使用道具 舉報(bào)

12#
ID:304318 發(fā)表于 2018-4-9 11:37 來(lái)自觸屏版 | 只看該作者
怎么自動(dòng)調(diào)節(jié)啊
回復(fù)

使用道具 舉報(bào)

13#
ID:57831 發(fā)表于 2018-4-13 00:37 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

14#
ID:311868 發(fā)表于 2018-5-7 21:26 來(lái)自觸屏版 | 只看該作者
謝謝樓主的分享,我試試看能不能仿真出來(lái)。
回復(fù)

使用道具 舉報(bào)

15#
ID:289258 發(fā)表于 2018-5-11 00:15 | 只看該作者
好資料,51黑有你更精彩!!!
回復(fù)

使用道具 舉報(bào)

16#
ID:295874 發(fā)表于 2018-5-11 08:57 | 只看該作者
果然是好資料,打算下載下倆看看
回復(fù)

使用道具 舉報(bào)

17#
ID:330939 發(fā)表于 2018-5-17 13:31 | 只看該作者
運(yùn)行后無(wú)法設(shè)置溫度,加熱裝置也不工作,蜂鳴器一直在報(bào)警
回復(fù)

使用道具 舉報(bào)

18#
ID:327959 發(fā)表于 2018-5-22 13:47 | 只看該作者
程序有問(wèn)題。
回復(fù)

使用道具 舉報(bào)

19#
ID:324374 發(fā)表于 2018-5-22 19:32 | 只看該作者
alphacrux 發(fā)表于 2017-8-27 16:54
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

運(yùn)行不了是因?yàn)橄螺d回來(lái)的protues圖中adc0804有幾個(gè)引腳的網(wǎng)絡(luò)標(biāo)號(hào)沒(méi)有標(biāo)上,可以參照樓主的截圖自行添加
回復(fù)

使用道具 舉報(bào)

20#
ID:327959 發(fā)表于 2018-5-23 16:56 | 只看該作者
這個(gè)有問(wèn)題。
回復(fù)

使用道具 舉報(bào)

21#
ID:336840 發(fā)表于 2018-5-23 21:04 | 只看該作者
正好需要,就是不知道能不能完成整個(gè)仿真
回復(fù)

使用道具 舉報(bào)

22#
ID:353526 發(fā)表于 2018-6-19 20:42 來(lái)自觸屏版 | 只看該作者
能運(yùn)行,lcd不顯示,有哪位可以解釋一下嗎?
回復(fù)

使用道具 舉報(bào)

23#
ID:466140 發(fā)表于 2019-1-10 21:03 | 只看該作者
謝謝分享,學(xué)習(xí)學(xué)習(xí)pID控制。
回復(fù)

使用道具 舉報(bào)

24#
ID:217128 發(fā)表于 2019-1-16 15:17 | 只看該作者
樓主能不能注釋下代碼!PIDInit()和PIDDeal()看不懂什么意思,和平常的PID函數(shù)不太一樣
回復(fù)

使用道具 舉報(bào)

25#
ID:496761 發(fā)表于 2019-3-24 13:37 | 只看該作者
感謝分享,更想學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

26#
ID:497626 發(fā)表于 2019-3-25 00:26 | 只看該作者
樓主精神可嘉啊
回復(fù)

使用道具 舉報(bào)

27#
ID:20793 發(fā)表于 2019-4-23 17:13 | 只看該作者
這仿真有問(wèn)題, 不會(huì)獲取溫度
估計(jì)樓主屏蔽了或者刪除了一部分代碼
回復(fù)

使用道具 舉報(bào)

28#
ID:75969 發(fā)表于 2019-5-7 22:19 | 只看該作者
樓主沒(méi)有找到ADC0804的代碼。
回復(fù)

使用道具 舉報(bào)

29#
ID:530517 發(fā)表于 2019-5-8 12:40 | 只看該作者

哪里有
回復(fù)

使用道具 舉報(bào)

30#
ID:514111 發(fā)表于 2019-5-8 22:24 | 只看該作者
可以向大家咨詢下關(guān)于PID控溫的其他問(wèn)題嗎?我的問(wèn)題是:為什么protues仿真中l(wèi)cd不顯示呢?求幫助,謝謝您了
回復(fù)

使用道具 舉報(bào)

31#
ID:409526 發(fā)表于 2019-5-23 20:24 | 只看該作者
程序有點(diǎn)問(wèn)題,按鍵也沒(méi)有進(jìn)行定義
回復(fù)

使用道具 舉報(bào)

32#
ID:526050 發(fā)表于 2019-6-5 13:57 | 只看該作者
大神厲害 剛好需要用到
回復(fù)

使用道具 舉報(bào)

33#
ID:448370 發(fā)表于 2019-6-16 18:15 | 只看該作者
編譯代碼沒(méi)問(wèn)題,一仿真就出現(xiàn)23 ERROR(S),都是ERROR L121: IMPROPER FIXUP.怎么解決啊,在線等,急
回復(fù)

使用道具 舉報(bào)

34#
ID:448370 發(fā)表于 2019-6-17 12:07 | 只看該作者
煙花易冷 發(fā)表于 2019-6-16 18:15
編譯代碼沒(méi)問(wèn)題,一仿真就出現(xiàn)23 ERROR(S),都是ERROR L121: IMPROPER FIXUP.怎么解決啊,在線等,急

這個(gè)問(wèn)題解決了,把工程設(shè)置中Options里的ROM改為large就行了。
可是仿真成功后,按鍵設(shè)置無(wú)反應(yīng),電熱爐也不加熱,LCD顯示也不改變。
回復(fù)

使用道具 舉報(bào)

35#
ID:564483 發(fā)表于 2019-6-17 15:08 | 只看該作者
值得學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

36#
ID:562503 發(fā)表于 2019-6-17 18:16 | 只看該作者
LCD顯示不成功啊
回復(fù)

使用道具 舉報(bào)

37#
ID:562818 發(fā)表于 2019-6-19 08:37 | 只看該作者
樓主,出現(xiàn)關(guān)鍵性錯(cuò)誤是怎么回事
回復(fù)

使用道具 舉報(bào)

38#
ID:565736 發(fā)表于 2019-6-19 11:44 | 只看該作者
kaili 發(fā)表于 2018-5-17 13:31
運(yùn)行后無(wú)法設(shè)置溫度,加熱裝置也不工作,蜂鳴器一直在報(bào)警

請(qǐng)問(wèn)怎么解決了
回復(fù)

使用道具 舉報(bào)

39#
ID:672345 發(fā)表于 2019-12-24 13:37 | 只看該作者
好資料,前來(lái)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

40#
ID:676780 發(fā)表于 2019-12-29 22:34 | 只看該作者
用oven那個(gè)圖的程序在哪啊?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表