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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9322|回復: 10
打印 上一主題 下一主題
收起左側

PID溫度控制系統源序程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:76686 發表于 2015-4-12 02:29 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
       溫度控制電子小制作, 要想得到比較好的控制效果,本介紹的PID溫度控制系統源序程序,是你不錯的參考實例。PID是比例,積分,微分的縮寫, 比例調節作用:是按比例反應系 統的偏差,系統一旦出現了偏差,比例調節立即產生調節作用用以減少偏差。比例作用大,可以加快調節,減少誤差,但是過大的比例,使系統的穩定性下降,甚至 造成系統的不穩定。積分調節作用:是使系統消除穩態誤差,提高無差度。因為有誤差,積分調節就進行,直至無差,積分調節停止,積分調節輸出一常值。積分作 用的強弱取決與積分時間常數Ti,Ti越小,積分作用就越強。反之Ti大則積分作用弱,加入積分調節可使系統穩定性下降,動態響應變慢。積分作用常與另兩 種調節規律結合,組成PI調節器或PID調節器。微分調節作用:微分作用反映系統偏差信號的變化率,具有預見性,能預見偏差變化的趨勢,因此能產生超前的 控制作用,在偏差還沒有形成之前,已被微分調節作用消除。因此,可以改善系統的動態性能。在微分時間選擇合適情況下,可以減少超調,減少調節時間。微分作 用對噪聲干擾有放大作用,因此過強的加微分調節,對系統抗干擾不利。此外,微分反應的是變化率,而當輸入沒有變化時,微分作用輸出為零。微分作用不能單獨 使用,需要與另外兩種調節規律相結合,組成PD或PID控制器。



源程序:
  1. /***********************************************************************
  2.                      PID溫度控制程序
  3.     程序說明:
  4.    系統上電后顯示 “--溫度”
  5.    表示需要先設定溫度才開始進行溫度檢測
  6.    溫度設定完畢后程序才開始進行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. /*個位0~9的數碼管段碼*/
  20. unsigned char code sao[]=
  21. {
  22.     0x7f,0xbf,0xdf,0xef
  23. }
  24. ;
  25. //掃描碼
  26. uchar set=30,keyflag=1 ; //set初始化為30° keyflag為進入溫度設定的標志位
  27. //4個按鍵使用說明
  28. sbit key_out=P1^0 ; //用于溫度設定后的退出
  29. sbit key_up=P1^1 ; //設定溫度加
  30. sbit key_down=P1^2 ; //設定溫度減
  31. sbit key_in=P1^3 ; //在程序的運行中如需要重新設定溫度 按下此鍵才能進入設置模式并且此時是停在溫度控制的,按下key_out鍵后才表示設定完畢
  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. //數碼管顯示函數
  42. P0口 作為數據口
  43. P2口的低四位作為掃描口

  44. 變量 x表示掃描
  45. d表示是否要加小數點 為1是 為0不加
  46. y表示傳遞的數值
  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表示是否要加小數點
  56.     P2=sao[x]; //打開掃描端號
  57.    
  58. }
  59. /*********************************************************
  60. 按鍵掃描
  61. *********************************************************/

  62. void keyscan(void)
  63. {
  64.     if(key_in==0) //按鍵進入函數
  65.     {
  66.         delays(10);    //延時消抖 (以下同)
  67.         if(key_in==0)
  68.         {
  69.             while(key_in==0)
  70.             {
  71.                 Show_key(); //如果一直按著鍵不放 就一直顯示在當前狀態 (以下同)
  72.             }
  73.             keyflag=1 ; //按鍵標志位
  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)   //設定溫度的加
  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)   //溫度設定的減
  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°時不在往下減
  122.                 set=30 ;
  123.             }
  124.         }
  125.     }
  126. }
  127. /*********************************************************************
  128. 按鍵按下時的顯示函數
  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); //顯示- (表示溫度設定 )
  136.     delays(3);
  137.     LCD_disp_char(1,0,set/10); //顯示溫度十位
  138.     delays(3);
  139.     LCD_disp_char(0,0,set%10); //顯示溫度個位
  140.     delays(3);
  141. }
  142. /*****************************************************************/
  143. void main()
  144. {
  145.     unsigned int tmp ;//聲明溫度中間變量   
  146.     unsigned char counter=0 ;
  147.     PIDBEGIN(); //PID參數的初始化
  148.     output=1 ; //關閉繼電器輸出
  149.     while(1)
  150.     {
  151.         keyscan();
  152.         if(keyflag)
  153.         {
  154.             Show_key(); //顯示溫度設定
  155.         }
  156.         else
  157.         {
  158.             if(counter--==0)
  159.             {
  160.                 tmp=ReadTemperature();//每隔一段時間讀取溫度值
  161.                 counter=20 ;
  162.             }
  163.             LCD_disp_char(3,0,tmp/1000);   //顯示溫度十位
  164.             delays(3);
  165.             LCD_disp_char(2,1,tmp/100%10); //顯示溫度個位
  166.             //顯示小數點
  167.             delays(3);
  168.             LCD_disp_char(1,0,tmp/10%10); //顯示溫度小數后一位
  169.             delays(3);
  170.             LCD_disp_char(0,0,tmp%10);//顯示溫度小數后二位
  171.             delays(3);
  172.             P2=0XFF ;
  173.             P0=0xff ;
  174.             compare_temper(); //比較溫度
  175.             
  176.             
  177.         }
  178.     }
  179. }

  180. /**********************************************************************************************************************************************/
復制代碼

另外一個文件:
  1. //PID算法溫控C語言2008-08-17 18:58
  2. #ifndef _PID_H__
  3. #define _PID_H__

  4. #include<intrins.h>
  5. #include<math.h>
  6. #include<string.h>
  7. struct PID
  8. {
  9.     unsigned int SetPoint ;
  10.     // 設定目標 Desired Value
  11.     unsigned int Proportion ;
  12.     // 比例常數 Proportional Const
  13.     unsigned int Integral ;
  14.     // 積分常數 Integral Const
  15.     unsigned int Derivative ;
  16.     // 微分常數 Derivative Const
  17.     unsigned int LastError ;
  18.     // Error[-1]
  19.     unsigned int PrevError ;
  20.     // Error[-2]
  21.     unsigned int SumError ;
  22.     // Sums of Errors
  23. }
  24. ;
  25. struct PID spid ;
  26. // PID Control Structure
  27. unsigned int rout ;
  28. // PID Response (Output)
  29. unsigned int rin ;
  30. // PID Feedback (Input)


  31. sbit output=P1^4;
  32. unsigned char high_time,low_time,count=0 ;
  33. //占空比調節參數
  34. unsigned char set_temper ;

  35. void PIDInit(struct PID*pp)
  36. {
  37.     memset(pp,0,sizeof(struct PID)); //PID參數初始化全部設置為0
  38. }

  39. unsigned int PIDCalc(struct PID*pp,unsigned int NextPoint)
  40. {
  41.     unsigned int dError,Error ;
  42.     Error=pp->SetPoint-NextPoint ;
  43.     // 偏差
  44.     pp->SumError+=Error ;
  45.     // 積分
  46.     dError=pp->LastError-pp->PrevError ;
  47.     // 當前微分
  48.     pp->PrevError=pp->LastError ;
  49.     pp->LastError=Error ;
  50.     //比例
  51.     //積分項
  52.     return(pp->Proportion*Error+pp->Integral*pp->SumError+pp->Derivative*dError);
  53.     // 微分項
  54. }

  55. /***********************************************************
  56. 溫度比較處理子程序
  57. ***********************************************************/
  58. void compare_temper()
  59. {
  60.     unsigned char i ;
  61.     //EA=0;
  62.     if(set_temper>temper)
  63.     {
  64.         if(set_temper-temper>1)
  65.         {
  66.             high_time=100 ; //大于1°不進行PID運算
  67.             low_time=0 ;
  68.         }
  69.         else
  70.         {   //在1°范圍內進行PID運算
  71.             for(i=0;i<10;i++)
  72.             {
  73.                 //get_temper();
  74.                 rin=s;
  75.                 // Read Input
  76.                 rout=PIDCalc(&spid,rin); //執行PID運算
  77.                 // Perform PID Interation
  78.             }
  79.             if(high_time<=100) //限制最大值
  80.             high_time=(unsigned char)(rout/800);
  81.             else
  82.             high_time=100;
  83.             low_time=(100-high_time);
  84.         }
  85.     }
  86. /****************************************/
  87.     else if(set_temper<=temper) //當實際溫度大于設置溫度時
  88.     {
  89.         if(temper-set_temper>0)//如果實際溫度大于設定溫度
  90.         {
  91.             high_time=0 ;
  92.             low_time=100 ;
  93.         }
  94.         else
  95.         {
  96.             for(i=0;i<10;i++)
  97.             {
  98.                 //get_temper();
  99.                 rin=s ;
  100.                 // Read Input
  101.                 rout=PIDCalc(&spid,rin);
  102.                 // Perform PID Interation
  103.             }
  104.             if(high_time<100) //此變量是無符號字符型
  105.             high_time=(unsigned char)(rout/10000);
  106.             else
  107.             high_time=0 ;//限制不輸出負值
  108.             low_time=(100-high_time);
  109.             //EA=1;
  110.         }
  111.     }
  112. }


  113. /*****************************************************
  114. T0中斷服務子程序,用于控制電平的翻轉 ,40us*100=4ms周期
  115. ******************************************************/
  116. void serve_T0()interrupt 1 using 1
  117. {
  118.     if(++count<=(high_time))
  119.          output=0 ;
  120.     else if(count<=100)
  121.     {
  122.         output=1 ;
  123.     }
  124.     else
  125.     count=0 ;
  126.     TH0=0x2f ;
  127.     TL0=0xe0 ;
  128. }

  129. void PIDBEGIN()
  130. {
  131.    
  132.     TMOD=0x01 ;
  133.     TH0=0x2f ;
  134.     TL0=0x40 ;
  135.    
  136.     EA=1 ;
  137.     ET0=1 ;
  138.     TR0=1 ;
  139.    
  140.     high_time=50 ;
  141.     low_time=50 ;
  142.     PIDInit(&spid);
  143.     // Initialize Structure
  144.     spid.Proportion=10 ;
  145.     // Set PID Coefficients
  146.     spid.Integral=8 ;
  147.     spid.Derivative=6 ;
  148.     spid.SetPoint=100 ;
  149.     // Set PID Setpoint
  150.    
  151. }
  152. #endif
復制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏8 分享淘帖 頂 踩
回復

使用道具 舉報

沙發
ID:74826 發表于 2015-4-29 15:51 | 只看該作者
p1.4口接的是什么
回復

使用道具 舉報

板凳
ID:56948 發表于 2015-5-10 15:41 | 只看該作者
既然把程序貼出來了,為什么只貼程序的片段呢,這樣對其他人也沒有什么意義啊
回復

使用道具 舉報

地板
ID:79943 發表于 2015-5-15 10:19 | 只看該作者
   溫度控制電子小制作, 要想得到比較好的控制效果,本介紹的PID溫度控制系統源序程序,是你不錯的參考實例。PID是比例,積分,微分的縮寫, 比例調節作用:是按比例反應系 統的偏差,系統一旦出現了偏差,比例調節立即產生調節作用用以減少偏差。比例作用大,可以加快調節,減少誤差,但是過大的比例,使系統的穩定性下降,甚至 造成系統的不穩定。積分調節作用:是使系統消除穩態誤差,提高無差度。
回復

使用道具 舉報

5#
ID:87799 發表于 2015-8-7 08:25 | 只看該作者
看看!
回復

使用道具 舉報

6#
ID:103523 發表于 2016-4-20 17:22 | 只看該作者
high_time=(unsigned char)(rout/800);為什么除以800呀?謝謝
回復

使用道具 舉報

7#
ID:106429 發表于 2016-5-27 13:08 | 只看該作者
這個比較復雜!支持一下
回復

使用道具 舉報

8#
ID:74145 發表于 2016-5-30 23:16 | 只看該作者
有幫助  謝謝分享
回復

使用道具 舉報

9#
ID:138549 發表于 2016-9-6 16:56 | 只看該作者
#include <absacc.h> 這個頭文件 在哪里呀???
回復

使用道具 舉報

10#
ID:387410 發表于 2019-5-10 07:49 來自手機 | 只看該作者
樓主很優秀
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 女人天堂av | 天天狠狠 | 久久久国产精品入口麻豆 | 日韩成人在线视频 | 欧美国产精品一区二区 | 久久艹免费视频 | 日韩一区二区在线播放 | 欧产日产国产精品国产 | 日韩视频在线免费观看 | 国产精品久久久久久亚洲调教 | 久久精品二区亚洲w码 | 欧美精品福利视频 | 成人在线观看免费视频 | 福利社午夜影院 | 久久久久久久久综合 | www.玖玖玖| 国产欧美日韩精品一区二区三区 | 人人澡人人爱 | 亚洲一区二区三区在线播放 | 久久一区二区三区四区 | 久久99这里只有精品 | 日韩成人在线播放 | 国产探花在线精品一区二区 | 欧美福利三区 | 久热精品在线播放 | 综合成人在线 | 黄页网址在线观看 | 男女下面一进一出网站 | 国产精品久久久久久 | 欧美国产日韩在线观看 | 欧美极品在线观看 | 亚洲91 | 综合在线视频 | 亚洲中午字幕 | 一区二区三区中文字幕 | 狠狠操天天干 | 精品国产一区二区三区久久影院 | 一区二区中文 | 羞羞色在线观看 | 欧美精品中文 | 羞羞视频在线观看免费观看 |