找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機溫度控制程序+仿真(按鍵設置上中下限)

  [復制鏈接]
跳轉到指定樓層
樓主
ID:264959 發(fā)表于 2018-12-16 15:09 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
1.可按鍵設置上中下限
2.有聲光報警
3.有風扇

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>

  3. #include <math.h>
  4. #include "main.h"


  5.   char code LED_display[14] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0XFF,0x89,0XC7};  //共陽數碼管段碼
  6.                              // 0     1    2   3     4    5    6     7   8    9    -                    H    L
  7.   char code bit_sel[4] = {0x01,0x02,0x04,0x08};
  8.   char dis[4];
  9.                                                                  


  10. unsigned char TL0_temp;         /*暫存TL0的初值*/
  11. unsigned char TH0_temp;         /*暫存TH0的初值*/
  12. #define INT_CLOCK 5 /*INT_CLOCK為定時值,單位為ms ,此處定義為5ms*/
  13. #define CRY_FREQUENCY 12000000 /*CRY_FREQUENCY為晶振頻率,單位為Hz*/

  14. bit flag = 0; //0-正溫度  1-負溫度
  15. sbit key1 = P3^2;  //設置按鍵
  16. sbit key2 = P3^3;  //增量按鍵
  17. sbit key3 = P3^4;  //減量按鍵

  18. bit bKey1,bKey2,bKey3;
  19. uchar countSet = 0;


  20. sbit ledRed = P1^0;             //紅燈
  21. sbit ledYellow = P1^1;         //黃燈
  22. sbit ledGreen = P1^2;         //綠燈

  23. sbit fan = P1^6;  //風扇
  24. sbit beep = P1^5; //蜂鳴器



  25. char shutDowmH = 85; //關機溫度
  26. char SetH = 65;          //高溫上限
  27. char SetL = 30;          //低溫下限

  28. char alarm = 0;
  29. sbit DQ=P3^6;           /* 18B20數據引腳*/


  30. #define temp_h P3|=0x40//單片機向DS18B20輸出高電平
  31. #define temp_l P3&=0xbf//單片機向DS18B20輸出低電平





  32. void delay(uint z)
  33. {
  34.         uint x,y;
  35.         for(x=z;x>0;x--)
  36.                 for(y=110;y>0;y--);
  37. }



  38. void Timer0_init()
  39. {
  40.         unsigned long T0_temp;                                     /*暫存T0的初始值        */
  41.         T0_temp = 65536-((INT_CLOCK *CRY_FREQUENCY /1000)/12);    /*T0初始值計算公式,參考教科書*/
  42.         TL0_temp = T0_temp & 0xff;
  43.         TH0_temp = T0_temp >> 8;
  44.         TL0 = TL0_temp;
  45.         TH0 = TH0_temp;
  46.         TMOD |= 0x01;
  47.         TR0 = 1;  
  48.         ET0 = 1;   
  49.         EA = 1;                                               /*開定時器0中斷*/

  50. }

  51. void INT0_Init()
  52. {
  53.         EX0 = 1;
  54.         IT0 = 1;
  55. }

  56. void delay1ms(unsigned int ms)//延時1毫秒(不夠精確的)
  57. {
  58.         unsigned int i,j;
  59.    for(i=0;i<ms;i++)
  60.     for(j=0;j<100;j++);
  61. }


  62. void keyScan()
  63. {
  64.   
  65.    if(!key2)
  66.    {
  67.      delay1ms(300);
  68.          if(!key2)
  69.            bKey2 = 1;
  70.    }
  71.    if(!key3)
  72.    {
  73.      delay1ms(300);
  74.          if(!key3)
  75.            bKey3 = 1;
  76.    }
  77. }






  78. //數碼管顯示溫度值

  79. void displayTemp(uint temp)
  80. {
  81.         uchar i;

  82.            if(countSet == 0) //顯示實際的測試溫度
  83.         {
  84.         if(flag == 1)  //負溫度
  85.         {
  86.             
  87.                 dis[0] = 11;
  88.                 dis[1] = 10;
  89.                 dis[2] = temp/100;
  90.                 dis[3] = temp%100/10;
  91.         }
  92.         else //正溫度
  93.         {
  94.          
  95.            dis[0] = 11;
  96.            dis[1] = temp/1000;
  97.            dis[2] = temp%1000/100;
  98.            dis[3] = temp%1000%100/10;

  99.         }
  100.         }
  101.         else if(countSet == 1) //顯示設置的溫度下限
  102.         {
  103.             dis[0] = 1;  //顯示'1'
  104.                
  105.                 dis[1] = 10;
  106.                 dis[2] = SetL/10;
  107.                 dis[3] = SetL%10;
  108.          
  109.            
  110.         }
  111.         else if(countSet == 2) //顯示設置的溫度上限
  112.         {
  113.            dis[0] = 2;  //顯示'2'
  114.                
  115.                 dis[1] = 10;
  116.                 dis[2] = SetH/10;
  117.                 dis[3] = SetH%10;
  118.         }
  119.         else if(countSet == 3) //顯示設置的關機溫度
  120.         {
  121.             dis[0] = 3;  //顯示'3'
  122.                
  123.                 dis[1] = 10;
  124.                 dis[2] = shutDowmH/10;
  125.                 dis[3] = shutDowmH%10;
  126.         }

  127. }







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

  129. void delayms(uint x)//延時1ms
  130. {
  131.         uint y,z;
  132.         for(y=x;y>0;y--)
  133.                 for(z=110;z>0;z--);
  134. }

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

  136. void Ds18b20_reset()//DS18B20初始化
  137. {
  138.         uchar count;
  139.         uint i=2200;
  140.         temp_l;
  141.         for(count=240;count>0;count--);//延時480us
  142.         temp_h;
  143.         while(DQ&&(i>0)) i--;
  144.         for(count=240;count>0;count--);//延時480us
  145. }

  146. /***********ds18b20讀一個字節(jié)**************/  

  147. uchar Ds18b20_read()//從DS18B20讀一個字節(jié)
  148. {
  149.         uchar i,count,dat;
  150.         for(i=8;i>0;i--)
  151.         {
  152.                 dat>>=1;
  153.                 temp_l;
  154.                 for(count=1;count>0;count--);
  155.                 temp_h;//此語句必須有,參考datasheet的P15
  156.                 for(count=1;count>0;count--);
  157.                 if(DQ)
  158.                         dat|=0x80;
  159.                 for(count=30;count>0;count--);        
  160.         }
  161.         return dat;
  162. }

  163. /*************ds18b20寫一個字節(jié)****************/  

  164. void Ds18b20_write(uchar dat)//向DS18B20寫一個字節(jié)
  165. {
  166.         uchar count;
  167.         uchar i;
  168.         for(i=8;i>0;i--)
  169.         {
  170.                 temp_l;
  171.                 for(count=1;count>0;count--);
  172.                
  173.                 if(dat&0x01==0x01)
  174.                         temp_h;
  175.                 else
  176.                         temp_l;
  177.                 for(count=30;count>0;count--);
  178.                 temp_h;
  179.                 dat>>=1;        
  180.         }        
  181. }
  182. /**************讀取ds18b20當前溫度************/
  183. uint ReadTemperature(void)
  184. {
  185.         uint dat;
  186.             uchar dat1,dat2;//保存讀出的溫度
  187.                 Ds18b20_reset();
  188.                 Ds18b20_write(0xcc);
  189.                 Ds18b20_write(0x44);//發(fā)送溫度轉換命令
  190.                 delayms(1000);//延時1s,等待溫度轉換完成
  191.                 Ds18b20_reset();
  192.                 Ds18b20_write(0xcc);
  193.                 Ds18b20_write(0xbe);//發(fā)送讀溫度寄存器命令
  194.                 dat1=Ds18b20_read();
  195.                 dat2=Ds18b20_read();
  196.             if(dat2 >= 240)         //負溫度
  197.                 {
  198.                                 dat=(~(dat2*256+dat1)+1)*(0.0625*10);
  199.                                 flag = 1;
  200.             }
  201.                 else  //正溫度
  202.                 {
  203.                       flag = 0;
  204.                           dat=(dat2*256+dat1)*(0.0625*10);
  205.                 }
  206.                 return dat;
  207. }

  208. void main()
  209. {

  210.         
  211.          uint temp;
  212.           Timer0_init();  //定時器0初始化
  213.           INT0_Init();

  214.           EA = 1;           //開總中斷
  215.           fan = 0;
  216.           countSet = 0;        
  217.         while(1)
  218.         {
  219.             if(countSet == 0)
  220.                 temp =         ReadTemperature();  //采集DS18B20的溫度值
  221.                 if(flag == 1)  //負溫度
  222.                 {
  223.                       ledYellow = 0;   //黃燈亮
  224.                           ledRed = 1;
  225.                           ledGreen = 1;
  226.                           displayTemp(temp); //顯示溫度
  227.                           fan = 0;//風扇關閉
  228.                           alarm = 0;
  229.                 }
  230.                 else
  231.                 {
  232.                      if(temp/10 > shutDowmH)
  233.                          {
  234.                               dis[0] = 11;
  235.                       dis[1] = 11;
  236.                       dis[2] = 11;
  237.                       dis[3] = 11; //數碼管熄滅
  238.                                   ledYellow = 1;   //燈全熄滅
  239.                               ledRed = 1;
  240.                               ledGreen = 1;
  241.                                   fan = 0; //風扇停轉
  242.                                   alarm = 0;
  243.                          }
  244.                          else if(temp/10 > SetH)
  245.                          {
  246.                             displayTemp(temp); //顯示溫度
  247.                                 ledYellow = 1;   //指示燈變紅
  248.                               ledRed = 0;
  249.                               ledGreen = 1;
  250.                                    fan = 1; //風扇開啟
  251.                                         alarm = 1;
  252.                          }
  253.                          else if(temp/10 > SetL)
  254.                          {
  255.                             displayTemp(temp); //顯示溫度 或者設置
  256.                                 ledYellow = 1;   //指示燈變綠
  257.                               ledRed = 1;
  258.                               ledGreen = 0;
  259.                                    fan = 1; //風扇開啟
  260.                                  alarm = 0;
  261.                          }
  262.                          else
  263.                          {
  264.                             displayTemp(temp); //顯示溫度
  265.                                 ledYellow = 0;   //指示燈變黃
  266.                               ledRed = 1;
  267.                               ledGreen = 1;
  268.                                    fan = 0; //風扇關閉
  269.                                    alarm = 0;
  270.                          }               
  271.                 }


  272.                 keyScan();
  273.                 if(bKey2)  //溫度加
  274.                 {
  275.                   bKey2 = 0;
  276.                   if(countSet == 1)         //設置低溫
  277.                   {
  278.                       if(SetL < SetH)
  279.                             SetL++;
  280.                   }
  281.                   if(countSet == 2)          //設置高溫
  282.                   {
  283.                       if(SetH < shutDowmH)
  284.                             SetH++;
  285.                   }
  286.                   if(countSet == 3)          //設置關機溫度
  287.                   {
  288.                       if(shutDowmH < 99)
  289.                             shutDowmH++;
  290.                   }
  291.                 }
  292.                 if(bKey3)        //溫度減
  293.                 {
  294.                   bKey3 = 0;
  295.                   if(countSet == 1)          //設置低溫
  296.                   {
  297.                       if(SetL > 0)
  298.                             SetL--;
  299.                   }
  300.                   if(countSet == 2)          //設置高溫
  301.                   {
  302.                       if(SetH > SetL)
  303.                             SetH--;
  304.                   }
  305.                   if(countSet == 3)         //設置關機溫度
  306.                   {
  307.                       if(shutDowmH > SetH)
  308.                             shutDowmH--;
  309.                   }
  310.                 }

  311.         }           
  312. }




  313. unsigned char count_5ms = 0;
  314. unsigned int count_5s = 0;

  315. void T0_interrupt(void) interrupt 1         
  316. {
  317.         TH0 += TH0_temp;
  318.         TL0 += TL0_temp;
  319.         
  320.         count_5ms++;
  321.         if(count_5ms >= 4)
  322.            count_5ms = 0;

  323.     P2 = 0X00;
  324.         P0 = LED_display[dis[count_5ms]];
  325.         P2 = bit_sel[count_5ms];

  326.         if(alarm == 1)
  327.         {
  328.            
  329.            if(count_5s < 1000)
  330.            {
  331.               count_5s++;
  332.                   beep = !beep;
  333.            }   
  334.         }
  335.         else
  336.           count_5s = 0;
  337. }

  338. /*
  339.   外部中斷0服務處理函數,記錄“設置”按鍵按下的次數
  340. */

  341. void int_int0() interrupt 0
  342. {
  343.         countSet++;
  344.         if(countSet > 3)
  345.           countSet = 0;
  346. }
復制代碼

所有資料51hei提供下載:
CPU溫度控制(1).zip (103.31 KB, 下載次數: 307)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

來自 2#
ID:668055 發(fā)表于 2020-5-30 18:11 | 只看該作者
你好 請問void Ds18b20_reset()//DS18B20初始化
{
        uchar count;
        uint i=2200;
        temp_l;
        for(count=240;count>0;count--);//延時480us
        temp_h;
        while(DQ&&(i>0)) i--;
        for(count=240;count>0;count--);//延時480us
temp_h和temp_l是代表了拉高總線和拉低總線嗎?為何延時不用上邊剛定義的函數,要用count呢?
回復

使用道具 舉報

板凳
ID:437339 發(fā)表于 2018-12-26 15:27 | 只看該作者
你好。我是新手,dis[1]=11,為什么數碼管熄滅啊
回復

使用道具 舉報

地板
ID:239620 發(fā)表于 2019-2-23 10:26 | 只看該作者
謝謝分享,學習學習!
回復

使用道具 舉報

5#
ID:468833 發(fā)表于 2019-4-12 10:20 | 只看該作者
謝謝分享
回復

使用道具 舉報

6#
ID:524279 發(fā)表于 2019-4-29 10:51 來自手機 | 只看該作者
樓主發(fā)全程序啊
回復

使用道具 舉報

7#
ID:409381 發(fā)表于 2019-4-29 12:28 | 只看該作者
謝謝分享樓主大作
回復

使用道具 舉報

8#
ID:208733 發(fā)表于 2020-2-2 18:47 | 只看該作者
謝謝分享
回復

使用道具 舉報

9#
ID:404346 發(fā)表于 2020-3-29 10:38 | 只看該作者
謝謝分享
回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表