主要問題是時序不當和數(shù)據(jù)處理不當。
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- void display1_Temperature(int temp);
- int num1(uchar temp1,uchar temp2);
- uint shu10(t);
- uint time;
- uchar code cdis1[]="Error!!!";
- uchar code cdis2[]="Xianzaiwendu:";
- uchar code cdis3[]="Temp:XXXX.X*C";
- uint code date1[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- sbit RS=P2^0;
- sbit RW=P2^1;
- sbit EN=P2^2;
- sbit DQ=P3^7;
- void delay_ms(uchar ms)//毫秒延時
- {
- uint x,y;
- for(x=ms;x>0;x--)
- for(y=124;y>0;y--);
- }
- //大致延時長度如下 T=us×2+5 uS
- void delay_us(uchar us)
- {
- while(--us);
- }
- bit busy() //檢測LCD1602忙
- {
- bit Bit;
- RS=0;
- RW=1;
- EN=1;
- delay_ms(1);
- Bit=(bit)(P0&0x80);//最高位為忙信號位
- EN=0;
- return Bit;
- }
- void write_com(uchar com)//LCD1602寫指令函數(shù)
- {
- while(busy());
- RS=0;
- RW=0;
- P0=com;
- delay_ms(5);
- EN=1;
- delay_ms(5);
- EN=0;
- }
- void pos_LCD(uchar pos)//LCD的顯示位置
- {
- write_com(0x80|pos);
- }
- void write_date(uchar date)//LCD1602寫數(shù)據(jù)函數(shù)
- {
- while(busy()); //測忙
- RS=1;
- RW=0;
- P0=date;
- delay_ms(5);
- EN=1;
- delay_ms(5);
- EN=0;
- }
- void init_LCD1602()//LCD1602初始化
- {
- EN=0;
- write_com(0X38);//設置16*2顯示,5*7點陣,8位數(shù)據(jù)接口
- write_com(0X0C);//設置開顯示,不開光標
- write_com(0X06);//寫一個字符時,整屏右移
- write_com(0X01);//顯示清零
- }
- bit init_DS18B02()//DS18B02初始化
- {
- bit x;//用于檢測DS18B02是否存在,1是并不存在,0是存在
- DQ=1;//先將電平拉高
- delay_us(5);
- DQ=0;//將電平拉低,要求保持480uS-960uS
- delay_us(200);
- delay_us(200);
- DQ=1;//釋放電平
- delay_us(50);
- x=DQ;//保持DS18B02是否存在的電平
- delay_us(25);//延時足夠長的時間,等待存在脈沖輸出完畢
- return x;//返回是否存在
- }
- void write_DS18B02(uchar date) //DS18B20寫一個字節(jié)
- {
- uint i;
- for(i=8;i>0;i--)
- {
- DQ=0;
- DQ=date&0x01;
- delay_us(25);
- DQ=1;
- date>>=1;
- }
- delay_us(25);
- }
- uchar Read_DS18B02()//從DS18B02讀一節(jié)數(shù)據(jù)
- {
- uint i;
- uchar date=0;//讀出的一節(jié)數(shù)據(jù)
- for(i=8;i>0;i--)
- {
- DQ=0;//拉低電平
- date>>=1;
- DQ=1;//拉高電平,為輸出電平做準備
- if(DQ)
- date|=0x80; //如果讀到數(shù)據(jù)是1,將1存入date
- delay_us(25);
- }
- return date;
- }
- void error()//顯示檢測不到DS18B02
- {
- uint i;
- pos_LCD(0x00);//設置顯示位置為第一行
- for(i=0;i<8;i++)write_date(cdis1[i]);
- }
- void display_explan1()//第一行的顯示
- {
- uint i;
- pos_LCD(0x00);//設置顯示位置為第一行
- for(i=0;i<13;i++)write_date(cdis2[i]);
- }
- void display_explan2()//第二行的顯示
- {
- uint i;
- pos_LCD(0x40);//設置顯示位置為第二行
- for(i=0;i<13;i++)write_date(cdis3[i]);
- }
- uint display()//讀溫度
- {
- uchar L;
- uint t,H;
- init_DS18B02();//DS18B02初始化
- write_DS18B02(0xCC);//跳過讀序號的操作
- write_DS18B02(0x44);//啟動溫度轉(zhuǎn)換
- delay_ms(10);//溫度轉(zhuǎn)換需要一點時間
- init_DS18B02();//DS18B02初始化
- write_DS18B02(0xCC);//跳過讀序號的操作
- write_DS18B02(0xBE);//讀取溫度寄存器
- L=Read_DS18B02();
- H=Read_DS18B02();
- t=H<<8|L;
- return(t);
- }
- void main()
- {
- uchar Temp_L,Temp_H;
- uint Temp;
- bit negative=0;
- init_LCD1602();//LCD1602初始化
- if(init_DS18B02()==1)//檢測不到DS18B02
- error();//顯示檢測不到DS18B02
- display_explan1();//第一行的顯示
- display_explan2();//第二行的顯示
- while(1)
- {
- Temp=display();
- if(Temp&0x8000)
- {
- negative=1;
- Temp=~Temp+1;
- }
- else negative=0;
-
- Temp_H=Temp>>4; //分解出整數(shù)
- Temp_L=Temp&0x0f; //分解出小數(shù)
- Temp_L=Temp_L*0.625; //保留一位小數(shù)
- write_com(0xc5);
- if(negative==1)
- write_date('-');
- else
- write_date('+');
- write_date(Temp_H/100+'0');
- write_date(Temp_H/10%10+'0');
- write_date(Temp_H%10+'0');
- write_date('.');
- write_date(Temp_L+'0');
- write_date(0xdf);
- delay_us(10);
- }
- }
復制代碼
|