- sbit DS=P3^7;//定義 DS18B20 接口
- sbit buzz=P3^6;//定義蜂鳴器
- sbit key1=P3^5;//選擇調整上限或者下限溫度
- sbit key2=P3^4;//溫度增加
- sbit key3=P3^3;//溫度減少
- sbit key4=P3^2;//顯示實際溫度并與上、 下限溫度比較
- sbit p23=P2^3;
- sbit p22=P2^2;
- sbit p21=P2^1;
- sbit p20=P2^0;
- uchar flag=1;
- uchar flag1=0;
- uchar flag2=0;
- static uint tmpH=5;
- static uint tmpL=-5;
- int tmp;//十六位
- uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//7 段數碼管
- 段碼表共陽,0~9 和熄滅, 負的段碼值
- uchar data disp_buf[]={0x00,0x00,0x00,0x00}; //保存各個位上的數值
- //引腳及標志變量初始化
- void init()
- {
- key1=1;
- key2=1;
- key3=1;
- key4=1;
- flag1=0;
- flag2=0;
- }
- //串口初始化
- void init_com()
- {
- TMOD=0x20;//設置定時器方式 1, 用定時器設置串口波特率
- TH1=0xfd;// 裝入初值
- TL1=0xfd;
- TR1=1;//啟動定時器 1;TR1 為 TCON 中的第六位
- REN=1;//串口初始化, 運行串口接收
- SM0=0;
- SM1=1;//這兩行設置串口方式 1
- EA=1;//開啟總中斷
- ES=1;//打開串口中斷開關
- }
- void delay(uint x)
- {
- for(x;x>0;x--);
- }
- void Init_ds18b20()//初始化
- {
- unsigned char x=0;
- DS = 1; //DS 復位
- delay(8); //稍做延時
- DS = 0; //單片機將 DQ 拉低
- delay(80); //精確延時 大于 480us
- DS = 1; //拉高總線
- delay(5);
- x=DS; //稍做延時后 如果 x=0 則初始化成功 x=1 則初始化失敗
- delay(20);
- }
- void Write_ds18b20(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- DS=0;
- //_nop_();
- //_nop_();//啟動寫時許開始, 延時 2us
- if(dat&0x01)
- {
- DS=1;//發 1 狀態
- delay(10);//延時 60us
- }
- else //發 0 狀態
- {
- DS=0;
- delay(10);//延時 60us
- DS=1;//釋放總線
- _nop_();//回復時間延時 2us
- _nop_();
- }
- dat>>=1;
- }
- //delay(4);
- }
- uchar Read_ds18b20()
- {
- uchar i,dat=0;
- for(i=0;i<8;i++)
- {
- DS=1; //特別注意此處
- //_nop_();//延時 1us //特別注意此處
- delay(1); //特別注意此處
- DS=0;//啟動讀開始 //特別注意此處
- dat>>=1;
- DS=1;//釋放總線
- //delay(8);//延時 16us
- if(DS)
- dat=dat|0x80;
- delay(5);
- }
- return dat;
- }
- int ReadTemperature(void)
- {
- uchar a,b;//uchar 八位
- int temp; //十六位
- Init_ds18b20();
- Write_ds18b20(0xCC);// 跳過讀序號列號的操作
- Write_ds18b20(0x44);// 啟動溫度轉換
- delay(200);
- Init_ds18b20();
- Write_ds18b20(0xCC);//跳過讀序號列號的操作
- Write_ds18b20(0xBE);//讀取溫度寄存器等(共可讀 9 個寄存器) 前兩個就是溫度
- a=Read_ds18b20();//低 8 位
- b=Read_ds18b20();//高 8 位
- temp=b;
- temp=temp<<8;
- temp=temp+a;
- return temp;
- }
- void change()
- {
- int tp;
- if((tmp&0xf800)==0xf800)//溫度小于零度時
- {
- tp=tmp;
- tp=~tp+1;
- tmp=tp&0x000f;
- disp_buf[0]=(tmp&0x000f)*0.625+0.5;
- tp=tp>>4;
- tp=tp%100;
- disp_buf[2]=tp/10;
- disp_buf[1]=tp%10;
- if(disp_buf[2]==0)
- {
- disp_buf[3]=10;
- disp_buf[2]=11;
- }
- else
- {
- disp_buf[3]=11;
- }
- }
- else
- {
- disp_buf[0]=(tmp&0x000f)*0.625+0.5;//小數部分
- tp=tmp>>4;//整數部分
- disp_buf[3]=tp/100;//百位
- tp=tp%100;
- disp_buf[2]=tp/10;//十位
- disp_buf[1]=tp%10;//個位
- if(!disp_buf[3])
- {
- disp_buf[3]=10;
- if(!disp_buf[2])
- {
- disp_buf[2]=10;
- }
- }
- }
- }
- void delayms(uint v)//延時, 實現數碼管的動態顯示
- {
- uint m,n;
- for(m=v;m>0;m--)
- for(n=73;n>0;n--);
- }
- void display()//溫度顯示函數
- {
- p20=0;//開百位顯示
- P0=tab[disp_buf[3]];//顯示百位
- delayms(5);//延時
- p20=1;//關百位顯示
- p21=0;
- P0 =tab[disp_buf[2]];//顯示十位
- delayms(5);
- p21=1;
- p22=0;
- P0=tab[disp_buf[1]]&0x7f;//顯示個位,并帶小數點
- delayms(5);
- p22=1;
- p23=0;
- P0 =tab[disp_buf[0]];//顯示小數位
- delayms(5);
- p23=1;
- }
- int main()
- {
- uchar data pc[6];
- uint i;
- init();
- init_com();
- tmp=ReadTemperature();
- change();
- pc[1]=disp_buf[2]+'0';
- pc[2]=disp_buf[1]+'0';
- pc[3]='.';
- pc[4]=disp_buf[0]+'0';
- while(1)
- {
- if(flag==1)
- {
- ES=0;
- for(i=1;i<5;i++)
- {
- SBUF=pc[ i];
- while(!TI);
- TI=0;
- }
- ES=1;
- flag=0;
- }
- while((flag1==0)&&(flag2==0))//flag1=1 時調上限。flag1=2 時調下限
- {
- tmp=ReadTemperature();
- change();
- display();
- if(key1==0)//按下 1 鍵
- {
- delayms(100);
- flag1=1;
- key1 = 1;
- }
- }
- while(flag1==0&&flag2==1)
- {
- buzz=1;
- tmp=ReadTemperature();
- change();
- display();
- while(tmp>=tmpH||tmp<=tmpL)
- {
- tmp=ReadTemperature();
- change();
- display();
- buzz=0;
- }
- }
- while(flag1==1)
- {
- tmp=(tmpH<<4);
- change();
- while(flag1==1)
- {
- display();
- if(key2==0)//上限升高
- {
- tmpH++;
- tmp=(tmpH<<4);
- change();
- while(!key2)
- display();
- }
- if(key3==0)//上限降低
- {
- tmpH--;
- tmp=(tmpH<<4);
- change();
- while(!key3)
- display();
- }
- if(key1 == 0)//切換到調整下限模式
- {
- delayms(5);
- flag1=2;
- tmp=(tmpH<<4);
- while(!key1);
- }
- if(key4==0)//按下 key4,實際溫度與上限、 下限比較
- {
- flag1=0;
- flag2=1;
- //tmp=tmpH;
- while(!key4);
- }
- }
- }
- while(flag1==2)//調下限
- {
- tmp=(tmpL<<4);
- change();
- while(flag1==2)
- {
- display();
- if(key2==0)
- {
- tmpL++;
- tmp=(tmpL<<4);
- change();
- while(!key2)
- display();
- }
- if(key3==0)
- {
- tmpL--;
- tmp=(tmpL<<4);
- change();
- while(!key3)
- display();
- }
- if(key1==0)
- {
- flag1=1;
- tmp=(tmpL<<4);
- while(!key1);
- }
- if(key4==0)
- {
- flag1=0;
- flag2=1;
- //tmp=tmpL;
- while(!key4);
- }
- }
- }
- }
- return 0;
- }
復制代碼 |