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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8721|回復: 1
收起左側

基于單片機的智能溫度監測系統設計(電路圖+程序)

[復制鏈接]
ID:983884 發表于 2021-11-23 20:51 | 顯示全部樓層 |閱讀模式

本次設計的主要思路是利用51系列單片機,數字溫度傳感器DS18B20和1602LCD液晶顯示,構成實現溫度檢測與顯示的單片機控制系統,即數字溫度計。通過對單片機編寫相應的程序,達到能夠實時檢測周圍溫度的目的。 通過對本課題的設計能夠熟悉數字溫度計的工作原理及過程,了解各功能器件(單片機、DS18B20、LCD)的基本原理與應用,掌握各部分電路的硬件連線與程序編寫,最終完成對數字溫度計的總體設計。其具體的要求如下: 1、根據設計要求,選用AT89C51單片機為核心器件; 2、溫度檢測器件采用DS18B20數字式溫度傳感器,利用單總線式連接方式與單片機的串行接口P3.3引腳相連; 3、顯示電路采用1602LCD液晶顯示溫度值,此類液晶模塊不僅可以顯示數字、字符,還可以顯示各種圖形符號以及少量自定義符號,人機界面友好,使用操作也更加靈活、方便,使其日益成為各種儀器儀表等設備的首選。

系統的開發過程

本設計主要介紹了用單片機和數字溫度傳感器DS18B20相結合的方法來實現溫度的采集,以單片機AT89C51芯片為核心,溫度傳感器DS18B20和1602LCD液晶顯示,構成了一個多功能單片機數字溫度計。其主要研究內容包括兩方面,一是對系統硬件部分的設計,包括溫度采集電路和顯示電路;二是對系統軟件部分的設計,應用C語言實現溫度的采集與顯示。通過利用數字溫度傳感器DS18B20進行設計,能夠滿足實時檢測溫度的要求,同時通過1602LCD的顯示功能,可以實現不間斷的溫度顯示。其總體設計框圖一如下:


1.png

圖一:總體設計框圖

第一節AT89C51簡介

AT89C51是美國ATMEL公司生產的低功耗,高性能CMOS8位單片機,片內含4kbytes的可編程的Flash只讀程序存儲器,兼容標準8051指令系統及引腳,并集成了 Flash 程序存儲器,既可在線編程(ISP),也可用傳統方法進行編程,因此,低價位AT89C51單片機可應用于許多高性價比的場合,可靈活應用于各種控制領域,對于簡單的測溫系統已經足夠。單片機AT89C51具有低電壓供電和體積小等特點,四個端口只需要兩個口就能滿足電路系統的設計需要,很適合便攜手持式產品的設計使用系統可用二節電池供電。芯片AT89C51的引腳排列如圖二所示:


2.png

圖二:AT89C51單片機引腳圖

第二節晶振電路的設計

單片機晶振電路的設計如圖三所示。XTAL1(X1)為反向振蕩放大器的輸入及內部時鐘工作電路的輸入。按照理論上AT89C51使用的是12MHz的晶振,但實測使用11.0592MHz。所以設計者通常用的是11.0592MHz。


3.png

圖三:單片機晶振電路

第三節溫度采集電路的設計

DALLAS 最新單線數字溫度傳感器DS18B20是一種新型的“一線器件”,其體積更小、更適用于多種場合、且適用電壓更寬、更經濟。DALLAS 半導體公司的數字化溫度傳感器DS18B20是世界上第一片支持“一線總線”接口的溫度傳感器。溫度測量范圍為-55~+125 攝氏度,可編程為9~12 位轉換精度,測溫分辨率可達0.0625攝氏度,分辨率設定參數以及用戶設定的報警溫度存儲在EEPROM 中,掉電后依然保存。被測溫度用符號擴展的16位數字量方式串行輸出;其工作電源既可以在遠端引入,也可以采用寄生電源方式產生;多個DS18B20可以并聯到3 根或2 根線上,CPU只需一根端口線就能與諸多DS18B20 通信,占用微處理器的端口較少,可節省大量的引線和邏輯電路。因此用它來組成一個測溫系統,具有線路簡單,在一根通信線,可以掛很多這樣的數字溫度計,十分方便。本設計的溫度采集電路如圖四所示。


4.png

圖四:溫度采集電路圖

第五節溫度顯示電路的設計

顯示器常用作單片機最簡單的輸出設備,用以顯示單片機的運行結果和運行狀態等。常用的顯示器主要有LED和LCD,它們都具有耗電少、成本低、線路簡單、壽命長等優點,廣泛應用于單片機顯示數字量的場合。設計中采用LCD顯示器。液晶顯示器(LCD)具有功耗低、體積小、質量輕、功耗小的特點。點陣字符型液晶顯示器把LCD控制器、點陣驅動器、字符存儲器集成在一塊印刷電路板上,構成便于應用的液晶模塊。此類液晶模塊不僅可以顯示數字、字符,還可以顯示各種圖形符號以及少量自定義符號,并且可以實現屏幕的上下左右滾動、文字的閃爍等功能,人機界面友好,使用操作也更加靈活、方便,使其日益成為各種儀器儀表等設備的首選。圖五為本設計的顯示電路圖。

5.png


圖五:顯示電路圖

第六節應用軟件介紹

本設計主要用Proteus仿真軟件和Keil編譯軟件。

本設計主要用Proteus仿真軟件和Keil編譯軟件 4.1.1 Proteus的介紹

Proteus軟件是英國Labcenter electronics公司出版的EDA工具軟件。它不僅具有其它EDA工具軟件的仿真功能,還能仿真單片機及外圍器件,它是目前最好的仿真單片機及外圍器件的工具,雖然目前國內推廣剛起步,但已受到單片機愛好者、從事單片機教學教師、致力于單片機開發應用的科技工作者的青睞。Proteus是世界上著名的EDA工具(仿真軟件),從原理布圖、代碼調試到單片機與外圍電路協同仿真,一鍵切換發到PCB設計,真正實現了從 概念到產品的完整設計。是目前世界上唯一將電路仿真軟件、PCB設計軟件和虛擬模型仿真軟件三合一的設計平臺,其處理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086HE MSP430等,2010年即將增加Cortex和DSP系列處理器,并持續增加其他系列處理器模型。在編譯方面,它也支持IAR、Keil和MPLAB等多種編譯器。

Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟件開發系統,與匯編相比,C語言在功能上、結構性、可讀性、可維護性上有明顯的優勢,因而易學易用。Keil提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調試器等在內的完整開發方案,通過一個集成開發環境(uVision)將這些部分組合在一起。運行Keil軟件需要WIN98、NT、WIN2000、WINXP等操作系統。如果你使用C語言編程,那么Keil幾乎就是你的不二之選,即使不使用C語言而僅用匯編語言編程,其方便易用的集成環境、強大的軟件仿真調試工具也會令你事半功倍。

系統測試情況

進入測試,開關不閉合,系統默認顯示1602LCD顯示當前采集的溫度,當溫度變化時,系統實時采集DS18B20的溫度并顯示出來,當采集的溫度超過系統所設置的上限或者下限的時候,系統自動報警,開關閉合,顯示報警溫度的上限值和下限值。綜合仿真圖如圖六所示:


6.png

系統的優點與不足

優點:軟件可以實時檢測溫度值,并顯示,當溫度超出預設范圍時及時報警,并且還可以檢測并顯示零下溫度。

缺點:只是做到了仿真程序,沒有具體的硬件實現,系統運行時預設溫度不能改動。




附錄代碼


  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. sbit DQ=P3^3;//DS18B20數據線
  6. sbit BEEP=P3^7;//報警器
  7. sbit LCD_RS=P2^0;
  8. sbit LCD_RW=P2^1;
  9. sbit LCD_EN=P2^2;
  10. sbit K1=P1^7;
  11. uchar code Temp_Disp_Title[]={" Current Temp : "};
  12. uchar Current_Temp_Display_Buffer[]={"TEMP:            "};
  13. uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};
  14. uchar Alarm_HI_LO_STR[]={"Hi:     Lo:      "};
  15. uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//溫度小數位對照表
  16. char Alarm_Temp_HL[2]={100,0};
  17. uchar CurrentT=0;//當前讀取的溫度整數部分
  18. uchar Temp_Value[]={0x00,0x00};//從DS18B20讀取的溫度值
  19. uchar Display_Digit[]={0,0,0,0};//待顯示的各溫度數位
  20. bit HI_Alarm=0,LO_Alarm=0;//高溫低溫報警標志
  21. bit DS18B20_IS_OK=1;//傳感器正常標志
  22. uint Time0_Count=0;//定時器延時累加
  23. //延時
  24. void DelayMS(uint x){
  25.         uchar i;
  26.         while(x--)for(i=0;i<120;i++);
  27. }
  28. //讀LCD狀態
  29. uchar Read_LCD_State(){
  30.         uchar state;
  31.         LCD_RS=0;LCD_RW=1;LCD_EN=1;DelayMS(1);state=P0;LCD_EN=0;DelayMS(1);
  32.         return state;
  33. }
  34. //忙等待
  35. void LCD_Busy_Wait(){
  36.         while((Read_LCD_State()&0x80)==0x80);
  37.         DelayMS(5);
  38. }
  39. //寫LCD指令
  40. void Write_LCD_Command(uchar cmd){
  41.         LCD_Busy_Wait();
  42.         LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd;LCD_EN=1;DelayMS(1);LCD_EN=0;
  43. }
  44. //向LCD寫數據
  45. void Write_LCD_Data(uchar dat){
  46.         LCD_Busy_Wait();
  47.         LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;LCD_EN=1;DelayMS(1);LCD_EN=0;
  48. }
  49. //延時
  50. void DelayXus(int x){
  51.         uchar i;
  52.         while(x--)for(i=0;i<200;i++);
  53. }
  54. //延時
  55. void Delay(uint num){
  56.         while(--num);
  57. }
  58. //初始化DS18B20
  59. uchar Init_DS18B20(){
  60.         uchar status;
  61.         DQ=1;Delay(8);
  62.         DQ=0;Delay(90);
  63.         DQ=1;Delay(8);
  64.         status=DQ;
  65.         Delay(100);
  66.         DQ=1;
  67.         return status;//初始化成功返回0
  68. }
  69. //讀一字節
  70. uchar ReadOneByte(){
  71.         uchar i,dat=0;
  72.         DQ=1;_nop_();
  73.         for(i=0;i<8;i++){
  74.                 DQ=0;dat>>=1;DQ=1;_nop_();_nop_();
  75.                 if(DQ)dat|=0x80;Delay(30);DQ=1;
  76.         }
  77.         return dat;
  78. }
  79. //寫一個字節
  80. void WriteOneByte(uchar dat){
  81.         uchar i;
  82.         for(i=0;i<8;i++){
  83.                 DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;
  84.         }
  85. }
  86. //讀取溫度值
  87. void Read_Temperature(){
  88.         if(Init_DS18B20()==1)//DS18B20故障
  89.                 DS18B20_IS_OK=0;
  90.         else{
  91.                 WriteOneByte(0xcc);//跳過序列號
  92.                 WriteOneByte(0x44);//啟動溫度轉換
  93.                 Init_DS18B20();
  94.                 WriteOneByte(0xcc);//跳過序列號
  95.                 WriteOneByte(0xbe);//讀取溫度寄存器
  96.                 Temp_Value[0]=ReadOneByte();//讀取低8位
  97.                 Temp_Value[1]=ReadOneByte();//溫度高8位
  98.                 Alarm_Temp_HL[0]=ReadOneByte();//報警TH
  99.                 Alarm_Temp_HL[1]=ReadOneByte();//報警TL
  100.                 DS18B20_IS_OK=1;
  101.         }
  102. }        
  103. //設置DS18B20溫度報警值
  104. void Set_Alarm_Temp_Value(){
  105.         Init_DS18B20();
  106.         WriteOneByte(0xcc);//跳過序列號
  107.         WriteOneByte(0x4e);//將設定的溫度報警值寫入DS18B20
  108.         WriteOneByte(Alarm_Temp_HL[0]);//寫TH
  109.         WriteOneByte(Alarm_Temp_HL[1]);//寫TL
  110.         WriteOneByte(0x7f);//12位精度
  111.         Init_DS18B20();
  112.         WriteOneByte(0xcc);//跳過序列號
  113.         WriteOneByte(0x48);//將設定的溫度報警值寫入DS18B20
  114. }
  115. //設置液晶顯示位置
  116. void Set_LCD_POS(uchar p){
  117.         Write_LCD_Command(p|0x80);
  118. }
  119. //在LCD上顯示當前溫度
  120. void Display_Temperature(){
  121.         uchar i;
  122.         uchar t=150;//延時值
  123.         uchar ng=0;//負數標志
  124.         char Signed_Current_Temp;//如果為負數則取反加1,并設置負數標識
  125.         if((Temp_Value[1]&0xf8)==0xf8){
  126.                 Temp_Value[1]=~Temp_Value[1];
  127.                 Temp_Value[0]=~Temp_Value[0]+1;
  128.                 if(Temp_Value[0]==0x00)Temp_Value[1]++;
  129.                 ng=1;//設負數標識
  130.         }
  131. //查表得到溫度小數部分
  132.         Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];
  133. //獲取溫度整數部分(無符號)
  134.         CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);
  135. //有符號的當前溫度值,注意此處定義為char,其值可為-128~+127
  136.         Signed_Current_Temp=ng?-CurrentT:CurrentT;
  137. //高低溫報警標志設置(與定義為char類型的Alarm_Temp_HL比較,這樣可區分正負比較)
  138.         HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;
  139.         LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;
  140. //將整數部分分解為三位待顯示數字
  141.         Display_Digit[3]=CurrentT/100;
  142.         Display_Digit[2]=CurrentT%100/10;
  143.         Display_Digit[1]=CurrentT%10;
  144. //刷新LCD顯示緩沖
  145.         Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';
  146.         Current_Temp_Display_Buffer[10]='.';
  147.         Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';
  148.         Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';
  149.         Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0';
  150. //高位為0時不顯示
  151.         if(Display_Digit[3]==0)Current_Temp_Display_Buffer[7]=' ';
  152. //高位為0且次高位為0時,次高位不顯示
  153.         if(Display_Digit[2]==0&&Display_Digit[3]==0)
  154.                 Current_Temp_Display_Buffer[8]=' ';
  155.         //負數符號顯示在恰當位置
  156.         if(ng)
  157.         {
  158.                 if(Current_Temp_Display_Buffer[8]==' ')
  159.                         Current_Temp_Display_Buffer[8]='-';
  160.                 else if(Current_Temp_Display_Buffer[7]==' ')
  161.                         Current_Temp_Display_Buffer[7]='-';
  162.                 else Current_Temp_Display_Buffer[6]='-';
  163.         }
  164.         //在第一行顯示標題
  165.         Set_LCD_POS(0x00);
  166.         for(i=0;i<16;i++)Write_LCD_Data(Temp_Disp_Title[ i]);
  167.         //在第二行顯示當前溫度
  168.         Set_LCD_POS(0x40);
  169.         for(i=0;i<16;i++)Write_LCD_Data(Current_Temp_Display_Buffer[ i]);
  170.         //顯示溫度符號
  171.         Set_LCD_POS(0x4d);Write_LCD_Data(0x00);
  172.         Set_LCD_POS(0x4e);Write_LCD_Data('C');
  173. }
  174. //定時器中斷,控制警報聲音
  175. void T0_INT()interrupt 1{
  176.         TH0=-1000/256;
  177.         TL0=-1000%256;
  178.         BEEP=!BEEP;
  179.         if(++Time0_Count==400){
  180.                 Time0_Count=0;
  181.                 TR0=0;
  182.         }
  183. }
  184. //顯示報警溫度
  185. void Disp_Alarm_Temperature(){
  186.         uchar i,ng;
  187.         //顯示Alarm_Temp_HL數組中的報警溫度值
  188.         //由于Alarm_Temp_HL類型為char,故可以直接進行正負比較
  189.         //高溫報警值
  190.         ng=0;
  191.         if(Alarm_Temp_HL[0]<0)//如果為負數則取反加1
  192.         {
  193.                 Alarm_Temp_HL[0]=~Alarm_Temp_HL[0]+1;
  194.                 ng=1;
  195.         }
  196.         //分解高溫各數位到待顯示串中
  197.         Alarm_HI_LO_STR[4]=Alarm_Temp_HL[0]/100+'0';
  198.         Alarm_HI_LO_STR[5]=Alarm_Temp_HL[0]/10%10+'0';
  199.         Alarm_HI_LO_STR[6]=Alarm_Temp_HL[0]%10+'0';
  200.         //屏蔽高位不顯示
  201.         if(Alarm_HI_LO_STR[4]=='0')Alarm_HI_LO_STR[4]=' ';
  202.         if(Alarm_HI_LO_STR[4]==' '&&Alarm_HI_LO_STR[5]=='0')
  203.                 Alarm_HI_LO_STR[5]=' ';
  204.         //"-"符號顯示
  205.         if(ng){
  206.                 if(Alarm_HI_LO_STR[5]==' ')Alarm_HI_LO_STR[5]='-';
  207.                 else if(Alarm_HI_LO_STR[4]==' ')Alarm_HI_LO_STR[4]='-';
  208.                 else Alarm_HI_LO_STR[3]='-';
  209.         }
  210.         //低溫報警值
  211.         ng=0;
  212.         if(Alarm_Temp_HL[1]<0)//如果為負數則取反加1
  213.         {
  214.                 Alarm_Temp_HL[1]=~Alarm_Temp_HL[1]+1;
  215.                 ng=1;
  216.         }
  217.         //分解高溫各數位到待顯示串中
  218.         Alarm_HI_LO_STR[12]=Alarm_Temp_HL[1]/100+'0';
  219.         Alarm_HI_LO_STR[13]=Alarm_Temp_HL[1]/10%10+'0';
  220.         Alarm_HI_LO_STR[14]=Alarm_Temp_HL[1]%10+'0';
  221.         //屏蔽高位不顯示
  222.         if(Alarm_HI_LO_STR[12]=='0')Alarm_HI_LO_STR[12]=' ';
  223.         if(Alarm_HI_LO_STR[12]==' '&&Alarm_HI_LO_STR[13]=='0')
  224.                 Alarm_HI_LO_STR[13]=' ';
  225.         //"-"符號顯示
  226.         if(ng){
  227.                 if(Alarm_HI_LO_STR[13]==' ')Alarm_HI_LO_STR[13]='-';
  228.                 else if(Alarm_HI_LO_STR[12]==' ')Alarm_HI_LO_STR[12]='-';
  229.                 else Alarm_HI_LO_STR[11]='-';
  230.         }
  231.         //顯示高低溫報警溫度值
  232.         Set_LCD_POS(0x00);//顯示標題
  233.         for(i=0;i<16;i++)Write_LCD_Data(Alarm_Temp[ i]);
  234.         Set_LCD_POS(0x40);//顯示高低溫
  235.         for(i=0;i<16;i++)Write_LCD_Data(Alarm_HI_LO_STR[ i]);
  236. }
  237. void LCD_Initialise(){
  238.         Write_LCD_Command(0x38);DelayXus(5);
  239.         Write_LCD_Command(0x01);DelayXus(5);
  240.         Write_LCD_Command(0x06);DelayXus(5);
  241.         Write_LCD_Command(0x0c);DelayXus(5);
  242. }
  243. void main(){
  244.         LCD_Initialise();
  245.         IE=0x82;
  246.         TMOD=0x01;
  247.         TH0=-1000/256;
  248.         TL0=-1000%256;
  249.         TR0=0;
  250.         K1=1;
  251.         Set_Alarm_Temp_Value();
  252.         Read_Temperature();
  253.         Delay(50000);
  254.         Delay(50000);
  255.         while(1){
  256.                 if(K1==0)
  257.                 {
  258.                         //顯示報警溫度上下限
  259.                         Read_Temperature();
  260.                         Disp_Alarm_Temperature();
  261.                         DelayXus(100);
  262.                 }else
  263.                 {
  264.                 //正常顯示當前溫度,越界時報警
  265.                                 Read_Temperature();
  266.                                 if(DS18B20_IS_OK){
  267.                                         if(HI_Alarm==1||LO_Alarm==1)TR0=1;
  268.                                                 else TR0=0;
  269.                                         Display_Temperature();
  270.                                 }
  271.                                 DelayXus(100);
  272.                 }
  273.         }
  274. }

復制代碼



回復

使用道具 舉報

ID:440028 發表于 2022-1-11 14:50 | 顯示全部樓層
程序有錯誤嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 在线看片福利 | 亚洲成人中文字幕 | 国产a视频| 国产一区二区三区免费 | 免费看黄色片 | 毛片国产 | 日本精品在线观看 | 欧美亚洲视频 | 日韩三区在线 | 亚洲视频欧美视频 | 国产精品久久国产精品久久 | 亚洲视频免费在线观看 | 国产成人综合久久 | 黄色在线观看网站 | 日日摸夜夜爽人人添av | 国产在线精品一区二区 | 亚洲成人免费在线 | 欧美一级一区 | 在线观看中文视频 | 国产91丝袜在线熟 | 久久精品91久久久久久再现 | 在线观看中文字幕 | 成人h视频在线观看 | 中文在线a在线 | 请别相信他免费喜剧电影在线观看 | 免费在线精品视频 | wwwww在线观看 | 精久久久 | 亚洲综合色视频在线观看 | 国产一区二区三区视频 | 久久久亚洲综合 | 久久精品国产久精国产 | 国产日韩欧美精品一区二区三区 | 亚洲精品日韩在线 | 精品一级毛片 | 福利视频亚洲 | 成人黄色av网址 | 日本不卡在线观看 | 精品三区| 国产精品美女www | eeuss国产一区二区三区四区 |