1、溫度可通過調整DS18B20“+”“-”進行調整。
2、當溫度超出范圍,會有聲光報警
3、因為在proteus中找不到三極管8550,所以拿了NPN管MSP8098代替,其原理是相同的,但程序稍做修改,位選本來用低電平,現在高電平位選。
4、如何裝載程序?雙擊單片機—program file—找到相應的hex文件。
1523791717856.jpg (26.1 KB, 下載次數: 59)
下載附件
2018-5-31 21:46 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (20.47 KB, 下載次數: 73)
下載附件
2018-6-1 03:57 上傳
0.png (9.77 KB, 下載次數: 74)
下載附件
2018-6-1 03:57 上傳
單片機源程序如下:
- #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include<math.h>
- #include<INTRINS.H>
- #define uchar unsigned char
- #define uint unsigned int
- /******************************************************************/
- /* 定義端口 */
- /******************************************************************/
- sbit buzzer=P1^0;//蜂鳴器端口
- sbit led1=P1^1; //led指示燈,當前溫度高于設置的最高溫度時點亮
- sbit led2=P1^2; //led指示燈,當前溫度低于設置的最低溫度時點亮
- sbit DQ=P1^4; //ds18b20 端口
- sbit key1=P3^4; //按鍵
- sbit key2=P3^5;
- sbit key3=P3^6;
- sbit key4=P3^7;
- /******************************************************************/
- /* 全局變量 */
- /******************************************************************/
- uint temp;//當前溫度值
- uchar TempH=0,TempL=0;
- int temp_max,temp_min;//設定溫度的最大值和最小值
- uchar flag_get,count,num;
- uchar tab[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0~~9段碼
- uchar str[4];//四位數碼管顯示字符
- uchar display_mod;//數碼管顯示模式
- /******************************************************************/
- /* 函數聲明 */
- /******************************************************************/
- unsigned int ReadTemperature(void);//讀取溫度函數
- void Init_DS18B20(void);//18b20初始化函數
- unsigned char ReadOneChar(void);//18B20讀一個字節
- void WriteOneChar(unsigned char dat);//18B20寫一個字節
- void delay(unsigned int i);//短延時
- void delay_ms(uint z);//長延時
- void alarm();//報警
- void keyscan();//鍵盤掃描
- /******************************************************************/
- /* 主函數 */
- /******************************************************************/
- main()
- {
- uchar buzzer_delay=0;//蜂鳴器延時計數
- uchar buzzer_work=0;//蜂鳴器開始工作
- display_mod=0;//顯示當前溫度
- temp_min=10;//設置最低溫
- temp_max=40;//設置最高溫
- TMOD|=0x01;//定時器設置
- TH0=0xef; //定時器初值
- TL0=0xf0;
- IE=0x82;//EA=1,ET0=1
- TR0=1; //開定時器
- P2=0xff;
- count=0;
- buzzer=0;
- while(1)
- {
- keyscan();//獨立按鍵掃描
-
- if(flag_get==1)
- { buzzer_delay++;
- flag_get=0;// 獲取溫度標志清零
- temp=ReadTemperature();//讀溫度值
- }
- if(display_mod==0)
- {
- if(temp&0x8000)
- {
- str[0]=0xbf;//負號標志
- temp=~temp; //取反加1
- temp +=1;
- }
- else
- {
- str[0]=0xff;
- }
- TempH=temp>>4;
- TempL=temp&0x0F;
- TempL=TempL*6/10;//小數近似處理
-
- str[1]=tab[(TempH%100)/10]; //十位溫度
- str[2]=tab[(TempH%100)%10]&0x7f; //個位溫度,帶小數點
- str[3]=tab[TempL];
- }
- else if(display_mod==1)//顯示最低溫
- {
- str[0]=0xc7;//顯示L
- str[1]=tab[temp_min/100]; //溫度百位
- str[2]=tab[(temp_min%100)/10]; //溫度十位
- str[3]=tab[temp_min%10];//溫度個位
- }
- else if(display_mod==2)//顯示最高溫
- {
- str[0]=0x89;//顯示H
- str[1]=tab[temp_max/100]; //溫度百位
- str[2]=tab[(temp_max%100)/10]; //溫度十位
- str[3]=tab[temp_max%10];//溫度個位
- }
- if(buzzer_delay>5)//為了防止溫度獲取前就會出現報警
- {
- buzzer_work=1;
- }
- if(buzzer_work==1)
- alarm();
- }
- }
- /******************************************************************/
- /* 定時器中斷 */
- /******************************************************************/
- void tim(void) interrupt 1 using 1//中斷,用于數碼管掃描和溫度檢測間隔
- {
- TH0=0xea;//定時器重裝值
- TL0=0xf0;
- num++;
- if (num==100)
- {
- num=0;
- flag_get=1;//獲取溫度標志位有效
- }
- count++;
- if(count==1)
- {
- //P2=0Xfe;
- P2=0x01;
- P0=str[0];
- }//數碼管掃描
- if(count==2)
- {
- if(str[1]==tab[0])
- str[1]=0xff;//顯示為空
- //P2=0Xfd;
- P2=0x02;
- P0=str[1];
- }
- if(count==3)
- {
- //P2=0Xfb;
- P2=0x04;
- P0=str[2];
- }
- if(count==4)
- {
- //P2=0Xf7;
- P2=0x08;
- P0=str[3];
- count=0;
- }
- }
- /******************************************************************/
- /* 長延時函數 */
- /******************************************************************/
- void delay_ms(uint z) //長延時函數
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /******************************************************************/
- /* 短延時函數 */
- /******************************************************************/
- void delay(unsigned int i)//短延時函數
- {
- while(i--);
- }
- /******************************************************************/
- /* 初始化 */
- /******************************************************************/
- void Init_DS18B20(void)
- {
- /*unsigned char x=0;
- DQ = 1; //DQ復位
- delay(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay(80); //精確延時 大于 480us
- DQ = 1; //拉高總線
- delay(10);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay(5);*/
- unsigned char x=0;
- DQ = 1; //DQ復位
- delay(8); //稍做延時
- DQ = 0; //單片機將DQ拉低
- delay(80); //精確延時 大于 480us
- DQ = 1; //拉高總線
- delay(14);
- x=DQ; //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
- delay(20);
- }
- /******************************************************************/
- /* 讀一個字節 */
- /******************************************************************/
- unsigned char ReadOneChar(void)
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0; // 給脈沖信號
- dat>>=1;
- DQ = 1; // 給脈沖信號
- if(DQ)
- dat|=0x80;
- delay(5);
- }
- return(dat);
- }
- /******************************************************************/
- /* 寫一個字節 */
- /******************************************************************/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- delay(5);
- DQ = 1;
- dat>>=1;
- }
- delay(5);
- }
- /******************************************************************/
- /* 讀取溫度 */
- /******************************************************************/
- unsigned int ReadTemperature(void)
- {
- unsigned char a=0;
- unsigned int b=0;
- unsigned int t=0;
- Init_DS18B20();
- WriteOneChar(0xCC); // 跳過讀序號列號的操作
- WriteOneChar(0x44); // 啟動溫度轉換
- delay(200);
- Init_DS18B20();
- WriteOneChar(0xCC); //跳過讀序號列號的操作
- WriteOneChar(0xBE); //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
- a=ReadOneChar(); //低位
- b=ReadOneChar(); //高位
- b<<=8;
- t=a+b;
- return(t);
- }
- /******************************************************************/
- /* 獨立鍵盤掃描函數并顯示設定的溫度 */
- /******************************************************************/
- void keyscan()
- {
- static uchar keynum;//用于切換界面時按鍵計數
- P3=0xff;//拉高P3口,以讀取P3口的值
- if(key4==0)//設置鍵
- {
- delay_ms(5);//延時消抖
- if(key4==0)
- {
- keynum++;
- keynum%=2;//在0、1間變化
- if(keynum==1)
- {
- display_mod=1;
- }
- else
- {
- display_mod=2;
- }
- }
- while(!key4);//松手檢測
- }
- if(key3==0)//確定鍵
- {
- delay_ms(5);
- if(key3==0)
- {
- keynum=0;
- display_mod=0;
- }
- while(!key3);
- }
- if(key2==0)//加鍵
- {
- delay_ms(5);//延時消抖
- if(key2==0)
- {
- if(display_mod==2)
- {
- temp_max++;
- if(temp_max>=99)
- temp_max=99;
- }
- if(display_mod==1)
- {
- temp_min++;
- if(temp_min>=temp_max)
- temp_min=temp_max;
- }
-
- }
- while(!key2);//松手檢測
- }
- if(key1==0)//減鍵
- {
- delay_ms(5);
- if(key1==0)
- {
- if(display_mod==2)
- {
- temp_max--;
- if(temp_max<=temp_min)
- temp_max=temp_min;
- }
- if(display_mod==1)
- {
- temp_min--;
- if(temp_min<=0)
- temp_min=0;
- }
- }
- while(!key1);//松手檢測
- }
- }
- /******************************************************************/
- /* 蜂鳴器報警程序 */
- /******************************************************************/
- void alarm()
- {
- if(display_mod==0)//在顯示當前溫度時報警才會動作
- {
- if(TempH<(temp_min))
- {
- led1=0;
- led2=1;
- buzzer=~buzzer;
- }
- else if(TempH>=(temp_max))
- {
- led1=1;
- led2=0;
- buzzer=~buzzer;
- }
- else
- {
- led1=1;
- led2=1;
- buzzer=0;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
3 protues仿真.zip
(71.5 KB, 下載次數: 308)
2018-5-31 21:48 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|