久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

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

QQ登錄

只需一步,快速開始

搜索
查看: 52335|回復(fù): 24
收起左側(cè)

51單片機(jī)PID溫度控制程序

  [復(fù)制鏈接]
ID:73526 發(fā)表于 2015-2-11 15:52 | 顯示全部樓層 |閱讀模式
PID是比例,積分,微分的縮寫. 比例調(diào)節(jié)作用:是按比例反應(yīng)系統(tǒng)的偏差,系統(tǒng)一旦出現(xiàn)了偏差,比例調(diào)節(jié)立即產(chǎn)生調(diào)節(jié)作用用以減少偏差。比例作用大,可以加快調(diào)節(jié),減少誤差,但是過(guò)大的比例,使系統(tǒng)的穩(wěn)定性下降,甚至造成系統(tǒng)的不穩(wěn)定。積分調(diào)節(jié)作用:是使系統(tǒng)消除穩(wěn)態(tài)誤差,提高無(wú)差度。因?yàn)橛姓`差,積分調(diào)節(jié)就進(jìn)行,直至無(wú)差,積分調(diào)節(jié)停止,積分調(diào)節(jié)輸出一常值。積分作用的強(qiáng)弱取決與積分時(shí)間常數(shù)Ti,Ti越小,積分作用就越強(qiáng)。反之Ti大則積分作用弱,加入積分調(diào)節(jié)可使系統(tǒng)穩(wěn)定性下降,動(dòng)態(tài)響應(yīng)變慢。積分作用常與另兩種調(diào)節(jié)規(guī)律結(jié)合,組成PI調(diào)節(jié)器或PID調(diào)節(jié)器。微分調(diào)節(jié)作用:微分作用反映系統(tǒng)偏差信號(hào)的變化率,具有預(yù)見性,能預(yù)見偏差變化的趨勢(shì),因此能產(chǎn)生超前的控制作用,在偏差還沒(méi)有形成之前,已被微分調(diào)節(jié)作用消除。因此,可以改善系統(tǒng)的動(dòng)態(tài)性能。在微分時(shí)間選擇合適情況下,可以減少超調(diào),減少調(diào)節(jié)時(shí)間。微分作用對(duì)噪聲干擾有放大作用,因此過(guò)強(qiáng)的加微分調(diào)節(jié),對(duì)系統(tǒng)抗干擾不利。此外,微分反應(yīng)的是變化率,而當(dāng)輸入沒(méi)有變化時(shí),微分作用輸出為零。微分作用不能單獨(dú)使用,需要與另外兩種調(diào)節(jié)規(guī)律相結(jié)合,組成PD或PID控制器。

程序如下:
  1. /***********************************************************************
  2.                      PID溫度控制程序
  3. 程序說(shuō)明:
  4.    系統(tǒng)上電后顯示 “--溫度”
  5.    表示需要先設(shè)定溫度才開始進(jìn)行溫度檢測(cè)
  6.    溫度設(shè)定完畢后程序才開始進(jìn)行PID溫控
  7. ***********************************************************************/
  8. #include <reg52.h>
  9. #include <absacc.h>
  10. #include"DS18B20.H"
  11. #include"PID.H"
  12. #define uchar unsigned char
  13. #define uint unsigned int
  14. unsigned char code tab[]=
  15. {
  16.     0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xBF
  17. }
  18. ;
  19. /*個(gè)位0~9的數(shù)碼管段碼*/
  20. unsigned char code sao[]=
  21. {
  22.     0x7f,0xbf,0xdf,0xef
  23. }
  24. ;
  25. //掃描碼
  26. uchar set=30,keyflag=1 ; //set初始化為30° keyflag為進(jìn)入溫度設(shè)定的標(biāo)志位
  27. //4個(gè)按鍵使用說(shuō)明
  28. sbit key_out=P1^0 ; //用于溫度設(shè)定后的退出
  29. sbit key_up=P1^1 ; //設(shè)定溫度加
  30. sbit key_down=P1^2 ; //設(shè)定溫度減
  31. sbit key_in=P1^3 ; //在程序的運(yùn)行中如需要重新設(shè)定溫度 按下此鍵才能進(jìn)入設(shè)置模式并且此時(shí)是停在溫度控制的,按下key_out鍵后才表示設(shè)定完畢
  32. void Show_key();
  33. /***********************************************************/
  34. void delays(unsigned char k)
  35. {
  36.     unsigned char i,j ;
  37.     for(i=0;i<k;i++)
  38.     for(j=0;j<50;j++);
  39. }
  40. /*********************************************************
  41. //數(shù)碼管顯示函數(shù)
  42. P0口 作為數(shù)據(jù)口
  43. P2口的低四位作為掃描口

  44. 變量 x表示掃描
  45. d表示是否要加小數(shù)點(diǎn) 為1是 為0不加
  46. y表示傳遞的數(shù)值
  47. *********************************************************/
  48. LCD_disp_char(uchar x,bit d,uchar y)
  49. {
  50.     P2=0XFF ;
  51.     P0=0xFF ;
  52.     if(d==0)
  53.     P0=tab[y];
  54.     else
  55.     P0=tab[y]&0x7f ; //與上0x7f表示是否要加小數(shù)點(diǎn)
  56.     P2=sao[x]; //打開掃描端號(hào)
  57.    
  58. }
  59. /*********************************************************
  60. 按鍵掃描
  61. *********************************************************/

  62. void keyscan(void)
  63. {
  64.     if(key_in==0) //按鍵進(jìn)入函數(shù)
  65.     {
  66.         delays(10);    //延時(shí)消抖 (以下同)
  67.         if(key_in==0)
  68.         {
  69.             while(key_in==0)
  70.             {
  71.                 Show_key(); //如果一直按著鍵不放 就一直顯示在當(dāng)前狀態(tài) (以下同)
  72.             }
  73.             keyflag=1 ; //按鍵標(biāo)志位
  74.         }
  75.     }
  76.     /***********************/
  77.     if(key_out==0)   //按鍵退出
  78.     {
  79.         delays(10);
  80.         if(key_out==0)
  81.         {
  82.             while(key_out==0)
  83.             {
  84.                 Show_key();
  85.             }
  86.             keyflag=0 ;
  87.             set_temper=set ;
  88.         }
  89.     }
  90.     /*************************/
  91.     if(key_up==0)   //設(shè)定溫度的加
  92.     {
  93.         delays(10);
  94.         if(key_up==0)
  95.         {
  96.             while(key_up==0)
  97.             {
  98.                 Show_key();
  99.             }
  100.             if(keyflag==1)
  101.             {
  102.                 set++;
  103.                 if(set>90) //如果大于90°就不在加
  104.                 set=90 ;
  105.             }
  106.         }
  107.     }
  108.     /*************************/
  109.     if(key_down==0)   //溫度設(shè)定的減
  110.     {
  111.         delays(10);
  112.         if(key_down==0)
  113.         {
  114.             while(key_down==0)
  115.             {
  116.                 Show_key();
  117.             }
  118.             if(keyflag==1)
  119.             {
  120.                 set--;
  121.                 if(set<30) //溫度減到30°時(shí)不在往下減
  122.                 set=30 ;
  123.             }
  124.         }
  125.     }
  126. }
  127. /*********************************************************************
  128. 按鍵按下時(shí)的顯示函數(shù)
  129. ***********************************************************************/
  130. void Show_key()  
  131. {
  132.     output=1 ;
  133.     LCD_disp_char(3,0,10); //顯示 -
  134.     delays(3);
  135.     LCD_disp_char(2,0,10); //顯示- (表示溫度設(shè)定 )
  136.     delays(3);
  137.     LCD_disp_char(1,0,set/10); //顯示溫度十位
  138.     delays(3);
  139.     LCD_disp_char(0,0,set%10); //顯示溫度個(gè)位
  140.     delays(3);
  141. }
  142. /*****************************************************************/
  143. void main()
  144. {
  145.     unsigned int tmp ;//聲明溫度中間變量  
  146.     unsigned char counter=0 ;
  147.     PIDBEGIN(); //PID參數(shù)的初始化
  148.     output=1 ; //關(guān)閉繼電器輸出
  149.     while(1)
  150.     {
  151.         keyscan();
  152.         if(keyflag)
  153.         {
  154.             Show_key(); //顯示溫度設(shè)定
  155.         }
  156.         else
  157.         {
  158.             if(counter--==0)
  159.             {
  160.                 tmp=ReadTemperature();//每隔一段時(shí)間讀取溫度值
  161.                 counter=20 ;
  162.             }
  163.             LCD_disp_char(3,0,tmp/1000);   //顯示溫度十位
  164.             delays(3);
  165.             LCD_disp_char(2,1,tmp/100%10); //顯示溫度個(gè)位
  166.             //顯示小數(shù)點(diǎn)
  167.             delays(3);
  168.             LCD_disp_char(1,0,tmp/10%10); //顯示溫度小數(shù)后一位
  169.             delays(3);
  170.             LCD_disp_char(0,0,tmp%10);//顯示溫度小數(shù)后二位
  171.             delays(3);
  172.             P2=0XFF ;
  173.             P0=0xff ;
  174.             compare_temper(); //比較溫度
  175.            
  176.            
  177.         }
  178.     }
  179. }

  180. /**********************************************************************************************************************************************/

  181. //PID算法溫控C語(yǔ)言2008-08-17 18:58
  182. #ifndef _PID_H__
  183. #define _PID_H__

  184. #include<intrins.h>
  185. #include<math.h>
  186. #include<string.h>
  187. struct PID
  188. {
  189.     unsigned int SetPoint ;
  190.     // 設(shè)定目標(biāo) Desired Value
  191.     unsigned int Proportion ;
  192.     // 比例常數(shù) Proportional Const
  193.     unsigned int Integral ;
  194.     // 積分常數(shù) Integral Const
  195.     unsigned int Derivative ;
  196.     // 微分常數(shù) Derivative Const
  197.     unsigned int LastError ;
  198.     // Error[-1]
  199.     unsigned int PrevError ;
  200.     // Error[-2]
  201.     unsigned int SumError ;
  202.     // Sums of Errors
  203. }
  204. ;
  205. struct PID spid ;
  206. // PID Control Structure
  207. unsigned int rout ;
  208. // PID Response (Output)
  209. unsigned int rin ;
  210. // PID Feedback (Input)


  211. sbit output=P1^4;
  212. unsigned char high_time,low_time,count=0 ;
  213. //占空比調(diào)節(jié)參數(shù)
  214. unsigned char set_temper ;

  215. void PIDInit(struct PID*pp)
  216. {
  217.     memset(pp,0,sizeof(struct PID)); //PID參數(shù)初始化全部設(shè)置為0
  218. }

  219. unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)
  220. {
  221.     unsigned int dError,Error ;
  222.     Error=pp->SetPoint-NextPoint ;
  223.     // 偏差
  224.     pp->SumError+=Error ;
  225.     // 積分
  226.     dError=pp->LastError-pp->PrevError ;
  227.     // 當(dāng)前微分
  228.     pp->PrevError=pp->LastError ;
  229.     pp->LastError=Error ;
  230.     //比例
  231.     //積分項(xiàng)
  232.     return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);
  233.     // 微分項(xiàng)
  234. }

  235. /***********************************************************
  236. 溫度比較處理子程序
  237. ***********************************************************/
  238. void compare_temper()
  239. {
  240.     unsigned char i ;
  241.     //EA=0;
  242.     if(set_temper>temper)
  243.     {
  244.         if(set_temper-temper>1)
  245.         {
  246.             high_time=100 ; //大于1°不進(jìn)行PID運(yùn)算
  247.             low_time=0 ;
  248.         }
  249.         else
  250.         {   //在1°范圍內(nèi)進(jìn)行PID運(yùn)算
  251.             for(i=0;i<10;i++)
  252.             {
  253.                 //get_temper();
  254.                 rin=s;
  255.                 // Read Input
  256.                 rout=PIDCalc(&spid,rin); //執(zhí)行PID運(yùn)算
  257.                 // Perform PID Interation
  258.             }
  259.             if(high_time<=100) //限制最大值
  260.             high_time=(unsigned char)(rout/800);
  261.             else
  262.             high_time=100;
  263.             low_time=(100-high_time);
  264.         }
  265.     }
  266. /****************************************/
  267.     else if(set_temper<=temper) //當(dāng)實(shí)際溫度大于設(shè)置溫度時(shí)
  268.     {
  269.         if(temper-set_temper>0)//如果實(shí)際溫度大于設(shè)定溫度
  270.         {
  271.             high_time=0 ;
  272.             low_time=100 ;
  273.         }
  274.         else
  275.         {
  276.             for(i=0;i<10;i++)
  277.             {
  278.                 //get_temper();
  279.                 rin=s ;
  280.                 // Read Input
  281.                 rout=PIDCalc(&spid,rin);
  282.                 // Perform PID Interation
  283.             }
  284.             if(high_time<100) //此變量是無(wú)符號(hào)字符型
  285.             high_time=(unsigned char)(rout/10000);
  286.             else
  287.             high_time=0 ;//限制不輸出負(fù)值
  288.             low_time=(100-high_time);
  289.             //EA=1;
  290.         }
  291.     }
  292. }


  293. /*****************************************************
  294. T0中斷服務(wù)子程序,用于控制電平的翻轉(zhuǎn) ,40us*100=4ms周期
  295. ******************************************************/
  296. void serve_T0()interrupt 1 using 1
  297. {
  298.     if(++count<=(high_time))
  299.          output=0 ;
  300.     else if(count<=100)
  301.     {
  302.         output=1 ;
  303.     }
  304.     else
  305.     count=0 ;
  306.     TH0=0x2f ;
  307.     TL0=0xe0 ;
  308. }

  309. void PIDBEGIN()
  310. {
  311.    
  312.     TMOD=0x01 ;
  313.     TH0=0x2f ;
  314.     TL0=0x40 ;
  315.    
  316.     EA=1 ;
  317.     ET0=1 ;
  318.     TR0=1 ;
  319.    
  320.     high_time=50 ;
  321.     low_time=50 ;
  322.     PIDInit(&spid);
  323.     // Initialize Structure
  324.     spid.Proportion=10 ;
  325.     // Set PID Coefficients
  326.     spid.Integral=8 ;
  327.     spid.Derivative=6 ;
  328.     spid.SetPoint=100 ;
  329.     // Set PID Setpoint
  330.    
  331. }
  332. #endif
復(fù)制代碼



回復(fù)

使用道具 舉報(bào)

ID:82175 發(fā)表于 2015-6-6 10:30 | 顯示全部樓層
make an effort  51hei有你更精彩!!
回復(fù)

使用道具 舉報(bào)

ID:83639 發(fā)表于 2015-6-22 19:24 | 顯示全部樓層
rin=s,這里的s你在哪里定義過(guò)?突然就出現(xiàn)了啊
回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2015-11-17 16:33 | 顯示全部樓層
szyzw 發(fā)表于 2015-6-22 19:24
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

struct PID spid ;
// PID Control Structure
unsigned int rout ;
// PID Response (Output)
unsigned int rin ;
// PID Feedback (Input)

你看214行的定義
回復(fù)

使用道具 舉報(bào)

ID:79544 發(fā)表于 2015-12-27 18:44 | 顯示全部樓層
樓主,其他的.h文件呢?
回復(fù)

使用道具 舉報(bào)

ID:102615 發(fā)表于 2016-1-10 13:33 | 顯示全部樓層
都沒(méi)見仿真圖呢
回復(fù)

使用道具 舉報(bào)

ID:106833 發(fā)表于 2016-3-1 13:34 | 顯示全部樓層
不想說(shuō)有多少錯(cuò)誤了
回復(fù)

使用道具 舉報(bào)

ID:103523 發(fā)表于 2016-4-20 17:23 | 顯示全部樓層
high_time=(unsigned char)(rout/800);樓主  這個(gè)為什么要除以800而不是其他數(shù)值  怎么算的呀  求回答  非常感謝!
回復(fù)

使用道具 舉報(bào)

ID:59609 發(fā)表于 2016-8-10 10:32 | 顯示全部樓層
這好的程序
為什么不把它做的更完美呢
回復(fù)

使用道具 舉報(bào)

ID:147531 發(fā)表于 2017-1-16 13:42 | 顯示全部樓層
admin 發(fā)表于 2015-11-17 16:33
struct PID spid ;
// PID Control Structure
unsigned int rout ;

他問(wèn)的應(yīng)該是第264行中 rin =s 中的 s 是怎么來(lái)的
回復(fù)

使用道具 舉報(bào)

ID:169407 發(fā)表于 2017-3-13 15:05 | 顯示全部樓層
li562721098 發(fā)表于 2016-3-1 13:34
**** 作者被禁止或刪除 內(nèi)容自動(dòng)屏蔽 ****

很多錯(cuò)誤?
回復(fù)

使用道具 舉報(bào)

ID:71525 發(fā)表于 2017-4-17 11:11 來(lái)自手機(jī) | 顯示全部樓層
整個(gè)分析了他的代碼,這樣的程序你發(fā)上來(lái)有什么意思?你用PID的意義何在?當(dāng)溫度超調(diào)你就不再加熱,這個(gè)自動(dòng)調(diào)節(jié)有違背呀。還有你的定時(shí)器實(shí)現(xiàn)PWM明顯邏輯錯(cuò)誤…我不知道說(shuō)什么好。誤人子弟,浪費(fèi)我墨水。

評(píng)分

參與人數(shù) 1黑幣 +40 收起 理由
admin + 40 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:161033 發(fā)表于 2017-6-4 23:39 | 顯示全部樓層
感謝,先下后看。
回復(fù)

使用道具 舉報(bào)

ID:110278 發(fā)表于 2017-7-23 15:57 | 顯示全部樓層
感謝分享分享。。。。
回復(fù)

使用道具 舉報(bào)

ID:229761 發(fā)表于 2017-9-12 11:24 | 顯示全部樓層
黑橙orangerx 發(fā)表于 2017-1-16 13:42
他問(wèn)的應(yīng)該是第264行中 rin =s 中的 s 是怎么來(lái)的

他還有的文件沒(méi)顯示出來(lái),應(yīng)該是溫度傳感器里面的
回復(fù)

使用道具 舉報(bào)

ID:167679 發(fā)表于 2017-12-8 12:43 | 顯示全部樓層
zae234234 發(fā)表于 2017-4-17 11:11
整個(gè)分析了他的代碼,這樣的程序你發(fā)上來(lái)有什么意思?你用PID的意義何在?當(dāng)溫度超調(diào)你就不再加熱,這個(gè)自 ...

一看到ds18b20 就應(yīng)該知道 這不是什么正經(jīng)的PID 溫控 ,頂多算學(xué)校練手的東西 ,  真正的經(jīng)典的pid溫控都是用51單片機(jī)做的雙積分adc 然后可以達(dá)到比較高的采樣分辨率 ,萬(wàn)能信號(hào)輸入.
回復(fù)

使用道具 舉報(bào)

ID:266854 發(fā)表于 2017-12-30 14:47 | 顯示全部樓層
harvardx 發(fā)表于 2017-12-8 12:43
一看到ds18b20 就應(yīng)該知道 這不是什么正經(jīng)的PID 溫控 ,頂多算學(xué)校練手的東西 ,  真正的經(jīng)典的pid溫控都是 ...

您是指PID溫控的話使用DS18B20是不合適的嗎?
回復(fù)

使用道具 舉報(bào)

ID:294233 發(fā)表于 2018-6-25 20:48 | 顯示全部樓層
樓主請(qǐng)問(wèn)一下
if(high_time<=100) //限制最大值
            high_time=(unsigned char)(rout/800);
            else
            high_time=100;
            low_time=(100-high_time);
這一塊程序里面的紅色部分是什么原理,看不懂,加急求回復(fù)
回復(fù)

使用道具 舉報(bào)

ID:346116 發(fā)表于 2018-10-27 10:01 | 顯示全部樓層
樓主估計(jì)是在哪里抄來(lái)的,他沒(méi)辦法解答大家的疑問(wèn)
回復(fù)

使用道具 舉報(bào)

ID:346116 發(fā)表于 2018-10-27 10:41 | 顯示全部樓層
zae234234 發(fā)表于 2017-4-17 11:11
整個(gè)分析了他的代碼,這樣的程序你發(fā)上來(lái)有什么意思?你用PID的意義何在?當(dāng)溫度超調(diào)你就不再加熱,這個(gè)自 ...

中斷控制電平翻轉(zhuǎn),確實(shí)邏輯有錯(cuò)誤,若pid算出了的high_time = 0,outpu = 1,并非預(yù)想中的output = 0。

評(píng)分

參與人數(shù) 1黑幣 +20 收起 理由
admin + 20 回帖助人的獎(jiǎng)勵(lì)!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:358930 發(fā)表于 2018-10-31 21:40 來(lái)自手機(jī) | 顯示全部樓層
mingzinanqu 發(fā)表于 2018-6-25 20:48
樓主請(qǐng)問(wèn)一下
if(high_time

high_time=(unsigned char)(rout/800);紅色大約代表,high_time=(rout/800)后強(qiáng)制轉(zhuǎn)為255
的char型變量。
回復(fù)

使用道具 舉報(bào)

ID:456973 發(fā)表于 2018-12-28 08:12 | 顯示全部樓層
PID算法新人,學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:146874 發(fā)表于 2018-12-28 08:45 | 顯示全部樓層
太感謝分享了,很值得研究
回復(fù)

使用道具 舉報(bào)

ID:517951 發(fā)表于 2020-11-15 14:20 | 顯示全部樓層

收藏學(xué)習(xí)學(xué)習(xí),謝謝樓主了
回復(fù)

使用道具 舉報(bào)

ID:67838 發(fā)表于 2022-10-18 15:47 | 顯示全部樓層
感謝,先下后看。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 99精品欧美一区二区三区综合在线 | 91国内在线观看 | 黑人巨大精品 | 国产一区二区欧美 | a毛片视频网站 | 中文字字幕一区二区三区四区五区 | 国产高清在线 | 欧美综合一区 | 手机看黄av免费网址 | 亚洲国产成人在线视频 | 欧美成人a | 视频一区二区在线观看 | 国产在线永久免费 | 国产精品久久久久一区二区三区 | 天堂网色| 免费看国产片在线观看 | 新超碰97 | 欧美日韩精品区 | 一区二区三区不卡视频 | 九九综合 | 欧产日产国产精品视频 | 日日夜夜天天久久 | 成人在线播放网址 | 成人1区2区| 亚洲国产一区二区三区, | 91成人在线视频 | 免费看黄色视屏 | 日本精品一区二区三区在线观看 | 国产激情免费视频 | 在线看片福利 | 日本手机看片 | 国产成人jvid在线播放 | 成人精品视频99在线观看免费 | 视频国产一区 | 欧美999 | 成人精品一区二区三区中文字幕 | 波多野结衣先锋影音 | 日韩精品一二三 | 超碰97免费 | 中文在线视频观看 | 99久久精品免费看国产小宝寻花 |