用Keil寫(xiě)的。溫度傳感器用DS18B20,單片機(jī)AT89C51. /*溫度范圍-55.0度~+99.9度,用四個(gè)七段LED顯示出來(lái)*/ #include#include #include //要用到取絕對(duì)值函數(shù) sbit DQ=P3^7;//DS18B20的數(shù)據(jù)線和單片機(jī)的P3.7口相接,且定義DQ為變量名 sbit led3_g=P2^4;//單片機(jī)的P2.4口定義為L(zhǎng)ED1的g段,表示溫度的正負(fù) sbit led0_off=P3^3;//led0熄滅信號(hào)接到P3.3口 sbit led1_off=P3^4;//led0熄滅信號(hào)接到P3.4口 sbit led2_off=P3^5;//led0熄滅信號(hào)接到P3.5口 float low_limitedTmp,high_limitedTmp; //設(shè)置的報(bào)警最低溫度和最高溫度,因?yàn)橐趲讉€(gè)函數(shù)中用,故為全局變量 int Final_tmpvalue; //存放最終得到的十進(jìn)制有符號(hào)并放大10倍的溫度值 unsigned char key_value;//存放鍵值 unsigned char sys_state;//存放系統(tǒng)狀態(tài),共有3態(tài) //正常測(cè)溫狀態(tài)sys_state=0、調(diào)最低溫度狀態(tài)sys_state=1、 //調(diào)最高溫度狀態(tài)sys_state=2 unsigned char led_pst;//存放正在設(shè)置的led位置值 //led_pst=0表示正在設(shè)置最右邊的LED,加1依次往左表示 /*****************延時(shí)函數(shù)************** *************功能:延時(shí)Nx15us***********/ void delay_multi_15us(unsigned int N) { do{ _nop_();//1 _nop_();//2 _nop_();//3 _nop_();//4 _nop_();//5 _nop_();//6 _nop_();//7 _nop_();//8 _nop_();//9 _nop_();//10 _nop_();//11 _nop_();//12 _nop_();//13 N--;//計(jì)滿15us后N減1 }while(N); } /*********************初始化函數(shù)****************************** ***********功能:初始化DS18B20,以便能進(jìn)行后續(xù)讀寫(xiě)操作********/ bit Init_DS18B20(void)//返回為位的函數(shù),以便檢測(cè)是否成功啟動(dòng) { DQ=0;//先拉低延時(shí)一段時(shí)間 delay_multi_15us(50);//延時(shí)750us,協(xié)議要求480us~980us,滿足要求 DQ=1;//再拉高延時(shí) delay_multi_15us(6);//延時(shí)等待返回低電平 return(DQ); delay_multi_15us(26);//再延時(shí)一段時(shí)間 } /****************** 寫(xiě)一字節(jié)數(shù)據(jù)函數(shù)********************* ************功能:向DS18B20寫(xiě)一個(gè)字節(jié)的數(shù)據(jù)內(nèi)容**********/ void WritetoDS_onebyte(char command) { unsigned char i; //8位數(shù)據(jù)記位,為了節(jié)約資源定義為8位 bit temp; for(i=0;i<8;i++) { temp=command&0x01;//將最低位提取出來(lái) command>>1;//將其右移一位 if(temp)//如果寫(xiě)入的是1,則按1的操作:先置DQ=0,延時(shí)15us,再置DQ=1,延時(shí)45us { DQ=0; delay_multi_15us(1);//延時(shí)15us DQ=1; delay_multi_15us(3);//延時(shí)45us } else //如果寫(xiě)入的是0,則按0的操作:先置DQ=0,延時(shí)60us,再置DQ=1 { DQ=0; delay_multi_15us(4);//延時(shí)60us DQ=1; } } } /****************** 讀一字節(jié)數(shù)據(jù)函數(shù)********************* ************功能:從DS18B20讀一個(gè)字節(jié)的數(shù)據(jù)內(nèi)容**********/ unsigned char ReadfromDS_onebyte()//char類型函數(shù),最后要返回一個(gè)字節(jié)數(shù)據(jù) { unsigned char i,dat; dat=0;//初始化存放讀取內(nèi)容的變量 for(i=0;i<8;i++) { DQ=0; //先拉低約4us,符合至少1us的要求 _nop_(); _nop_(); _nop_(); _nop_(); DQ=1; //再拉高延時(shí) delay_multi_15us(1);//延時(shí)15us _nop_();//為了保證大于15us再延時(shí)幾u(yù)s _nop_(); _nop_(); if(DQ) //如果讀出為1,按1讀: { dat=dat|0x80;//存進(jìn)最高位,待會(huì)右移 } else { dat=dat|0x00;//存進(jìn)最高位,待會(huì)右移 } dat=dat>>1; delay_multi_15us(4);//延時(shí)60us } return(dat); } /************************發(fā)送溫度轉(zhuǎn)換命令函數(shù) **************************** **************功能:發(fā)送溫度轉(zhuǎn)換命令到DS18B20,啟動(dòng)溫度轉(zhuǎn)換功能************/ void SendCommand_TmpConvert(void) { while(Init_DS18B20());//初始化DS18B20,等待返回低電平信號(hào) WritetoDS_onebyte(0xcc);//寫(xiě)入跳過(guò)序列號(hào)命令字 Skip Rom WritetoDS_onebyte(0x44);//寫(xiě)入溫度轉(zhuǎn)換命令字 Convert T,啟動(dòng)溫度轉(zhuǎn)換功能 } /************************發(fā)送讀取溫度命令函數(shù) **************************** **************功能:發(fā)送溫度讀取命令到DS18B20,讀取DS18B20中的溫度值************/ void SendCommand_TmpRead(void) { while(Init_DS18B20());//初始化DS18B20,等待返回低電平信號(hào) WritetoDS_onebyte(0xcc);//寫(xiě)入跳過(guò)序列號(hào)命令字 Skip Rom WritetoDS_onebyte(0xbe);//寫(xiě)入溫度讀取命令字 ,以便后續(xù)讀取溫度值 } /******************************溫度值獲取和計(jì)算函數(shù)*********************** ***************功能:獲得溫度值并進(jìn)行計(jì)算,得到最終十進(jìn)制溫度值***********/ int Get_TmpValue(void)//返回溫度最終十進(jìn)制值 { unsigned int Temp_tmpvalue;//存放中間溫度變量 float temp;//存放中間的浮點(diǎn)數(shù),因?yàn)榉直媛蕿?.0625,故先算出來(lái)的應(yīng)該為浮點(diǎn)數(shù) unsigned char low,high;//存放讀取出來(lái)的溫度低、高字節(jié) SendCommand_TmpRead();//送讀取溫度命令 low=ReadfromDS_onebyte();//讀取兩個(gè)字節(jié)的數(shù)據(jù),先送入低字節(jié) high=ReadfromDS_onebyte();//再送入高字節(jié) Temp_tmpvalue=high;//數(shù)據(jù)處理,將兩個(gè)字節(jié)合并 Temp_tmpvalue<<=8; Temp_tmpvalue|=low; Final_tmpvalue=Temp_tmpvalue;//直接將無(wú)符號(hào)數(shù)變?yōu)橛蟹?hào)數(shù) //因?yàn)橛?jì)算機(jī)中對(duì)于負(fù)數(shù)是利用補(bǔ)碼來(lái)表示的 //若是負(fù)值, 讀取出來(lái)的數(shù)值是用補(bǔ)碼表示的, 可直接賦值給int型的Final_tmpvalue temp=Final_tmpvalue*0.0625; //使用DS18B20的默認(rèn)分辨率12位, 精確度為0.0625度, //即讀回?cái)?shù)據(jù)的最低位代表0.0625度 Final_tmpvalue=temp*10+(Final_tmpvalue>0?0.5:-0.5); //將它放大10倍, //使顯示時(shí)可顯示小數(shù)點(diǎn)后1位, 并對(duì)小數(shù)點(diǎn)后第二進(jìn)行4舍5入 //如t=11.0625, 進(jìn)行計(jì)數(shù)后, 得到value = 1106, 即11.06 度 //如t=-11.0625, 進(jìn)行計(jì)數(shù)后, 得到value = -1106, 即-11.06 度 //大于0加0.5, 小于0減0.5 return(Final_tmpvalue);//最終返回放大10倍的十進(jìn)制有符號(hào)溫度值 } /**************************溫度LED顯示函數(shù)***************************** *******************功能:將溫度值顯示在LED數(shù)碼管上*********************/ void Display_TmpValue(int tmp)//參數(shù)將引用函數(shù)Get_TmpValue(), //或者直接引用全局變量Final_tmpvalue //或者顯示設(shè)置的最高或者最低溫度high_limitedTmp*10、low_limitedTmp*10 { unsigned char dat[3]={0,0,0};//定義分別存溫度的十、個(gè)、小數(shù)三位值 unsigned char temp; unsigned int v; LED1_g=tmp>0?0:1;//確定負(fù)號(hào)顯示與否:溫度為正不點(diǎn)亮LED1_g, //為負(fù)則置P2.4=1,即點(diǎn)亮LED1_g,顯示為一個(gè)“-”號(hào) v=abs(tmp); //取溫度的絕對(duì)值 dat[0]=v%100; //計(jì)算十位數(shù)值 dat[1]=(v-(dat[0]*100))%10; //計(jì)算個(gè)位數(shù)值 dat[2]=v-(dat[0]*100)-(dat[1]*10);//計(jì)算小數(shù)位數(shù)值 temp=dat[0];//將十位和個(gè)位合并送到P0口顯示 temp<<=4; temp|=dat[1]; P0=temp;//已包含reg51.h頭文件,可以直接用P口 P2&=0x10;//先將P2口低4位清0,高4位不改變 P2|=dat[2];//將小數(shù)位送到P2口低4位顯示:不改變高4位,把低4位送入P2口低4位 } /************************************報(bào)警函數(shù)************************************** **************功能:當(dāng)溫度超過(guò)設(shè)置的最高值或者低于最低值時(shí)系統(tǒng)報(bào)警*****************/ void Alarm_tmp(int tmp) //參數(shù)將引用函數(shù)Get_TmpValue() //得出的溫度值全局變量Final_tmpvalue { sbit BUZZER=P2^5; //定義蜂鳴器口為P2.5口 sbit LED_R=P2^6; //定義紅燈為P2.6口 sbit LED_G=P2^7; //定義綠燈為P2.7口 float temp; temp=tmp/10.0; //因?yàn)閠mp為放大10倍的溫度值,要再縮小10倍 if((temp>=high_limitedTmp)||(temp<=low_limitedTmp)) //高于設(shè)置最高溫或者低于最低溫 { BUZZER=1; //蜂鳴器響 LED_R=1; //紅燈亮 LED_G=0; //綠燈滅 } else //正常 { BUZZER=0; //蜂鳴器停 LED_R=0; //紅燈滅 LED_G=1; //綠燈亮 } } /**********************************鍵盤(pán)掃描函數(shù)************************************ ***************功能:當(dāng)有鍵盤(pán)中斷時(shí),進(jìn)入鍵盤(pán)查詢鍵值,得出按下的鍵值**************/ void Int0_key_Calculate() interrupt 0 //中斷程序,用外部中斷0 { unsigned char row,col;//分別存放鍵盤(pán)為0的行和列號(hào) int temp; sbit P1_4=P1^4; sbit P1_5=P1^5; sbit P1_6=P1^6; sbit P1_7=P1^7; EA=0;//關(guān)cpu中斷,在完成一個(gè)鍵的過(guò)程中不能有中斷產(chǎn)生 delay_multi_15us(800);//進(jìn)入中斷,說(shuō)明有鍵按下,先延時(shí)12ms去抖 if((P1|0x10)!=1)//有鍵按下,進(jìn)入查詢程序 { switch(P1)//根據(jù)P1口來(lái)查哪一行為低電平,P1=1111xxxx,其中xxxx中只有一個(gè)為0 { case 0x0FE:row=0;break; //如果P1=1111 1110,則置row=0 case 0x0FD:row=1;break; //如果P1=1111 1101,則置row=1 case 0x0FB:row=2;break; case 0x0F7:row=3;break; default:break; } P1_5=1;//先置P0.4口為0,P0.5~P0.7為1 P1_6=1; P1_7=1; if((P1|0x10)!=1) //如果P0.0~P0.3中有0,則列號(hào)為P0.4,置col=0標(biāo)志 col=0; else //否則繼續(xù)查P0.5 { P1_4=1;//置P0.5口為0 P1_5=0; P1_6=1; P1_7=1; if((P1|0x10)!=1) //如果P0.0~P0.3中有0,則列號(hào)為P0.5,置col=1標(biāo)志 col=1; else //否則繼續(xù)查P0.6 { P1_4=1;//再置P0.6口為0 P1_5=1; P1_6=0; P1_7=1; if((P1|0x10)!=1) //如果P0.0~P0.3中有0,則列號(hào)為P0.6,置col=2標(biāo)志 col=2; else //否則繼續(xù)查P0.7 { P1_4=1;//再置P0.5口為0 P1_5=1; P1_6=1; P1_7=0; if((P1|0x10)!=1) //如果P0.0~P0.3中有0,則列號(hào)為P0.7,置col=3標(biāo)志 col=3; } } } temp=row;//將row和col合并,以便查鍵值 temp<<=8; temp|=col; switch(temp)//鍵值查詢賦值 { case 0x0000:key_value=1;break;//第0行第0列,鍵值為1 case 0x0001:key_value=2;break;//第0行第1列,鍵值為2 case 0x0002:key_value=3;break; case 0x0003:key_value=4;break; case 0x0100:key_value=5;break;//第1行第0列,鍵值為5 case 0x0101:key_value=6;break;//第1行第1列,鍵值為6 case 0x0102:key_value=7;break; case 0x0103:key_value=8;break; case 0x0200:key_value=9;break; case 0x0201:key_value=0;break; case 0x0202:key_value='L';break;//表示要設(shè)置最低溫度 case 0x0203:key_value='H';break;//表示要設(shè)置最高溫度 case 0x0300:key_value='l';break;//表示按下向左鍵 case 0x0301:key_value'r';break;//表示按下向右鍵 case 0x0302:key_value='F';break;//表示改變正負(fù)號(hào)的標(biāo)志flag case 0x0303:key_value='E';break;//表示按下了確認(rèn)鍵 default:key_value=FALSE;break;//無(wú)按鍵按下 } } else key_value=FALSE; //無(wú)鍵按下,將鍵值置為FALSE if(key_value!=FALSE) Tmp_Setting();//每一次有鍵按下進(jìn)行一次狀態(tài)查詢和溫度設(shè)置 EA=1;//開(kāi)cpu中斷,準(zhǔn)備下次中斷 P1=0x01;//將鍵盤(pán)掃描口低4位寫(xiě)入全1,高四位寫(xiě)入全0,以查下次中斷 } /***************************************單LED跳動(dòng)顯示函數(shù)*************************************** ***功能:根據(jù)LED的位置參數(shù)led_pos跳動(dòng)此位置的單個(gè)LED,其他的靜止顯示************/ void Single_LED_twinkle(void) { unsigned char i; switch(led_pst) { case 0:for(i=0;i<2;i++) //正在設(shè)置小數(shù)位led0,閃2次 { led0_off=0;//將led0熄滅 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 led0_off=1;//將led0點(diǎn)亮 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 } break; case 1:for(i=0;i<2;i++) //正在設(shè)置個(gè)位led1,閃2次 { led1_off=0;//將led1熄滅 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 led1_off=1;//將led1點(diǎn)亮 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 } break; case 2:for(i=0;i<2;i++) //正在設(shè)置十位led2,閃2次 { led2_off=0;//將led2熄滅 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 led2_off=1;//將led2點(diǎn)亮 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 } break; case 3:for(i=0;i<2;i++) //正在設(shè)置符號(hào)位led3,閃2次 { led3_g=0;//將led0熄滅 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 led3_g=1;//將led0熄滅 delay_multi_15us(20000);//延時(shí)300ms,大于人視覺(jué)暫留時(shí)間 } break; } } /******************全4個(gè)LED跳動(dòng)顯示函數(shù)************************************* *功能:在進(jìn)入最低極限溫度或者最高極限溫度設(shè)置的初始時(shí)將4個(gè)LED全部跳動(dòng)閃爍幾下***/ void All_LED_twinkle(int lmt_tmp)//參數(shù)將引用low_limitedTmp或者h(yuǎn)igh_limitedTmp { unsigned char i; Display_TmpValue(lmt_tmp*10);//先顯示上次設(shè)置的極限溫度 for(i=0;i<3;i++)//跳動(dòng)3次 { delay_multi_15us(40000);//延時(shí)延時(shí)600ms led0_off=0;//將led0熄滅 led1_off=0;//將led1熄滅 led2_off=0;//將led2熄滅 led3_g=0;//將led0熄滅 delay_multi_15us(40000);//延時(shí)延時(shí)600ms led0_off=1;//將led0點(diǎn)亮 led1_off=1;//將led1點(diǎn)亮 led2_off=1;//將led2點(diǎn)亮 led3_g=1;//將led0點(diǎn)亮 } } /******************************************溫度設(shè)置函數(shù)***************************************** ************功能:根據(jù)鍵盤(pán)掃描值設(shè)置報(bào)警的最低溫度和最高溫度*************************/ void Tmp_Setting(void) { unsigned char lmt_low_tmp[3];//lmt_low_tmp[0]、lmt_low_tmp[1]、 //lmt_low_tmp[2]、lmt_low_tmp[3]分別表示 //調(diào)節(jié)中的小數(shù)位數(shù)字、個(gè)位數(shù)字、十位數(shù)字、正負(fù)號(hào)(正用0,負(fù)用1表示) unsigned char lmt_high_tmp[3];//lmt_high_tmp[0]、lmt_high_tmp[1]、 //lmt_high_tmp[2]、lmt_high_tmp[3]分別表示 //調(diào)節(jié)中的小數(shù)位數(shù)字、個(gè)位數(shù)字、十位數(shù)字、正負(fù)號(hào)(正用0,負(fù)用1表示) unsigned int tmp[2];//存放low_limitedTmp、 high_limitedTmp的絕對(duì)值放大10倍的值 tmp[0]=abs(low_limitedTmp*10); tmp[1]=abs(high_limitedTmp*10); unsigned int tmp; if(sys_state==0)//查狀態(tài)為狀態(tài)0:正常測(cè)溫狀態(tài) { switch(key_value)//查此時(shí)按下的鍵值 { case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 0: case 'l': case 'r': case 'F': case 'E':break; //在sys_state=0正常測(cè)溫下,按以上鍵均無(wú)效 case 'L':sys_state=1;//按“VL”,則轉(zhuǎn)換為設(shè)置溫度下限狀態(tài) led_pst=0;//默認(rèn)為最右邊的led0設(shè)置 lmt_low_tmp[3]=(low_limitedTmp>0?0:1);//提取分離極限最低溫度的每一位數(shù)值 lmt_low_tmp[2]=tmp[0]%100; lmt_low_tmp[1]=(tmp[0]-lmt_tmp[2]*100)%10; lmt_low_tmp[0]=tmp[0]-lmt_tmp[2]*100-lmt_tmp[1]*10; All_LED_twinkle(low_limitedTmp);//全部閃爍3次 Single_LED_twinkle(led_pst);//再默認(rèn)為最右邊的led閃爍設(shè)置 break; case 'H':sys_state=2;//按“VH”,則轉(zhuǎn)換為設(shè)置溫度下限狀態(tài) led_pst=0; //默認(rèn)為最右邊的led0設(shè)置 lmt_high_tmp[3]=(high_limitedTmp>0?0:1);//提取分離極限最高溫度的每一位數(shù)值 lmt_high_tmp[2]=tmp[1]%100; lmt_high_tmp[1]=(tmp[1]-lmt_tmp[2]*100)%10; lmt_high_tmp[0]=tmp[1]-lmt_tmp[2]*100-lmt_tmp[1]*10; All_LED_twinkle(low_limitedTmp);//全部閃爍3次 Single_LED_twinkle(led_pst);//再默認(rèn)為最右邊的led閃爍設(shè)置 break; } } if(sys_state==1)//查狀態(tài)為狀態(tài)1:設(shè)置最低極限溫度狀態(tài) { switch(key_value)//查此時(shí)按下的鍵值 { case 1:switch(led_pst) { case 0:lmt_low_tmp[0]=1;//小數(shù)位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 1:lmt_low_tmp[1]=1;//個(gè)位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 2:lmt_low_tmp[2]=1;//十位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 3:Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break;//無(wú)效 }break; case 2:switch(led_pst) { case 0:lmt_low_tmp[0]=2;//小數(shù)位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 1:lmt_low_tmp[1]=2;//個(gè)位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 2:lmt_low_tmp[2]=2;//十位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 3:Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break;//無(wú)效 }break; case 3:switch(led_pst) { case 0:lmt_low_tmp[0]=3; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=3; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=3; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 4:switch(led_pst) { case 0:lmt_low_tmp[0]=4; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=4; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=4; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 5:switch(led_pst) { case 0:lmt_low_tmp[0]=5; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=5; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=5; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 6:switch(led_pst) { case 0:lmt_low_tmp[0]=6; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=6; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=6; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 7:switch(led_pst) { case 0:lmt_low_tmp[0]=7; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=7; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=7; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 8:switch(led_pst) { case 0:lmt_low_tmp[0]=8; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=8; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=8; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 9:switch(led_pst) { case 0:lmt_low_tmp[0]=9; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=9; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=9; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 0:switch(led_pst) { case 0:lmt_low_tmp[0]=0; Single_LED_twinkle(led_pst); break; case 1:lmt_low_tmp[1]=0; Single_LED_twinkle(led_pst); break; case 2:lmt_low_tmp[2]=0; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 'l':switch(led_pst) { case 0:led_pst=1;//按一次向左鍵led向左移一次,改變?cè)O(shè)置的位數(shù) Single_LED_twinkle(led_pst);//換閃爍的led break; case 1:led_pst=2; Single_LED_twinkle(led_pst); break; case 2:led_pst=3; Single_LED_twinkle(led_pst); break; case 3:led_pst=0;//到最左邊的led再按向左回到最右邊的led0 Single_LED_twinkle(led_pst); break; }break; case 'r':switch(led_pst) { case 0:led_pst=3;//按一次向右鍵led向右移一次,改變?cè)O(shè)置的位數(shù) Single_LED_twinkle(led_pst);//換閃爍的led break; case 1:led_pst=0; Single_LED_twinkle(led_pst); break; case 2:led_pst=1; Single_LED_twinkle(led_pst); break; case 3:led_pst=2;//到最左邊的led再按向左回到最右邊的led0 Single_LED_twinkle(led_pst); break; }break; case 'F':switch(led_pst) { case 0:Single_LED_twinkle(led_pst);//設(shè)置符號(hào)正負(fù)的鍵,對(duì)小數(shù)位、個(gè)位、十位不起作用 break; case 1:Single_LED_twinkle(led_pst); break; case 2:Single_LED_twinkle(led_pst); break; case 3:if(lmt_low_tmp[3]==0) lmt_low_tmp[3]=1; //對(duì)符號(hào)位取反,如果以前是正,則按下后變?yōu)樨?fù) else lmt_low_tmp[3]=0; Single_LED_twinkle(led_pst); break; }break; case 'E':sys_state=0;//系統(tǒng)設(shè)置溫度完成,回到正常測(cè)溫時(shí)候 if(lmt_low_tmp[3]==0)//最低溫度是正溫度時(shí) { low_limitedTmp=(lmt_low_tmp[2]*100+lmt_low_tmp[1]*10+lmt_low_tmp[0])/10.0; //計(jì)算并確認(rèn)設(shè)置后的最低溫度 } else //最低溫度是負(fù)溫度時(shí) { low_limitedTmp=-(lmt_low_tmp[2]*100+lmt_low_tmp[1]*10+lmt_low_tmp[0])/10.0; } break; case 'L':Single_LED_twinkle(led_pst);//正在設(shè)置報(bào)警低溫,不起作用,相應(yīng)led閃爍 break; case 'H':sys_state=2;//按“VH”,則轉(zhuǎn)換為設(shè)置溫度上限狀態(tài) led_pst=0; lmt_high_tmp[3]=(high_limitedTmp>0?0:1);//提取分離極限最高溫度的每一位數(shù)值 lmt_high_tmp[2]=tmp[1]%100; lmt_high_tmp[1]=(tmp[1]-lmt_tmp[2]*100)%10; lmt_high_tmp[0]=tmp[1]-lmt_tmp[2]*100-lmt_tmp[1]*10; All_LED_twinkle(high_limitedTmp);//全部閃爍3次 Single_LED_twinkle(led_pst);//再默認(rèn)為最右邊的led閃爍設(shè)置 break; } } if(sys_state==2)//查狀態(tài)為狀態(tài)2:設(shè)置最高極限溫度狀態(tài) { switch(key_value)//查此時(shí)按下的鍵值 { case 1:switch(led_pst) { case 0:lmt_high_tmp[0]=1;//小數(shù)位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 1:lmt_high_tmp[1]=1;//個(gè)位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 2:lmt_high_tmp[2]=1;//十位為1 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 3:Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break;//無(wú)效 }break; case 2:switch(led_pst) { case 0:lmt_high_tmp[0]=2;//小數(shù)位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 1:lmt_high_tmp[1]=2;//個(gè)位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 2:lmt_high_tmp[2]=2;//十位為2 Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break; case 3:Single_LED_twinkle(led_pst);//相應(yīng)led閃爍 break;//無(wú)效 }break; case 3:switch(led_pst) { case 0:lmt_high_tmp[0]=3; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=3; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=3; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 4:switch(led_pst) { case 0:lmt_high_tmp[0]=4; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=4; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=4; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 5:switch(led_pst) { case 0:lmt_high_tmp[0]=5; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=5; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=5; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 6:switch(led_pst) { case 0:lmt_high_tmp[0]=6; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=6; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=6; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 7:switch(led_pst) { case 0:lmt_high_tmp[0]=7; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=7; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=7; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 8:switch(led_pst) { case 0:lmt_high_tmp[0]=8; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=8; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=8; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 9:switch(led_pst) { case 0:lmt_high_tmp[0]=9; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=9; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=9; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 0:switch(led_pst) { case 0:lmt_high_tmp[0]=0; Single_LED_twinkle(led_pst); break; case 1:lmt_high_tmp[1]=0; Single_LED_twinkle(led_pst); break; case 2:lmt_high_tmp[2]=0; Single_LED_twinkle(led_pst); break; case 3:Single_LED_twinkle(led_pst); break; }break; case 'l':switch(led_pst) { case 0:led_pst=1;//按一次向左鍵led向左移一次,改變?cè)O(shè)置的位數(shù) Single_LED_twinkle(led_pst);//換閃爍的led break; case 1:led_pst=2; Single_LED_twinkle(led_pst); break; case 2:led_pst=3; Single_LED_twinkle(led_pst); break; case 3:led_pst=0;//到最左邊的led再按向左回到最右邊的led0 Single_LED_twinkle(led_pst); break; }break; case 'r':switch(led_pst) { case 0:led_pst=3;//按一次向右鍵led向右移一次,改變?cè)O(shè)置的位數(shù) Single_LED_twinkle(led_pst);//換閃爍的led break; case 1:led_pst=0; Single_LED_twinkle(led_pst); break; case 2:led_pst=1; Single_LED_twinkle(led_pst); break; case 3:led_pst=2;//到最左邊的led再按向左回到最右邊的led0 Single_LED_twinkle(led_pst); break; }break; case 'F':switch(led_pst) { case 0:Single_LED_twinkle(led_pst);//設(shè)置符號(hào)正負(fù)的鍵,對(duì)小數(shù)位、個(gè)位、十位不起作用 break; case 1:Single_LED_twinkle(led_pst); break; case 2:Single_LED_twinkle(led_pst); break; case 3:if(lmt_high_tmp[3]==0) lmt_high_tmp[3]=1;//對(duì)符號(hào)位取反,如果以前是正,則按下后變?yōu)樨?fù) else lmt_high_tmp[3]=0; Single_LED_twinkle(led_pst); break; }break; case 'E':sys_state=0;//系統(tǒng)設(shè)置溫度完成,回到正常測(cè)溫時(shí)候 if(lmt_high_tmp[3]==0)//最低溫度是正溫度時(shí) { high_limitedTmp=(lmt_high_tmp[2]*100+lmt_high_tmp[1]*10+lmt_high_tmp[0])/10.0; //計(jì)算并確認(rèn)設(shè)置后的最低溫度 } else //最低溫度是負(fù)溫度時(shí) { high_limitedTmp=-(lmt_high_tmp[2]*100+lmt_high_tmp[1]*10+lmt_high_tmp[0])/10.0; } break; case 'L':sys_state=1;//按“VL”,則轉(zhuǎn)換為設(shè)置溫度下限狀態(tài) led_pst=0; lmt_low_tmp[3]=(low_limitedTmp>0?0:1);//提取分離極限最低溫度的每一位數(shù)值 lmt_low_tmp[2]=tmp[0]%100; lmt_low_tmp[1]=(tmp[0]-lmt_tmp[2]*100)%10; lmt_low_tmp[0]=tmp[0]-lmt_tmp[2]*100-lmt_tmp[1]*10; All_LED_twinkle(low_limitedTmp);//全部閃爍3次 Single_LED_twinkle(led_pst);//再默認(rèn)為最右邊的led閃爍設(shè)置 break; case 'H':Single_LED_twinkle(led_pst);//正在設(shè)置報(bào)警高溫,不起作用,相應(yīng)led閃爍 break; } } } /***********************************主程序***************************************/ void main() { EA=1;//開(kāi)cpu中斷和INT0中斷 EX0=1; P1=0x01;//將鍵盤(pán)掃描口低4位寫(xiě)入全1,高四位寫(xiě)入全0 sys_state=0;//初始化系統(tǒng)狀態(tài)為測(cè)溫狀態(tài)0 led0_off=1;//把led全部點(diǎn)亮 led1_off=1; led2_off=1; low_limitedTmp=-40.0;//設(shè)置初始報(bào)警溫度下限 high_limitedTmp=50.0;//設(shè)置初始報(bào)警溫度下限 Final_tmpvalue=100;//設(shè)置初始10倍放大溫度以便滅報(bào)警器和紅燈 Alarm_tmp(Final_tmpvalue);//初始化報(bào)警設(shè)備 while(1) //實(shí)時(shí)顯示溫度值 { SendCommand_TmpConvert();//啟動(dòng)溫度轉(zhuǎn)換 Display_TmpValue(Get_TmpValue());//顯示溫度值 Alarm_tmp(Final_tmpvalue);//調(diào)用報(bào)警函數(shù) } }
完整程序下載:http://www.torrancerestoration.com/ziliao/file/ds18.rar