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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機溫度PID控制程序有問題 仿真數值不變

[復制鏈接]
跳轉到指定樓層
樓主
電路原理圖如下:


系統元件清單
1.    9*15萬用板
2.    AT89C51
3.    40P IC座
4.    溫度傳感器
5.    語音芯片
6.    104電容
7.    5v喇叭
8.    12M晶振
9.    22uF電容
10.    30P瓷片電容    *2
11.    有源蜂鳴器
12.    103  10k排阻
13.    10k電阻
14.    2.4k電阻
15.    1k電阻*2
16.    紅色Led燈
17.    8550三極管
18.    輕觸按鍵*3
19.    Lcd1602液晶
20.    16p排母
21.    16p插針
22.    自鎖開關
23.    導線若干
24.    焊錫若干
25.    dc插頭
26.    usb供電線



單片機源程序如下:
  1. #include<reg52.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char        //宏定義
  4. #define uint unsigned int
  5. sbit DQ = P3^7;  
  6. sbit k1=P3^2;
  7. sbit k2=P3^3;
  8. sbit k3=P3^4;
  9. sbit k=P3^5;
  10. sbit beep=P2^3;
  11. sbit P10=P1^0;
  12. uchar temp_value,num,t,s1num;                          //溫度值
  13. uchar htemp=33,ltemp=15;                    //溫度上下線初始化
  14. bit yyp=1,lalarm=0,yy=1;
  15. unsigned char TL=0,TH=0,TD=0,TN=0,count;
  16. int key_delay=0;
  17. const int key_count=400;
  18. /***********1602液晶顯示部分子程序****************/
  19. sbit rs=P2^6;//LCD數據/命令選擇端(H/L)
  20. sbit en=P2^7;//LCD使能控制
  21. uchar code table[]={"The temp  system"};//液晶固定顯示部分
  22. uchar code table1[]={" Temp:          "};
  23. uchar code table2[]={" Set the temp:  "};
  24. uchar code table3[]={"H:   C    L:   C"};
  25. /*************************************************/
  26. void delay(uint x) //毫秒級延時函數
  27. {
  28.   uint i,j;
  29.   for(i=x;i>0;i--)
  30.      for(j=110;j>0;j--);
  31. }
  32. void delay1(uchar i)
  33. {
  34.     uchar j=100;
  35.     for(i;i>0;i--)
  36.       for(j;j>0;j--)
  37.         {;}
  38. }
  39. void di()
  40. {
  41.     beep=0;
  42.     delay(100);
  43.     beep=1;
  44. }
  45. void write_com(uchar com)
  46. {
  47.     rs=0;//命令
  48.     P0=com;
  49.     delay(5);
  50.     en=1;
  51.     delay(5);
  52.     en=0;
  53. }
  54. void write_date(uchar date)
  55. {
  56.     rs=1;//數據
  57.     P0=date;
  58.     delay(5);
  59.     en=1;
  60.     delay(5);
  61.     en=0;
  62. }
  63. void init1602()             //上電后液晶顯示初始化函數
  64. {
  65.     write_com(0x38);    //設置工作方式
  66.     write_com(0x0c);    //設置光標
  67.     write_com(0x06);    //設置輸入方式
  68.     write_com(0x01);    //清屏
  69.     write_com(0x80);
  70.     for(num=0;num<16;num++)
  71.     {
  72.         write_date(table[num]);
  73.     }
  74.     write_com(0x80+0x40);
  75.     for(num=0;num<16;num++)
  76.     {
  77.         write_date(table1[num]);
  78.     }
  79. }
  80. void init16021()        //設置溫度上下限顯示初始化函數
  81. {
  82.     write_com(0x80);
  83.     for(num=0;num<16;num++)
  84.     {
  85.         write_date(table2[num]);
  86.     }
  87.     write_com(0x80+0x40);
  88.     for(num=0;num<16;num++)
  89.     {
  90.         write_date(table3[num]);
  91.     }
  92.     write_com(0x80+0x40+4);
  93.     write_date(0xdf);
  94.     write_com(0x80+0x40+14);
  95.     write_date(0xdf);
  96.    
  97. }
  98. /////////////////////////////////
  99. /***********ds18b20子程序*************************/

  100. /***********ds18b20延遲子函數(晶振12MHz )*******/

  101. void delay_18B20(unsigned int i)
  102. {
  103.     while(i--);
  104. }

  105. /**********ds18b20初始化函數**********************/

  106. void Init_DS18B20(void)
  107. {
  108.      unsigned char x=0;
  109.      DQ = 1;                                  //DQ復位
  110.      delay_18B20(8);                          //稍做延時
  111.      DQ = 0;                                  //單片機將DQ拉低
  112.      delay_18B20(80);                         //精確延時 大于 480us
  113.      DQ = 1;                                  //拉高總線
  114.      delay_18B20(14);
  115.      x=DQ;                                    //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  116.      delay_18B20(20);
  117. }

  118. /***********ds18b20讀一個字節**************/  

  119. unsigned char ReadOneChar(void)
  120. {
  121.     uchar i=0;
  122.     uchar dat = 0;
  123.     for (i=8;i>0;i--)
  124.      {
  125.           DQ = 0;                             // 給脈沖信號
  126.           dat>>=1;
  127.           DQ = 1;                             // 給脈沖信號
  128.           if(DQ)
  129.           dat|=0x80;
  130.           delay_18B20(4);
  131.      }
  132.      return(dat);
  133. }

  134. /*************ds18b20寫一個字節****************/  

  135. void WriteOneChar(uchar dat)
  136. {
  137.      unsigned char i=0;
  138.      for (i=8; i>0; i--)
  139.      {
  140.           DQ = 0;
  141.          DQ = dat&0x01;
  142.         delay_18B20(5);
  143.          DQ = 1;
  144.         dat>>=1;
  145. }
  146. }

  147. /**************讀取ds18b20當前溫度************/

  148. void ReadTemp()
  149. {
  150.    

  151.     Init_DS18B20();
  152.     WriteOneChar(0xCC);        // 跳過讀序號列號的操作
  153.     WriteOneChar(0x44);     // 啟動溫度轉換

  154.     delay_18B20(100);       // this message is wery important

  155.     Init_DS18B20();
  156.     WriteOneChar(0xCC);     //跳過讀序號列號的操作
  157.     WriteOneChar(0xBE);     //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度

  158.     TL=ReadOneChar();    //先讀的是溫度值低位
  159.     TH=ReadOneChar();    //接著讀的是溫度值高位
  160.     TN=TH*16+TL/16;         //實際溫度值=(TH*256+TL)/16,即:TH*16+TL/16
  161.                                             //這樣得出的是溫度的整數部分,小數部分被丟棄了
  162.                        
  163.     TD=(TL%16)*10/16;       //計算溫度的小數部分,將余數乘以10再除以16取整,
  164.                                             //這樣得到的是溫度小數部分的第一位數字(保留1位小數)
  165. }
  166. void write_wendu(uchar add,uchar date)
  167. {
  168.     uchar shi,ge;
  169.     shi=date/10;
  170.     ge=date%10;
  171.     write_com(0x80+0x40+add);
  172.     write_date(0x30+shi);
  173.     write_date(0x30+ge);
  174.     write_date('.');          //小數點

  175. }
  176. void write_wendu2(uchar add,uchar date)
  177. {
  178.      write_com(0x80+0x40+add);    //寫顯示地址
  179.     write_date(0x30+date);     //將小數部分的第一位數字字符常量寫入LCD
  180.     write_date(0xdf);
  181.     write_date('C');
  182.     delay(50);          //延時1ms給硬件一點反應時間
  183. }
  184. void write_htemp(uchar add,uchar date)
  185. {
  186.     uchar shi,ge;
  187.     shi=date/10;
  188.     ge=date%10;
  189.     write_com(0x80+0x40+add);
  190.     write_date(0x30+shi);
  191.     write_date(0x30+ge);
  192. }

  193. void write_ltemp(uchar add,uchar date)
  194. {
  195.     uchar shi,ge;
  196.     shi=date/10;
  197.     ge=date%10;
  198.     write_com(0x80+0x40+add);
  199.     write_date(0x30+shi);
  200.     write_date(0x30+ge);   
  201. }
  202. /****按鍵掃描******/
  203. void keyscan()
  204. {
  205.     if(k1==0)
  206.     {
  207.         delay(10);
  208.         if(k1==0)
  209.         {
  210.             s1num++;TR0=1;                              //開定時器0
  211.             while(!k1);            //等待按鍵釋放
  212.             yyp=0;
  213.             di();            
  214.             switch(s1num)
  215.             {
  216.                 case 1:    init16021();                  //設置溫度上下限初始化
  217.                         
  218.                
  219.                         write_htemp(2,htemp);
  220.                         write_ltemp(12,ltemp);
  221.                         write_com(0x80+0x40+3);
  222.                         write_com(0x0f);            //打開光標
  223.                         break;
  224.                 case 2:    write_com(0x80+0x40+13);
  225.                         break;
  226.                 case 3:    s1num=0;
  227.                         write_com(0x0c);            //關閉光標
  228.                         yyp=1;
  229.                         init1602();                    //上電后顯示初始化
  230.                         break;
  231.             }        
  232.         }
  233.     }
  234.     if(s1num!=0)
  235.     {
  236.         if(k2==0)
  237.         {
  238.             delay(10);
  239.             if(k2==0)
  240.             {
  241.                 do
  242.                 {
  243.                 delay1(10);
  244.                     }
  245.                 while((!k2)&(key_delay++<key_count));        //等待按鍵釋放
  246.                 TR0=0;                              //關定時器0
  247.                 di();
  248.                 switch(s1num)
  249.                 {
  250.                     case 1: htemp++;
  251.                             if(htemp==50)htemp=20;
  252.                             write_htemp(2,htemp);
  253.                             write_com(0x80+0x40+3);   
  254.                         
  255.                             break;
  256.                     case 2: ltemp++;
  257.                             if(ltemp==30)ltemp=5;
  258.                             write_ltemp(12,ltemp);
  259.                             write_com(0x80+0x40+13);
  260.                         
  261.                             break;
  262.                 }
  263.             }
  264.         }
  265.         if(k3==0)
  266.         {
  267.             delay(10);
  268.             if(k3==0)
  269.             {
  270.                  do
  271.                 {
  272.                 delay1(10);
  273.                 }
  274.                 while((!k3)&(key_delay++<key_count));    //等待按鍵釋放
  275.                 TR0=0;                              //關定時器0
  276.                 di();
  277.                 switch(s1num)
  278.                 {
  279.                     case 1: htemp--;
  280.                             if(htemp==0)htemp=50;
  281.                             write_htemp(2,htemp);
  282.                             write_com(0x80+0x40+3);
  283.                         
  284.                             break;
  285.                     case 2: ltemp--;
  286.                             if(ltemp==0)ltemp=30;
  287.                             write_ltemp(12,ltemp);
  288.                             write_com(0x80+0x40+13);
  289.                         
  290.                             break;
  291.                 }
  292.             }
  293.         }
  294.     }
  295. }
  296. void baojing()
  297. {
  298.             if((TN>htemp)||(TN<ltemp))        //溫度高于設置最大溫度或低于設置最小溫度
  299.             {
  300.                 lalarm=1;
  301.             }
  302.             else
  303.             {
  304.                 lalarm=0;
  305.             
  306.               
  307.             }
  308.             if(lalarm==1)
  309.             {
  310.                     di();
  311.                     delay(100);
  312.                     di();
  313.                     delay(100);
  314.             }        
  315. }
  316. void  time0()
  317. {
  318.     TMOD=0x01;         //設置定時器0和1工作方式為1(0001 0001)
  319.     TH0=(65536-50000)/256;      //裝定時器初值
  320.     TL0=(65536-50000)%256;
  321.     EA=1;                            //開總中斷
  322.     ET0=1;                              //開定時器0中斷
  323.     TR0=0;                              //關閉定時器0
  324. }

  325. //語音播報程序
  326. sbit MUSIC_REST =P2^2;//語音芯片復位腳                    
  327. sbit MUSIC_DATA =P2^1;//語音芯片脈沖識別
  328. sbit bus =P2^0;       //語音芯片工作狀態識別信號  
  329. uchar bbh,xm1,xm2,xm0;

  330. void delay_us(unsigned int us)
  331. {
  332.     while(us--)
  333.     {
  334.         _nop_();
  335.         _nop_();
  336.         _nop_();
  337.         _nop_();
  338.     }
  339. }
  340. void Music(unsigned char music_count)
  341. {
  342.     MUSIC_REST=1;
  343.     delay_us(200);
  344.     MUSIC_REST=0;
  345.     delay_us(200);

  346.     while(music_count>0)
  347.     {
  348.         MUSIC_DATA=1;
  349.         delay_us(100);
  350.         MUSIC_DATA=0;
  351.         delay_us(100);
  352.         music_count--;
  353.     }
  354. }

  355. void Msc()
  356. {
  357.     if((xm0+xm1+xm2)!=0)           //當超出測量范圍時不進行播報
  358.     {
  359.         Music(21);                    //播報:“溫度”
  360.         while(!bus);
  361.         if(xm0==0)
  362.         {
  363.                   Music(2);             //播報:“十位數具體值”      0
  364.             while(!bus);   
  365.         }               
  366.            else Music(xm0+2);             //播報:“十位數具體值”
  367.         while(!bus);
  368.         Music(12);                //播報:+
  369.         while(!bus);

  370.         if((xm1+xm2)!=0)
  371.         {                  
  372.             Music(xm1+2);                //播報:“十分位的具體值”
  373.             while(!bus);

  374.             Music(14);                    //播報:“點”
  375.             while(!bus);
  376.                                 
  377.             Music(xm2+2);                //播報:“百分位的具體值”
  378.             while(!bus);               
  379.             Music(29);                //播報:“度”
  380.             while(!bus);
  381.         }
  382.         else
  383.         {
  384.             Music(29);                //播報:“度”
  385.             while(!bus);   
  386.         }
  387.     }      
  388. }

  389. void main()
  390. {

  391.     time0();
  392.     init1602();   
  393. P10 = 0;   
  394.             di();
  395.                     delay(100);
  396.     while(1)
  397.     {  
  398.         keyscan();  
  399.           if(yyp==1)
  400.         {
  401.             keyscan();
  402.             ReadTemp();                  //開啟溫度采集程序
  403.             write_wendu(6,TN);          //顯示溫度整數
  404.             write_wendu2(9,TD);          //顯示溫度小數
  405.             baojing();                                //報警函數        
  406.             if(TN<=htemp)
  407.                
  408.                 P10 = 1;
  409.         else
  410.             {
  411.                         Music(23);                //播報:“歡迎”
  412.     while(!bus);
  413.                 P10 = 0;
  414.             }
  415.             xm0=TN /10 ;
  416.             xm1=TN%10;
  417.             xm2=TD;
  418.         }
  419.           while(!k)
  420.           {
  421.               bbh=1;
  422.           }
  423.           if(bbh==1)                    //bb=1調用一次播報程序
  424.            {
  425.                 bbh=0;
  426.                 Msc();
  427.             }                     

  428.     }
  429. }
  430. void timer0() interrupt 1 //定時器0中斷服務程序
  431. {
  432.     TH0=(65536-50000)/256;      //再次裝定時器初值
  433.     TL0=(65536-50000)%256;
  434.     count++;
  435.     if(count>=200)    //20次50毫秒為1秒       5秒
  436.     {
  437.                 count=0;
  438.                 s1num=0;
  439.                 write_com(0x0c);            //關閉光標
  440.                 yyp=1;
  441.                 init1602();                    //上電后顯示初始化
  442.                 TR0=0;                              //關閉定時器0
  443.     }
  444.    
  445.    
  446.    
  447. }
復制代碼

所有資料51hei附件下載:
溫度報警+語音播報.7z (188.75 KB, 下載次數: 11)
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九视频网 | 中文字幕一区二区三区在线视频 | 区一区二区三在线观看 | 亚洲aⅴ精品| 精品国产一二三区 | 欧美成人a∨高清免费观看 91伊人 | 国产精品a久久久久 | 成人av一区二区三区 | 红色av社区| 精品福利在线 | 欧美精品在欧美一区二区少妇 | 在线观看毛片网站 | 日韩精品成人一区二区三区视频 | 欧美一区二区三区高清视频 | 人人叉| 欧美激情五月 | 日韩毛片 | 欧美www在线观看 | 国产一区二区精华 | 国产视频一区二区 | 亚洲在线中文字幕 | 国产成人精品久久 | 亚洲一区二区视频 | 成人精品鲁一区一区二区 | 国产资源在线视频 | 亚洲第1页 | 国产69久久精品成人看动漫 | 免费视频久久久久 | 国产毛片久久久 | 欧美国产中文字幕 | 成人av在线播放 | 韩国毛片视频 | 在线观看国产 | 国产精品激情 | 日韩中文字幕视频在线 | 久久久女女女女999久久 | 一区二区三区在线播放 | 国产精品久久久久久久久久久久午夜片 | 在线一区视频 | 亚洲福利片 | 韩日在线观看视频 |