<li id="8g3ty"><tbody id="8g3ty"><th id="8g3ty"></th></tbody></li>
    <label id="8g3ty"><samp id="8g3ty"></samp></label>
  • <span id="8g3ty"></span>

    1. <center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
    2. <bdo id="8g3ty"><meter id="8g3ty"><bdo id="8g3ty"></bdo></meter></bdo><center id="8g3ty"><optgroup id="8g3ty"></optgroup></center>
      <label id="8g3ty"><samp id="8g3ty"></samp></label>

    3. 電子開發網

      電子開發網電子設計 | 電子開發網Rss 2.0 會員中心 會員注冊
      搜索: 您現在的位置: 電子開發網 >> 電子開發 >> 單片機 >> 正文

      基于51單片機的恒溫控制器系統 protues+keil c

      作者:佚名    文章來源:網友    點擊數:    更新時間:2023/5/21

      恒溫控制器系統概述

      該恒溫控制器系統包含以下幾個功能:

      • 可按鍵設定溫度
      • 可顯示當前溫度和用戶設定溫度
      • 有升溫、降溫模塊
      • 可最終達到恒溫

      仿真軟件

      • Keil 5
      • Proteus 8.6

      系統設計

      電路設計

       
      恒溫控制系統一共有6個模塊,分別是主控芯片模塊、按鍵輸入模塊、設定溫度顯示模塊、當前溫度顯示模塊、溫度采集模塊和升溫、降溫模塊。

      1. 按鍵輸入模塊:該模塊由4*3的矩陣鍵盤和1個確認按鈕構成。系統剛開始啟動后,用戶通過矩陣鍵盤輸入想要設定的溫度(0°~99°),輸入完畢后按下確認鍵,然后將該溫度數據傳送給主控芯片AT89C51;
      2. 設定溫度顯示模塊:該模塊由一個2位8段LED數碼管構成,主控芯片AT89C51使用P3口控制該數碼管的段選,使用P2.4和P2.5兩個端口來控制該數碼管的位選。主控芯片AT89C51將從矩陣鍵盤得到的設定溫度信息,通過2位8段LED數碼管顯示出來;
      3. 溫度采集模塊;該模塊由一個DS18B20溫度傳感器構成。使用DS18B20溫度傳感器采集當前的溫度,并將該溫度信息傳送給主控芯片AT89C51;
      4. 當前溫度顯示模塊:該模塊由兩個74HC573鎖存器和一個4位8段LED數碼管構成,主控芯片AT89C51使用P2.6和P2.7控制兩個74HC573鎖存器的片選,兩個鎖存器的輸入口均與主控芯片的P0口相連,并使用一個100歐的排阻作為P0口的上拉電阻,兩個鎖存器的輸出口分別與4位8段LED數碼管的段選口與位選口相連;
      5. 升溫、降溫模塊:該模塊由一個綠色LED和一個紅色LED構成,綠色LED負責降溫,每閃爍一次溫度下降0.5°,紅色LED負責升溫,每閃爍一次溫度上升0.5°。主控芯片AT89C51根據當前溫度和用戶設定溫度之間的差值,來控制升溫還是降溫,以達到恒溫的目的。

      軟件代碼編寫

       

      51單片機恒溫控制系統程序流程圖  

      程序的具體流程如下:

      1. 硬件初始化,關閉所有的數碼管;
      2. 進行兩次按鍵掃描循環,分別獲取用戶設定溫度的十位和個位,獲取完畢后,判斷確認鍵是否被按下,如果用戶按下確認鍵則進入到主程序循環中;
       while(ok) //用戶設定溫度
       {
        while(key1 == 15)
        {
         key1 = keyscan();
         delay(50);
        }
        while(key2 == 15)
        {
         key2 = keyscan();
         delay(50);
        }
        delay(100);//等待確認鍵
       }
      //鍵盤掃描
      uchar keyscan()
      {
       uchar temp,key;
       key = 15; // 默認值,如果沒有按鍵按下key就為該默認值
       P1 = 0xfe; //掃描第一行
       temp = P1;
       temp = temp & 0xf0;
       if(temp!=0xf0)
       {
        delay(10); // 延時消抖
        temp = P1;
        temp = temp & 0xf0;
        if(temp!=0xf0) 
        {
         temp = P1;
         switch(temp) //掃描列
         {
          case 0xee:
           key = 1;
           break;
          case 0xde:
           key = 2;
           break;
          case 0xbe:
           key = 3;
           break;
         }
         while(temp!=0xf0) //等待按鍵釋放
         {
          temp = P1;
          temp = temp & 0xf0;
         }
        }
       }
       P1 = 0xfd; //掃描第二行
       temp = P1;
       temp = temp & 0xf0;
       if(temp!=0xf0)
       {
        delay(10); // 延時消抖
        temp = P1;
        temp = temp & 0xf0;
        if(temp!=0xf0)
        {
         temp = P1;
         switch(temp) //掃描列
         {
          case 0xed:
           key = 4;
           break;
          case 0xdd:
           key = 5;
           break;
          case 0xbd:
           key = 6;
           break;
         }
         while(temp!=0xf0) //等待按鍵釋放
         {
          temp = P1;
          temp = temp & 0xf0;
         }
        }
       }
       P1 = 0xfb; //掃描第三行
       temp = P1;
       temp = temp & 0xf0;
       if(temp!=0xf0)
       {
        delay(10); // 延時消抖
        temp = P1;
        temp = temp & 0xf0;
        if(temp!=0xf0)
        {
         temp = P1;
         switch(temp) //掃描列
         {
          case 0xeb:
           key = 7;
           break;
          case 0xdb:
           key = 8;
           break;
          case 0xbb:
           key = 9;
           break;
         }
         while(temp!=0xf0) //等待按鍵釋放
         {
          temp = P1;
          temp = temp & 0xf0;
         }
        }
       }
       P1 = 0xf7; //掃描第四行
       temp = P1;
       temp = temp & 0xf0;
       if(temp!=0xf0)
       {
        delay(10); // 延時消抖
        temp = P1;
        temp = temp & 0xf0;
        if(temp!=0xf0)
        {
         temp = P1;
         switch(temp) //掃描列
         {
          case 0xe7:
           key = 0;
           break;
          case 0xd7:
           key = 0;
           break;
          case 0xb7:
           key = 0;
           break;
         }
         while(temp!=0xf0) //等待按鍵釋放
         {
          temp = P1;
          temp = temp & 0xf0;
         }
        }
       }
       return key;
      }
      1. 在主程序循環中,首先調用dis_set()函數顯示用戶設定溫度;
      for(i=20;i>0;i--) 
       dis_set(key1, key2); //顯示用戶設定的溫度
      //顯示設定溫度函數
      void dis_set(uchar k1, uchar k2)
      {
        display2(1, k1);
        display2(2, k2);
        display2(0, k1);
      }
      //設定溫度數據顯示函數
      void display2(uchar num, uchar tem_data)
      {
       if(num==0)
       {
        S1 = 1;
        S2 = 1;
        delay(5);
       }
       if(num==1)
       {
        S1 = 0;
        S2 = 1;
        P3 = table[tem_data]; //table為 0-9的16進制編碼表
        delay(5);
       }
       else if(num==2)
       {
        S1 = 1;
        S2 = 0;
        P3 = table[tem_data];
        delay(5);
       }
      }

      然后再從溫度傳感器獲取當前溫度,獲取當前溫度的流程如下圖所示,先調用DSreset()函數進行溫度傳感器的初始化,再調用temwrite()函數,對傳感器寫入溫度轉換的指令,進行溫度獲取和轉換,然后調用get_tem()函數對傳感器寫入讀取寄存器指令,從寄存器中讀取存儲的溫度數據,并對該數據進行精度轉換處理,最后獲得一個保留了1位小數的當前溫度數據;

       

      temchange();    //獲取當前溫度
      //溫度獲取和轉換函數
      void temchange(void)
      {
       DSreset();
       delay(1);
       temwrite(0xcc); //寫跳過ROM指令
       temwrite(0x44); //寫溫度轉換指令
      } 
      //讀取寄存器中存儲的溫度數據
      uint get_tem(void)
      {
       uchar l8,h8;
       DSreset();
       delay(1);
       temwrite(0xcc); //寫跳過ROM指令
       temwrite(0xbe); //寫讀寄存器指令
       l8 = temread(); //讀低8位數據
       h8 = temread(); //讀高8位數據
       tem = h8;
       tem = tem<<8;
       tem = tem|l8; //合成一個16位數據
       f_tem = tem*0.0625;
       tem = f_tem*10+0.5; //*10用于保留1位小數點,+0.5用于四舍五入
       return (tem);
      }

      DS18B20溫度傳感器的基本操作代碼如下,各項操作要嚴格遵守DS18B20溫度傳感器的時序圖,延時時間要足夠,可以根據使用的主控芯片適當地修改循環的次數來調整延時。

      初始化

      //溫度傳感器初始化
      uint DSreset(void)
      {
       uint i;
       DS = 0;
       i = 73;
       while(i>0)
        i--;
       DS = 1;
       i = 0;
       while(DS) 
       {//等待DS18B20拉低總線
        delay(1);
        i++;
        if(i>10)
        {
         return 0;//初始化失敗
        }
       }
       DS = 1;
       return 1;//初始化成功
      }

      讀1位數據

      //讀1位數據
      bit temreadbit(void)
      {
       uint i;
       bit tem_bitdata;
       DS = 0;
       i++; //延時
       DS = 1;
       i++;
       i++;
       tem_bitdata = DS;
       i = 10;
       while(i>0)
        i--;
       return(tem_bitdata);
      }

      讀1字節數據

      //讀1字節數據
      uchar temread(void)
      {
       uint i;
       uchar j,tem_data;
       for(i=1;i<=8;i++)
       {
        j = temreadbit();
        tem_data = (j<<7)|(tem_data>>1); //移位,讓最低位在最后面
       }
       return (tem_data);
      }

      寫1字節數據

      //寫1字節數據
      void temwrite(uchar tem_data)
      {
       uint i;
       uchar j;
       bit send_bitdata;
       for(j=1;j<=8;j++)
       {
        send_bitdata = tem_data&0x01; //取要發送數據的最低位
        tem_data = tem_data>>1; //右移一位
        if(send_bitdata) //寫1
        {
         DS = 0;
         i++;
         i++;
         DS = 1;
         i = 10;
         while(i>0)
          i--;
        }
        else     //寫0
        {
         DS = 0;
         i = 10;
         while(i>0)
          i--;
         DS = 1;
         i++;
         i++;
        }
       }
      }
      1. 獲取完當前溫度,調用dis_tem()函數顯示當前溫度;
      for(i=20;i>0;i--)  //顯示當前溫度
       dis_tem(get_tem());
      //顯示當前溫度函數
      void dis_tem(uint t)
      {
       uchar i;
       i = t/100; //取溫度的十位
       display1(1,i);
       i = t%100/10; //取溫度的個位
       display1(2,i+10);
       i = t%10; //取溫度的小數點后一位
       display1(3,i);
      }
      //當前溫度數據顯示函數
      void display1(uchar num, uchar tem_data)
      {
       WE = 1; //選位,低電平有效
       P0 = ~((0x01)<<(num));
       WE = 0;
       DU = 1; //選段,高電平有效
       P0 = table[tem_data];
       DU = 0;
       delay(10);
      }
      1. 將當前溫度和用戶設定溫度傳入deal()函數,進行恒溫控制,在恒溫控制函數deal()中,根據判斷當前溫度和用戶設定溫度之間的差值進行不同的處理,如果當前溫度小于用戶設定溫度,就進行升溫處理,即紅燈閃爍一次,每閃爍一次溫度上升0.5°,如果當前溫度大于用戶設定溫度,就進行降溫處理,即綠燈閃爍一次,每閃爍一次溫度下降0.5°,如果當前溫度與用戶設定溫度想等,則不做處理,只顯示溫度;
      void deal(uint t, uint t_set)
      {
       uchar i;
       if(tt_set)
       {
        work(15, 0x40); //降溫
       }
       else
       {
        i = 15;
        while(i--)
         {
          dis_tem(tem_set);
          dis_set(key1, key2);
         }
       }
      }
      //升溫、降溫模塊
      void work(uint s, uchar led)
      {
       uchar i;
       if(led==0x20)
       {
        i = s;
        led0 = ~(led0); //燈亮
        tem = tem+5;
        while(i--)
        {
         dis_tem(tem);
         dis_set(key1, key2);
        }
        led0 = ~(led0); //燈滅
        i = s;
        while(i--)
        {
         dis_tem(tem);
         dis_set(key1, key2);
        }
       }
       else
       {
        i = s;
        led1 = ~(led1); //燈亮
        tem = tem-5;
        while(i--)
        {
         dis_tem(tem);
         dis_set(key1, key2);
        }
        led1 = ~(led1); //燈滅
        i = s;
        while(i--)
        {
         dis_tem(tem);
         dis_set(key1, key2);
        }
       }
      }
      1. 進行一次恒溫控制后,系統又回到主程序循環的起始點,不斷重復上述3-5步驟,使溫度保持在用戶設定的溫度,達到恒溫的效果。

      代碼下載 51單片機恒溫控制系統C語言程序代碼

      Tags:51單片機,恒溫控制,C語言,proteus  
      責任編輯:admin
    4. 上一篇文章:
    5. 下一篇文章: 沒有了
    6. 相關文章列表
      51單片機數碼管顯示程序, 共陰數碼管顯示程序 數碼管原理(顯示
      單片機C語言編程入門教程  流水燈程序示例
      51單片機學習筆記直流電機驅動(PWM)C語言程序
      MCU-51單片機直流電機驅動(PWM)51單片機驅動直流電機
      先學51還是先學STM32?STM32和51單片機的區別
      51單片機和STM32單片機的結構有什么不同
      51單片機、AVR單片機和PIC單片機的IO口操作
      關于51單片機IO引腳的驅動能力與上拉電阻
      51單片機“呼吸燈”程序
      51單片機入門之靜態數碼管電路設計
      穩定可靠的恒溫控制裝置,TWH8751 Temperature controller
      AT89C51,51單片機1602液晶顯示時鐘程序
      單片機電子時鐘程序設計
      4位單片機數字鐘 電子鐘制作
      51單片機4位數碼管電子鐘源程序
      AT89C2051電腦機箱風扇智能溫控儀,AT89C2051 Temperature contro
      51單片機溫控風扇(含程序+原理圖+仿真+PCB)
      89C52來做定時記數器程序,51定時程序
      單片機C語言程序設計:用 ADC0808 控制PWM 輸出
      51單片機蜂鳴器播放音樂代碼
      利用單片機AT89S51與ADC0809設計數字電壓表,Voltmeter
      單片機制作的純正弦波逆變器,12V Pure Sine Wave Inverter
      51單片機00-59秒計時器 0-59s Timer
      51單片機按鍵程序中 while(!key)的作用
      51系列單片機尋址方式
      認識單片機引腳【詳解】
      數碼管顯示矩陣鍵盤掃描值
      用51單片機設計的無線防盜報警器技術
      51單片機產生“嘀、嘀、……”報警聲
      51單片機匯編模擬串口通信程序
      請文明參與討論,禁止漫罵攻擊,不要惡意評論、違禁詞語。 昵稱:
      1分 2分 3分 4分 5分

      還可以輸入 200 個字
      [ 查看全部 ] 網友評論
      關于我們 - 聯系我們 - 廣告服務 - 友情鏈接 - 網站地圖 - 版權聲明 - 在線幫助 - 文章列表
      返回頂部
      刷新頁面
      下到頁底
      晶體管查詢
      主站蜘蛛池模板: 久久综合九色综合97手机观看 | 99久久国产综合精品麻豆| 国产成人精品综合网站| 亚洲熟女综合色一区二区三区| 色综合天天综一个色天天综合网 | 亚洲综合一区国产精品| 一本久久a久久精品综合香蕉| 久久久久久久综合日本| 一本色道久久88加勒比—综合| 丁香婷婷亚洲六月综合色| 人人狠狠综合88综合久久| 色婷五月综激情亚洲综合| 亚洲精品二区国产综合野狼| 国产91色综合久久免费分享| 亚洲综合熟女久久久30p| 天天狠狠色综合图片区| 久久综合综合久久狠狠狠97色88| 婷婷亚洲综合五月天小说在线| 色欲综合一区二区三区| 亚洲香蕉网久久综合影视| 国产天堂一区二区综合| 天天干天天色综合网| 亚洲国产精品成人综合色在线| 国产成人综合日韩精品无码不卡 | 成人综合伊人五月婷久久| 亚洲精品第一国产综合亚AV| 一本色道久久88精品综合| 自拍三级综合影视| 亚洲情综合五月天| 亚州欧州一本综合天堂网| 亚洲狠狠综合久久| 久久精品国产9久久综合| 久久综合亚洲色HEZYO国产| 亚洲狠狠爱综合影院婷婷| 国产成人综合日韩精品无码| 色综合色狠狠天天综合色| 99久久国产综合精品五月天| 天天影视色香欲综合久久| 大香网伊人久久综合观看| 色视频综合无码一区二区三区| 国产亚洲精品第一综合|