采用ds18b20溫度傳感器,將實時溫度與預設溫度進行比較,若實時溫度低于預設溫度,則控制電阻絲進行加熱,若實時溫度高于預設溫度,則停止電阻絲加熱,系統溫度在50~100攝氏度范圍內可調,溫度控制精度±0.5攝氏度。
我主程序的最后用if語句將實時溫度與預設溫度比較,但是用proteus仿真后,P3.1口一直輸出低電平,發現if語句好像沒有起作用,每次都直接執行else語句。下面是我的程序和proteus電路圖。
51hei截圖20210427162136.png (46.67 KB, 下載次數: 40)
下載附件
2021-4-27 16:22 上傳
單片機源程序如下:
- #include"reg51.h"
- #define uint unsigned int
- #define uchar unsigned char
- uchar code smg_duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數碼管段選定義
- uchar code smg_duan1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//數碼管段選定義(小數點)
- uchar code smg_wei[]={0xf7,0xfb,0xfd,0xfe};//數碼管位選定義
- sbit key1=P1^0;//輸入設定溫度50度
- sbit key2=P1^1;//輸入設定溫度75度
- sbit key3=P1^2;//輸入設定溫度100度
- sbit key4=P1^3;//增加2度
- sbit key5=P1^4;//減少2度
- sbit key6=P1^5;//增加0.5度
- sbit key7=P1^6;//減少0.5度
- sbit key8=P1^7;//確認鍵
- float setH=0;//預設溫度上限
- float setL=0;//預設溫度下限
- uint bkey;
- sbit DQ=P3^0;//18b20 I/O口定義
- sbit jiare=P3^1;//加熱電阻絲I/O口定義
- /***********1ms延時函數********/
- void delay_1ms(uint i)
- {
- while(i--);
- }
- /***********小延時函數**********/
- void delay_small(uint q)
- {
- while(q--);
- }
- /**********18b20初始化函數*******/
- void Init_18b20()
- {
- bit q;
- DQ=1;//把總線拉高
- delay_small(1);//15us
- DQ=0;//給復位脈沖
- delay_small(80);//750us
- DQ=1;//把總線拉高,等待
- delay_small(10);//110us
- q=DQ;//讀取18b20初始化信號
- delay_small(20);//200us
- DQ=1;//把總線拉高,釋放總線
- }
- /**********寫18b20數據******/
- void write_18b20(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DQ=0;
- DQ=dat&0x01;//向18b20總線寫數據
- delay_small(5);//60us
- DQ=1;//釋放總線
- dat>>=1;
- }
- }
- /*********讀18b20數據******/
- uchar read_18b20()
- {
- uchar i,r_dat;
- for(i=0;i<8;i++)
- {
- DQ=0;
- r_dat>>=1;//讀數據從低位開始
- DQ=1;//釋放總線
- if(DQ==1)
- r_dat|=0x80;
- delay_small(5);//60us
- }
- return r_dat;//返回數據
- }
- /**********讀取實時溫度數值*******/
- uint read_Tem()
- {
- uint r_high;
- uchar r_low;
- Init_18b20();//初始化18b20
- write_18b20(0xcc);//跳過64位ROM
- write_18b20(0x44);//啟動一次溫度轉換命令
- delay_small(50);//500us
- Init_18b20();//初始化18b20
- write_18b20(0xcc);//跳過64位ROM
- write_18b20(0xbe);//發出讀取暫存器命令
- EA=0;//關總中斷
- r_low=read_18b20();//讀溫度低字節
- r_high=read_18b20();//讀溫度高字節
- EA=1;//開總中斷
- r_high<<=8;//把溫度的高字節左移8位
- r_high|=r_low;//把讀出的溫度低位放到r_high的低八位中
- r_high*=0.625;//轉換到溫度值小數
- return r_high;//返回讀出的溫度
- }
- /**********數碼管顯示溫度函數(實時顯示)******/
- void DisplayTem(uint temperature)
- {
- uint a,b;
- P0=0x00;
- P2=smg_wei[0];//位選小數位
- P0=smg_duan[temperature%10];//段選顯示小數位
- delay_1ms(2300);
- P0=0x00;
- P2=smg_wei[1];//位選個位
- P0=smg_duan1[temperature/10%10];//段選顯示個位
- delay_1ms(2300);
- P0=0x00;
- P2=smg_wei[2];//位選十位
- P0=smg_duan[temperature/100%10];//段選顯示十位
- delay_1ms(2300);
- P0=0x00;
- b=temperature/1000%10;
- if(b==0)
- {
- a=0;
- }
- else
- {
- a=1;
- }
- switch(a)
- {
- case(0):break;
- case(1):P2=smg_wei[3];//位選百位
- P0=smg_duan[temperature/1000%10];//段選顯示百位
- delay_1ms(2300);
- P0=0x00;
- break;
- }
-
- }
- void keyscan()
- {
- bkey=0;
- if(!key1)
- {
- delay_1ms(3000);
- if(!key1)
- bkey=1;
- }
- if(!key2)
- {
- delay_1ms(3000);
- if(!key2)
- bkey=2;
- }
- if(!key3)
- {
- delay_1ms(3000);
- if(!key3)
- bkey=3;
- }
- if(!key4)
- {
- delay_1ms(8000);
- if(!key4)
- bkey=4;
- }
- if(!key5)
- {
- delay_1ms(8000);
- if(!key5)
- bkey=5;
- }
- if(!key6)
- {
- delay_1ms(8000);
- if(!key6)
- bkey=6;
- }
- if(!key7)
- {
- delay_1ms(8000);
- if(!key7)
- bkey=7;
- }
- if(!key8)
- {
- delay_1ms(8000);
- if(!key8)
- bkey=8;
- }
- }
- /***********數碼管顯示函數(按鍵顯示)******/
- void displaytem1(float temperature1)
- {
- do
- {
- uint b;
- float c;
- P0=0x00;
- P2=smg_wei[0];//位選小數位
- c=temperature1*10;
- P0=smg_duan[(int)c/1%10];//段選顯示小數位
- delay_1ms(1325);
- P0=0x00;
- P2=smg_wei[1];//位選個位
- P0=smg_duan1[(int)temperature1/1%10];//段選顯示個位
- delay_1ms(1325);
- P0=0x00;
- P2=smg_wei[2];//位選十位
- P0=smg_duan[(int)temperature1/10%10];//段選顯示十位
- delay_1ms(1325);
- P0=0x00;
- b=(int)temperature1/100%10;
- switch(b)
- {
- case(0):break;
- case(1):P2=smg_wei[3];//位選百位
- P0=smg_duan[1];//段選顯示百位
- delay_1ms(1325);
- P0=0x00;
- break;
- }
- keyscan();
- }
- while(bkey==0);
- }
- void main()
- {
- uint temperature;
- jiare=0;
- do
- {
- keyscan();
- switch(bkey)
- {
- case(0):break;
- case(1):setH=50.0;
- setL=50.0;
- displaytem1(50.0);
- break;
- case(2):setH=75.0;
- setL=75.0;
- displaytem1(75.0);
- break;
- case(3):setH=100.0;
- setL=100.0;
- displaytem1(100.0);
- break;
- case(4):setH=setH+2.0;
- setL=setL+2.0;
- displaytem1(setH);
- break;
- case(5):setH=setH-2.0;
- setL=setL-2.0;
- displaytem1(setH);
- break;
- case(6):setH=setH+0.5;
- setL=setL+0.5;
- displaytem1(setH);
- break;
- case(7):setH=setH-0.5;
- setL=setL-0.5;
- displaytem1(setH);
- break;
- case(8):P0=0x00;
- break;
- }
- }
- while(bkey<8);
- while(1)
- {
- temperature=read_Tem();//讀出溫度的值
- DisplayTem(temperature);//顯示實時溫度
- if(temperature<setH)
- {
- jiare=1;
- }
- else
- {
- jiare=0;
- }
- }
-
- }
復制代碼
|