在1602显示屏最后几位显示温度值,ds18b20采集温度,但是温度值显示不正确,并且不能变换,请大家帮小弟看看怎么回事,多谢了。
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds18b20_io=P3^7; //定义ds18b20的数据口
uchar tem_data[2]={0}; //暂存读出的高字节和低字节
uchar tem_dataa2[4]={0}; //暂存转换后的值,分别表示百位,十位,个位,符号位
sbit lcd_rs=P2^0; //定义lcd的引脚
sbit lcd_rw=P2^1;
sbit lcd_e=P2^2;
uint tem;
void lcd_write_data();
bit lcd_busy();
//延时1ms程序-----------------------
void delay_1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//lcd写指令-------------------------
void lcd_write_com(uchar lcd_com)
{
while(lcd_busy());
lcd_e=0;
lcd_rs=0;
lcd_rw=0;
P0=lcd_com;
_nop_();_nop_();
lcd_e=1;
_nop_();_nop_();
lcd_e=0;
}
//lcd写数据-------------------------
void lcd_write_data(uchar lcd_data)
{
while(lcd_busy());
lcd_e=0;
lcd_rs=1;
lcd_rw=0;
P0=lcd_data;
_nop_();_nop_();
lcd_e=1;
_nop_();_nop_();
lcd_e=0;
}
//lcd忙检测,1为忙------------------
bit lcd_busy()
{
bit result;
lcd_rs=0;
lcd_rw=1;
lcd_e=1;
delay_1ms(2);
result=(bit)(P0&0x80);
return result;
}
//lcd初始化-------------------------
void lcd_init()
{
delay_1ms(15);
lcd_write_com(0x38);
delay_1ms(5);
lcd_write_com(0x38);
delay_1ms(5);
lcd_write_com(0x38);
while(lcd_busy());
lcd_write_com(0x08);
lcd_write_com(0x01);
lcd_write_com(0x0c);
}
void delay(uint i) //延时ius
{
while(i--)
{
_nop_();
}
}
/*void ds18b20_init()
{
uchar presence=1; //presence=0为存在
uchar release=0; //release=1时初始化成功
while(!release)
{
while(presence)
{
ds18b20_io=1;
ds18b20_io=0;
delay(400);
ds18b20_io=1;
delay(30);
presence=ds18b20_io; //若检测到存在时,跳出循环,没有检测到则重新初始化
}
delay(200);
release=ds18b20_io;
}
}*/
ds18b20_init(void) //ds18b20初始化
{
char presence=1;
while(!presence)
{
while(presence)
{
ds18b20_io=1;_nop_();_nop_();//从高拉倒低
ds18b20_io=0;
delay(550); //550 us
ds18b20_io=1;
delay(66); //66 us
presence=ds18b20_io; //presence=0 复位成功,继续下一步
}
delay(500); //延时500 us
presence=~ds18b20_io;
}
ds18b20_io=1; //拉高电平
}
void ds18b20_write(uchar dataa)
{
uchar i;
for(i=0;i<8;i++)
{
ds18b20_io=1;
delay(2);
ds18b20_io=0;
delay(5);
ds18b20_io=dataa&0x01;
delay(66);
dataa=dataa>>1;
}
ds18b20_io=1;
delay(1);
}
uchar ds18b20_read(void)
{
uchar i,dataa;
for(i=0;i<8;i++)
{
dataa=dataa>>1;
ds18b20_io=1;
delay(2);
ds18b20_io=0;
delay(4);
ds18b20_io=1;
delay(4);
if(ds18b20_io)
dataa=dataa|0x80;
delay(66);
}
ds18b20_io=1;
delay(1);
return dataa;
}
uint ds18b20_readtem()
{
ds18b20_init();
delay(2);
ds18b20_write(0xcc);
ds18b20_write(0x44);
ds18b20_init();
delay(2);
ds18b20_write(0xcc);
ds18b20_write(0xbe);
tem_data[0]=ds18b20_read();
tem_data[1]=ds18b20_read();
tem=tem_data[1];
tem=tem<<8;
tem=tem|tem_data[0];
return tem;
}
void ds18b20_temwork(uchar temp)
{
uchar n;
if(temp>63488)
{temp=65536-temp;n=1;} // 负温度求补码,标志位置1
temp=temp>>4; // 取中间八位,即整数部分的值
tem_dataa2[0]=temp/100; // 取百位数据暂存
tem_dataa2[1]=temp/10%10; // 取十位数据暂存
tem_dataa2[2]=temp%10; // 取个位数据暂存
if(tem_dataa2[0]==0) //高位为0不显示
{
tem_dataa2[0]=0x20;
if(tem_dataa2[1]==0)
{
tem_dataa2[1]=0x20;
}
}
if(n==1) //判断符号位
tem_dataa2[3]=0x2d;
else tem_dataa2[3]=0x20;
}
void main()
{
lcd_init();
while(1)
{
ds18b20_temwork(ds18b20_readtem());
lcd_write_com(0x80+0x40+11);
lcd_write_data(tem_dataa2[3]);
lcd_write_data(0x20);
lcd_write_data(0x30+tem_dataa2[1]);
lcd_write_data(0x30+tem_dataa2[2]);
lcd_write_data(0x43);
}
} |