主要问题是时序不当和数据处理不当。
- #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写指令函数
- {
- 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写数据函数
- {
- 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位数据接口
- 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写一个字节
- {
- 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读一节数据
- {
- uint i;
- uchar date=0;//读出的一节数据
- for(i=8;i>0;i--)
- {
- DQ=0;//拉低电平
- date>>=1;
- DQ=1;//拉高电平,为输出电平做准备
- if(DQ)
- date|=0x80; //如果读到数据是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);//启动温度转换
- delay_ms(10);//温度转换需要一点时间
- 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; //分解出整数
- Temp_L=Temp&0x0f; //分解出小数
- Temp_L=Temp_L*0.625; //保留一位小数
- 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);
- }
- }
复制代码
|