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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

改良基于51單片機pid算法水溫控制系統程序+Proteus仿真

  [復制鏈接]
跳轉到指定樓層
樓主
實現了升溫,降溫控制,用了pid算法


單片機源程序如下:
  1. #include <REG51.H>
  2. #define Kp 18        //比例系數 18
  3. #define Ki 13 //積分系數  13
  4. #define Kd 0.8        //微分系數 0.3

  5. unsigned char m,n,p;                          //溫度的十位 個位 小數
  6. unsigned char test_temp;                //溫度檢定標志
  7. unsigned char key_set_flag;                //按鍵設定進入標志
  8. unsigned char flag=1;                        //按鍵保持標志
  9. unsigned char Change_step=1;        //溫度設置步進
  10. unsigned char T0_H = 0,T0_L = 0,T1_H=0,T1_L=0,T0h=0,T0l=0;
  11. unsigned char t0=0,t1=0;

  12. int Real_temp;                //實際溫度值
  13. int Set_temp;                //設置溫度
  14. int Disp_temp;                //顯示溫度
  15. int last_error;                //上次誤差
  16. float I_term;                //前面溫差和
  17. bit        key_hold;
  18. int PID_MAX;
  19. unsigned int out,PWMT,counter,kk,outp;
  20. int time;        //脈沖觸發時刻

  21. sbit DQ=P1^0;        //定義DS18b20的管腳        1.0
  22. sbit L1=P2^0;        //定義控制數碼管的管腳
  23. sbit L2=P2^2;
  24. sbit L3=P2^4;
  25. sbit L4=P2^6;
  26. sbit k1=P3^3;
  27. sbit k2=P3^4;
  28. sbit k3=P3^5;
  29. sbit PWM=P2^7;        //PWM控制腳
  30. //sbit jia=P2^5;

  31. unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x7F,0xbF,0xC6};//0-9數字,后面為". - C"

  32. /*****延時子程序*****/
  33. void delay(unsigned int t)
  34. {
  35.         for(;t>0;t--);
  36. }
  37. void delay_50us(unsigned int t)
  38. {
  39.         unsigned char j;
  40.         for(;t>0;t--)
  41.                 for(j=19;j>0;j--);
  42. }

  43. /*****初始化DS18B20*****/
  44. unsigned char Init_DS18B20(void)
  45. {
  46.   unsigned char x=0;
  47.   DQ = 1;      //DQ復位
  48.   delay(8);    //稍做延時
  49.   DQ = 0;      //單片機將DQ拉低
  50.   delay(80);   //精確延時,大于480us
  51.   DQ = 1;      //拉高總線
  52.   delay(8);
  53.   x = DQ;      //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗
  54.   delay(4);
  55.   return x;
  56. }

  57. /*****讀一個字節*****/
  58. unsigned char ReadOneChar(void)
  59. {
  60.   unsigned char i=0;
  61.   unsigned char dat = 0;
  62.   for (i=8;i>0;i--)
  63.   {
  64.     DQ = 0;     // 給脈沖信號
  65.     dat>>=1;
  66.     DQ = 1;     // 給脈沖信號
  67.     if(DQ)
  68.             dat|=0x80;
  69.         delay(4);
  70.   }
  71.   return(dat);
  72. }

  73. /*****寫一個字節*****/
  74. void WriteOneChar(unsigned char dat)
  75. {
  76.   unsigned char i=0;
  77.   for (i=8; i>0; i--)
  78.   {
  79.     DQ = 0;
  80.     DQ = dat&0x01;
  81.         delay(4);
  82.     DQ = 1;
  83.     dat>>=1;
  84.   }
  85.   delay(4);
  86. }

  87. /*****讀取溫度*****/
  88. int ReadTemperature(void)
  89. {
  90.           unsigned char a=0;
  91.           unsigned char b=0;
  92.           unsigned int t=0;
  93.           t=Init_DS18B20();
  94.           if(t) return Real_temp;
  95.           WriteOneChar(0xCC);  //跳過讀序號列號的操作
  96.           WriteOneChar(0x44);  //啟動溫度轉換
  97.           t=Init_DS18B20();
  98.           if(t) return Real_temp;
  99.           WriteOneChar(0xCC);  //跳過讀序號列號的操作
  100.           WriteOneChar(0xBE);  //讀取溫度寄存器
  101.           a=ReadOneChar();     //讀低8位
  102.           b=ReadOneChar();     //讀高8位
  103.           t=b;
  104.           t<<=8;
  105.           t=t|a;
  106.           if(t<=0||t>0x900)
  107.         return Real_temp;
  108.         t=t*0.625+0.5;
  109.           return(t);
  110. }


  111. void display(signed int dd)//數碼管掃描函數
  112. {
  113.     int tt=0;   

  114.     tt= dd; //放大10倍輸出并四舍五入
  115.         m=tt/100;                //分離出十位
  116.         n=(tt%100)/10;        //分離出個位
  117.         p=tt%10;                //分離出小數位
  118.                                                                                           //m
  119.         P0=table[12];
  120.         L1=0;                        //暫未1,如用三極管驅動要改為0                 L1
  121.         delay(300);
  122.         L1=1;                        //后關閉顯示

  123.         P0=table[n];                           //n
  124.         L3=0;                                                                                //L2
  125.         delay(300);
  126.         L3=1;
  127.         P0=table[10];                          //10
  128.         L3=0;                                                                                  //L2
  129.         delay(300);
  130.         L3=1;

  131.         P0=table[p];        //小數部分p
  132.         L2=0;                                                                                        //L3
  133.         delay(300);
  134.         L2=1;

  135.         P0=table[m];                         //12
  136.         L4=0;
  137.         delay(300);
  138.         L4=1;
  139. }

  140. void key_set(void)
  141. {
  142.         if(k1==0)
  143.         {
  144.                 delay(10);
  145.                 while(!k1);
  146.                 key_hold=~key_hold;
  147.         }
  148.         if(key_hold==0)
  149.         {
  150.             if(k2==0)
  151.                 {
  152.                         delay(10);
  153.                     while(!k2);
  154.                         Set_temp=Set_temp+1;
  155.                         if(Set_temp>99)
  156.                         Set_temp=99;
  157.                 }
  158.         }
  159.         if(key_hold==0)
  160.         {
  161.             if(k3==0)
  162.                 {
  163.                         delay(10);
  164.                         while(!k3);
  165.                         Set_temp=Set_temp-1;
  166.                         if(Set_temp<1)
  167.                         Set_temp=1;
  168.                 }
  169.         }
  170. }

  171. int PID(int Set_value,int Real_value) //標準PID溫度控制算法
  172. {
  173.         float uk ,uk1 ,duk;
  174.         int pid_out,e ,e1 ,e2;
  175.         e=Set_value-Real_value;//誤差量
  176.         duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2);  //+Kd*(e-2e1+e2)
  177.         uk=uk1+duk;
  178.         pid_out=(int)uk;
  179.         uk1=uk;
  180.         e2=e1;
  181.         e1=e;
  182.         if(pid_out>1000) //1000
  183.         {
  184.                 pid_out=990;//        990
  185.         }
  186.         else if(pid_out<10)         //10
  187.         {
  188.                 pid_out=10;                //10
  189.         }
  190.         outp=pid_out;

  191.         return(pid_out);
  192.                
  193. }


  194. void T0_int(void) interrupt 1
  195. {
  196.         T0_H = (65535-2000)/256;                                //PWM=1高位初值計算
  197.         T0_L = (65535-2000)%256;                                          //PWM=1低位初值計算

  198.         TH0 = T0_H;                                 //通的初值高位
  199.         TL0= T0_L;                                 //通的初值低位


  200.         kk++;
  201.         if(kk>1000)
  202.         kk=0;
  203.         if(kk>outp)
  204.         {PWM=1;
  205.         // jia=1;
  206.           }
  207.         else {PWM=0;
  208.              //jia=0;
  209.         }
  210.        
  211.          
  212. }
  213.                  
  214. void main()
  215. {       
  216.         PWMT=128;                        //128級步進PWM控制               
  217.         PID_MAX=PWMT;
  218.         counter=0;
  219.         out=0;
  220.         PWM=1;
  221.    // jia=1;

  222.         I_term=0;
  223.         last_error=0;
  224.         Set_temp=40;                //初始設定溫度為41度
  225.         Real_temp=Set_temp*10;
  226.         key_hold=1;
  227.           Init_DS18B20();
  228.           WriteOneChar(0xCC);        //跳過讀序號列號的操作
  229.           WriteOneChar(0x44); //啟動溫度轉換
  230.         delay_50us(15000);        //等待溫度測量         15000
  231.         TMOD=0x01;                        //定時器0模式1               
  232.         TR0=1;                                                                  
  233.         ET0=1;
  234.         IT0=1;
  235.         EX0=1;
  236.         EA=1;
  237.        
  238.         while(1)
  239.         {
  240.                 counter++;
  241.                 if(counter>40)        //if(counter>40)
  242.                 {
  243.                         test_temp=1;        //進行一次溫度檢定
  244.                         counter=0;                               
  245.                 }
  246.                 if(test_temp)         //溫度檢定標志置位,進入溫度PID調節
  247.                 {
  248.                         Real_temp=ReadTemperature(); //采集當前實際溫度
  249.                         if(Real_temp>Set_temp*10)
  250.                         PWM=1;
  251.                         else                       
  252.                         PID(Set_temp*10,Real_temp); //PID程序
  253.                         test_temp=0;                                 //檢定完成,清溫度檢定標志
  254.                 }       
  255.                 if(key_hold)
  256.                 Disp_temp=Real_temp;
  257.                 else Disp_temp=Set_temp;
  258.                 display(Disp_temp);       
  259.                 key_set();        //按鍵溫度設置
  260.         }
  261. }
復制代碼

所有資料51hei提供下載:
水溫控制系統1.zip (338.66 KB, 下載次數: 533)


評分

參與人數 2黑幣 +70 收起 理由
yanyuwei + 20 很給力!
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:165363 發表于 2019-6-24 10:04 | 只看該作者
感謝分享,學習一下。
回復

使用道具 舉報

板凳
ID:597627 發表于 2019-8-17 11:23 | 只看該作者
感謝,很有用 學習了
回復

使用道具 舉報

地板
ID:546381 發表于 2019-11-25 16:24 | 只看該作者
感謝分享,學習一下。不知道能不能用
回復

使用道具 舉報

5#
ID:665952 發表于 2019-12-17 10:00 來自觸屏版 | 只看該作者
感謝分享。非常好用
回復

使用道具 舉報

6#
ID:665952 發表于 2019-12-17 10:07 | 只看該作者
挺好用的 非常完美
回復

使用道具 舉報

7#
ID:666029 發表于 2019-12-17 10:48 | 只看該作者
挺全面呀,發現新大陸
回復

使用道具 舉報

8#
ID:666029 發表于 2019-12-17 10:48 | 只看該作者
感謝,仿真圖有高清版嗎,大神
回復

使用道具 舉報

9#
ID:666029 發表于 2019-12-17 13:40 | 只看該作者
1151541640 發表于 2019-12-17 10:00
感謝分享。非常好用

確實挺好用
回復

使用道具 舉報

10#
ID:97678 發表于 2019-12-17 14:25 | 只看該作者
好東西,值得學習!!!!!!!!!!
回復

使用道具 舉報

11#
ID:67838 發表于 2020-1-2 20:25 | 只看該作者
效果不太理想,數據誤差太大
回復

使用道具 舉報

12#
ID:292097 發表于 2020-1-2 22:46 | 只看該作者
樓主太優秀了
回復

使用道具 舉報

13#
ID:67838 發表于 2020-1-5 00:39 | 只看該作者
做成實物,數碼管閃爍厲害,調整溫度只能調到9.9度,望樓主審查后再發出來
回復

使用道具 舉報

14#
ID:67838 發表于 2020-1-5 00:40 | 只看該作者
else Disp_temp=Set_temp;這句代碼不全281行
回復

使用道具 舉報

15#
ID:724791 發表于 2020-4-8 20:23 | 只看該作者
樓主我想知道P2^7這個管腳接的器件是什么
回復

使用道具 舉報

16#
ID:724791 發表于 2020-4-8 22:01 | 只看該作者
您好,我想請問一下,示波器跟繼電器是怎么調配的
回復

使用道具 舉報

17#
ID:470525 發表于 2021-5-28 08:41 | 只看該作者
duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2);  //+Kd*(e-2e1+e2)這公式錯了吧
回復

使用道具 舉報

18#
ID:385637 發表于 2021-9-9 10:36 | 只看該作者
121385936 發表于 2021-5-28 08:41
duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2);  //+Kd*(e-2e1+e2)這公式錯了吧

PID=Uk+KP*【E(k)-E(k-1)】+KI*E(k)+KD*【E(k)-2E(k-1)+E(k-2)】 公式沒錯哦
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99爱免费| 国产美女自拍视频 | av黄色免费 | 99国产欧美| 欧美黑人一区二区三区 | 午夜99| 99视频在线播放 | 日韩精品视频一区二区三区 | 久久久久久成人 | 黄色成人在线 | 亚洲一区中文字幕在线观看 | 成人国产精品久久久 | 国产精品3区 | 国产一区二区在线视频 | 欧美aaa级 | 欧美日韩精品一区二区三区四区 | 最新高清无码专区 | 免费成人在线网 | 国产成人免费 | 精品美女久久久 | 免费av一区二区三区 | 国产精品欧美一区二区三区不卡 | 国产在线看片 | 国产精品乱码一二三区的特点 | 午夜www | 欧美日韩a| 国产一区影院 | 精品国产18久久久久久二百 | 亚洲精品一区二区网址 | 国产1区| 99re6在线视频精品免费 | 91免费在线看 | 欧美日韩精品一区二区三区四区 | 亚洲午夜视频在线观看 | 色资源在线观看 | 亚洲视频一区 | 天天干夜夜| 久草色视频 | 噜久寡妇噜噜久久寡妇 | 国产综合精品一区二区三区 | 国产精品区一区二区三区 |