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