0.png (17.46 KB, 下載次數: 81)
下載附件
2017-7-27 23:25 上傳
0.png (54.98 KB, 下載次數: 85)
下載附件
2017-7-27 23:26 上傳
單片機源程序如下:
- #include<reg51.h>
- #include<intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- uchar i;
- sbit RS=P3^0;
- sbit RW=P3^1;
- sbit E=P3^2;//LCD的RS RW E三個端口的定義
- sbit BF=P2^7;
- sbit d1=P1^0;
- sbit d2=P1^1;//警報定義
- sbit key=P1^5;//總開關控制標志位
- sbit key1=P1^6;//加開關
- sbit key2=P1^7;//減開關
- uchar code t0[]="0000-00-00";
- uchar code t1[]="T:";
- uchar code t2[]="00:00:00";
- uchar code t3[]="Mon ";//清屏顯示
- uchar code wendu[]="0123456789";//定義數字,以方便顯示溫度以及時間
- uchar code weeks[]="Mon Tue Wed Thu Fri Sat Sun ";//定義一到星期天
- sbit DQ = P3^7;//DQ的數據線輸入輸出口
- uchar Temp;
- void delay(uint z)
- {
- uint x,y;
- for(x=20;x>1;x--)
- for(y=z;y>1;y--);
- }//延遲函數
- bit BusyTest(void)//忙檢測指令。對寄存器的操作,如果忙返回1,如果空閑返回0
- {
- bit result;
- RS=0;
- RW=1;//RS=0;RW=1時可以讀寄存器的狀態
- E=1; //E=1才允許讀寫
- _nop_(); //空操作,主要作用類似于延遲
- _nop_();
- _nop_();
- _nop_();
- result=BF; //將忙碌標志位賦值給result作為忙檢測指令的返回值
- E=0; //將E重新置為低電平
- return result;
- }
- void write_com(uchar com)//寫命令
- {
- while(BusyTest()==1); //如果忙就等待
- RS=0;
- RW=0;
- P2=com;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- void write_date(uchar date)//寫數據
- {
- while(BusyTest()==1); //如果忙就等待
- RS=1;
- RW=0;
- P2=date;
- delay(5);
- E=1;
- delay(5);
- E=0;
- }
- void init_lcd()//初始化
- {
- E=0;
- RW=0;
- write_com(0x38);//LCD初始化設置 (顯示模式設置:16X2顯示,8位數據接口)
- write_com(0x01);//清屏,將以前的顯示清除
- write_com(0x0c);//開顯示。無光標,光標不閃爍
- write_com(0x06);//讓光標右移,字符不移動
- write_com(0x80);//初始化位置(第一行第一列)
- for(i=0;i<10;i++)
- {
- write_date(t0[i]);
- delay(0);//顯示"0000-00-00";
- }
- write_com(0x80+13);
- for(i=0;i<4;i++)
- {
- write_date(t3[i]);//顯示"Mon "
- delay(0);
- }
- write_com(0x80+0x40);
- for(i=0;i<8;i++)
- {
- write_date(t2[i]);//顯示"00:00:00"
- delay(0);
- }
- write_com(0x80+0x40+10);
- for(i=0;i<2;i++)
- {
- write_date(t1[i]);//顯示"T:"
- delay(0);
- }
-
- }
- void tmpDelay(int num)//做延遲用
- {
- while(num--) ;
- }
- void Init_DS18B20()//初始化設置
-
- {
- unsigned char x=0;
- DQ = 1; //先將數據線拉高
- tmpDelay(8);
- DQ = 0; //再將數據從高拉到低 。要求保持480~960us
- tmpDelay(80);//延遲略微在480~960us,以向DS18B20發出一持續的480~960us低電平復位脈沖
- DQ = 1; //釋放數據線,將數據線拉高
- tmpDelay(14);//延遲給硬件反應時間
- // x=DQ; //讓單片機檢測是否輸出了存在脈沖(DQ=0表示存在),可有可無
- tmpDelay(20);
- }
- unsigned char ReadOneChar()//讀一個字節
- {
- unsigned char i=0;
- unsigned char dat = 0;
- for (i=8;i>0;i--)
- {
- DQ = 0;
- dat>>=1;
- DQ = 1;
- if(DQ)
- dat|=0x80;
- tmpDelay(4);
-
- }
- return(dat);
- }
- void WriteOneChar(unsigned char dat)//寫一個字節數據
- {
- unsigned char i=0;
- for (i=8; i>0; i--)
- {
- DQ = 0;
- DQ = dat&0x01;
- tmpDelay(5);
- DQ = 1;
- dat>>=1;
- }
- }
- unsigned int Readtemp()
- {
- unsigned char a=0;
- unsigned char b=0;
- unsigned int t=0;
- float tt=0;
- Init_DS18B20();//初始化
-
- WriteOneChar(0xCC); //跳過ROM
- WriteOneChar(0x44); //溫度轉換
- Init_DS18B20();//初始化,每次執行都要初始化
- WriteOneChar(0xCC); //跳過ROM
- WriteOneChar(0xBE);//存暫存器
- a=ReadOneChar(); //將低兩位放在a中
- b=ReadOneChar(); //將高兩位放在b中
- t=b;
- t<<=8;
- t=t|a;
- tt=t*0.0625;
- t= tt*10+0.5;
- return(t);
- }
- unsigned int num,num1;
- void display()//動態顯示
- {
- unsigned int num,num1;
- unsigned int shi,ge,xiaoshu;
-
- num=Readtemp();
- num1=num/10;
-
- /*****溫度高于100度或者低于10度時警報器響紅燈亮*****/
- if(num1>100)
- {
- d1=0;d2=0;
- }
- else if(num1<10)
- {
- d1=0;d2=0;
- }
- else
- {
- d1=1;d2=1;
- }
- /*********************************************/
- shi=num/100;//溫度的十位
- ge=num/10%10;//溫度的個位
- xiaoshu=num%10;//溫度的小數位
- write_com(0x80+0x40+12);//顯示的位置
- write_date(wendu[shi]);//顯示十位
- write_com(0x80+0x40+13);//顯示的位置
- write_date(wendu[ge]);//顯示個位
- write_com(0x80+0x40+14);//顯示的位置
- write_date(0x2e);//顯示小數點
- write_com(0x80+0x40+15);//顯示的位置
- write_date(wendu[xiaoshu]);//顯示十位
- }
- unsigned char shis=23,fen=59,miao=50;//定義時分秒
- unsigned int nian=2017,yue=5,ri=24,xingqi=8,k=0;//定義年月日
- void LCD_time()//時間
- {
- /**********年月日*****************/
- write_com(0x80);
- write_date(wendu[nian/1000]);//千位
- write_date(wendu[nian%1000/100]);//百位
- write_date(wendu[nian%100/10]);//十位
- write_date(wendu[nian%10]);//個位
- write_com(0x80+5);
- write_date(wendu[yue/10]);
- write_date(wendu[yue%10]);
- write_com(0x80+8);
- write_date(wendu[ri/10]);
- write_date(wendu[ri%10]);
- /***********星 期****************/
- write_com(0x80+13);
- for(k=0+xingqi;k<4+xingqi;k++)
- {
- write_date(weeks[k]);
- }
- /***********時分秒***************/
- write_com(0x80+0x40);
- write_date(wendu[shis/10]);
- write_date(wendu[shis%10]);
- write_com(0x80+0x40+3);
- write_date(wendu[fen/10]);
- write_date(wendu[fen%10]);
- write_com(0x80+0x40+6);
- write_date(wendu[miao/10]);
- write_date(wendu[miao%10]);
- }
- /*************************************
- 函數功能:秒鐘走動時,時,分 年 月 日以及星期的換算
- **************************************/
- void zou()
- {
- if(fen==60)
- {
- fen=0;
- shis++;
- }
- if(shis==24)
- {
- shis=0;
- ri++;
- xingqi+=4;
- if(xingqi==28)
- xingqi=0;
- }
- if(yue==1||yue==3||yue==5||yue==7||yue==8||yue==10||yue==12)
- {
- if(ri==32)
- {
- ri=1;
- yue++;
- }
- }
- else if(yue==2&&((nian%400==0)||(nian%4==0&&nian%100!=0)))
- {
- if(ri==30)
- {
- ri=1;
- yue++;
- }
- }
-
- else if(yue==4||yue==6||yue==9||yue==11)
- {
- if(ri==31)
- {
- ri=1;
- yue++;
- }
- }
- else
- {
- if(ri==29)
- {
- ri=1;
- yue++;
- }
- }
- if(yue==13)
- {
- yue=1;
- nian++;
- }
- }
- /*******************************************************
- 函數功能:總開關控制調時間的標識為Temp,Temp為1時可調秒
- Temp為2時,調分依次到可調年后Temp重置為0,時間繼續走
- *******************************************************/
- void keys()
- {
- if(key==0)
- {
- delay(10);
- if(key==0)
- {
- while(key==0)
- display();
- TR0=0;
- Temp++;
- if(Temp==8)
- {
- Temp=0;
- TR0=1;
- }
- }
- }
- }
- /*定義以下函數*/
- void mins(uchar);
- uchar key_button(uchar Times,Temp);
- uint key_nian(uint Times);
- void key_Temp(uchar Temp);
- uchar key_xingqi(uchar Times);
- uchar Y;
- void main()
- {
- EA=1;
- ET0=1;
- TMOD=0X01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TR0=1;//時鐘的初始化
- init_lcd();//初始化LCD
- d1=1;d2=1;
- while(1)
- {
- display();//溫度顯示
- zou();//判斷時間之間的運算,實現秒鐘走可以控制時分,年月日以及星期的換算
- key_Temp(Temp);//根據標識位置確定可以調節那個時間
- keys();//總開關
- LCD_time();//時間顯示
- }
- }
- void int0() interrupt 1 //定時器中斷1
- {
- unsigned char ms;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- ms++;
- if(ms==20)
- {
- ms=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- }
- }
- }
- /********************************************************/
- void key_Temp(uchar Temp)//實現調節時鐘時閃爍的效果,
- {
- switch(Temp)
- {
- case 1:
- Y=5;
- while(Y--){ mins(Temp); miao=key_button(miao,1);keys();}
- Y=5;
- while(Y--){ LCD_time(); miao=key_button(miao,1);keys();}
- break;
- case 2:
- Y=5;
- while(Y--){ mins(Temp); fen=key_button(fen,2);keys();}
- Y=5;
- while(Y--){ LCD_time(); fen=key_button(fen,2);keys();}
- break;
- case 3:
- Y=5;
- while(Y--){ mins(Temp); shis=key_button(shis,3);keys();}
- Y=5;
- while(Y--){ LCD_time(); shis=key_button(shis,3);keys();}
- break;
- case 4:
- Y=5;
- while(Y--){ mins(Temp); xingqi=key_xingqi(xingqi);keys();}
- Y=5;
- while(Y--){ LCD_time(); xingqi=key_xingqi(xingqi);keys();}
- break;
- case 5:
- Y=5;
- while(Y--){ mins(Temp); ri=key_button(ri,Temp);keys();}
- Y=5;
- while(Y--){ LCD_time(); ri=key_button(ri,Temp);keys();}
- break;
- case 6:
- Y=5;
- while(Y--){ mins(Temp); yue=key_button(yue,Temp);keys();}
- Y=5;
- while(Y--){ LCD_time(); yue=key_button(yue,Temp);keys();}
- break;
- case 7:
- Y=5;
- while(Y--){ mins(Temp); nian=key_nian(nian);keys();}
- Y=5;
- while(Y--){ LCD_time(); nian=key_nian(nian);keys();}
- break;
- }
- }
- /********************************************************/
- uchar key_button(uchar Times,Temp)//月、日、時分秒
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- LCD_time();
- Times++;
- if(Temp==3)
- {
- if(Times==24)
- Times=0;
- }
- else if(Temp==1||Temp==2)
- {
- if(Times==60)
- Times=0;
- }
- else if(Temp==5)
- {
- if(Times==32)
- Times=0;
- }
- else if(Temp=6)
- {
- if(Times==13)
- Times=0;
- }
-
-
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times--;
- if(Temp==3)
- {
- if(Times==255)
- Times=23;
- }
- else if(Temp==1||Temp==2)
- {
- if(Times==255)
- Times=59;
- }
- else if(Temp==5)
- {
- if(Times==255)
- Times=31;
- }
- else if(Temp==6)
- {
- if(Times==255)
- Times=12;
- }
- }
-
- }
- return Times;
- }
- /********************************************************/
- uint key_nian(uint Times)//年的加減
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- display();
- Times++;
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times--;
- if(Times==1980)
- Times=1980;
- }
-
- }
- return Times;
- }
- /********************************************************/
- uchar key_xingqi(uchar Times)//星期的加減
- {
- if(key1==0)
- {
- delay(10);
- if(key1==0)
- {
- while(key1==0)
- display();
- Times+=4;
- if(Times==28)
- Times=0;
- }
-
- }
- if(key2==0)
- {
- delay(10);
- if(key2==0)
- {
- while(key2==0)
- display();
- Times-=4;
- if(Times==-4)
- Times=24;
- }
-
- }
- return Times;
- }
- void mins(uchar Temp)//不顯示shijian的動態顯示
- {
- /**********年月日*****************/
- write_com(0x80);
- if(Temp==7)
- {
- write_date(' ');
- write_date(' ');
- write_date(' ');
- write_date(' ');
- }
- else
- {
- write_date(wendu[nian/1000]);//千位
- write_date(wendu[nian%1000/100]);//百位
- write_date(wendu[nian%100/10]);//十位
- write_date(wendu[nian%10]);//個位
- }
- write_com(0x80+5);
- if(Temp==6)
- {
- write_date(' ');
- write_date(' ');
- }
- else
- {
- write_date(wendu[yue/10]);
- write_date(wendu[yue%10]);
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
wenduji.zip
(114.92 KB, 下載次數: 31)
2017-7-27 20:04 上傳
點擊文件名下載附件
DS18B20 下載積分: 黑幣 -5
|