我做了一个ds18b20的程序,但是现在总显示85度,不能正常运行。程序如下
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^3;
bit DS18B20_IS_OK=1;//传感器正常标志
uchar temp_value[]={0x00,0x00};//读取的温度值
char alarm_temp[]={50,-10};//报警上下线
sbit beep=P3^5;//蜂鸣器
uchar current=0;//温度整数部分
bit hi_alarm=0;
bit lo_alarm=0;
uchar code dsy_code[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0};
uchar code df_table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//温度小数位表
uchar display_digit[]={0,0,0,0};//待显示的各位温度值
//延时函数
void delay(uint x)
{
while(--x);
}
//初始化DS18B20
uchar init_ds18b20()
{
uchar status;
DQ=1;
delay(8);
DQ=0;
delay(90);
DQ=1;
delay(8);
status=DQ;
delay(100);
DQ=1;
return status;
}
//读一个字节
uchar readonebyte()
{
uchar i,dat=0;
DQ=1;
_nop_();
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
_nop_();_nop_();
if(DQ)
dat|=0x80;
delay(30);
DQ=1;
}
return dat;
}
//写一个字节
void writeonebyte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
}
//读取温度值
void read_temperature()
{
if(init_ds18b20==1)
DS18B20_IS_OK=0;
else
{
writeonebyte(0xcc);//跳过读序列号
writeonebyte(0x44);//启动温度转换
init_ds18b20();
writeonebyte(0xcc);//跳过读序列号
writeonebyte(0xbe); //读取温度存储器
temp_value[0]=readonebyte();//温度低8位
temp_value[1]=readonebyte();//温度高8位
alarm_temp[0]=readonebyte();//报警温度TH
alarm_temp[1]=readonebyte();//报警温度TL
DS18B20_IS_OK=1;
}
}
//设置温度报警值
void set_alarm_temp()
{
init_ds18b20();
writeonebyte(0xcc);//跳过读序列号
writeonebyte(0x4e);//将设定的温度报警值写入ds18b20
writeonebyte(alarm_temp[0]);//写TH
writeonebyte(alarm_temp[1]);//写TL
writeonebyte(0x7f);//12位精度
init_ds18b20();
writeonebyte(0xcc);//跳过读序列号
writeonebyte(0x48);//温度报警值存入ds18b20
}
//数码管显示温度
void display_temperature()
{
uchar i;
uchar t=150;//延时值
uchar ng=0;//负数标志位
uchar np=0;//负号显示位置
char signed_current_temp;
//如果为负数则取反加1,并设置负号标志和负号显示位置
if((temp_value[1]&0xf8)==0xf8)
{
temp_value[1]=~temp_value[1];
temp_value[0]=~temp_value[0]+1;
if(temp_value[0]==0x00)
temp_value[1]++;
ng=1;
np=1;
}
//查表获得温度小数部分
display_digit[0]=df_table[temp_value[0]&0x0f];
//温度整数部分
current=((temp_value[0]&0xf0)>>4)|((temp_value[1]&0x07)<<4);
//有符号的当前温度值
signed_current_temp=ng?(-current):current;
//高低温报警标志设置
hi_alarm=signed_current_temp>=alarm_temp[0]?1:0;
lo_alarm=signed_current_temp<=alarm_temp[1]?1:0;
//整数部分分解成显示的数字
display_digit[3]=current/100;
display_digit[2]=current%100/10;
display_digit[1]=current%10;
if(display_digit[3]==0)
{
display_digit[3]=10;
np=2;
if(display_digit[2]==0)
{
display_digit[2]=10;
np=3;
}
}
//刷新显示
for(i=0;i<20;i++)
{
P0=0;
P2=7;
P0=0x39;
delay(t);//显示C
P0=0;
P2=6;
P0=0x63;
delay(t);//显示du
P0=0;
P2=5;
P0=dsy_code[display_digit[0]];
delay(t);//显示小数位
P0=0;
P2=4;
P0=(dsy_code[display_digit[1]])|0x80;
delay(t);//显示个位和小数点
P0=0;
P2=3;
P0=dsy_code[display_digit[2]];
delay(t);//显示十位
P0=0;
P2=2;
P0=dsy_code[display_digit[3]];
delay(t);//显示百位
if(ng)
{
P0=0;
P2=np;
P0=0x40;
delay(t);//如果是负数,则显示负号
}
}
}
//定时器中断,控制报警声音
void time0() interrupt 1
{
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
beep=!beep;
}
void main()
{
TMOD=0x01;
TH0=(65536-1000)/256;
TL0=(65536-1000)%256;
TR0=0;
EA=1;
ET0=1;
set_alarm_temp();
read_temperature();
delay(50000);
delay(50000);
while(1)
{
read_temperature();
if(DS18B20_IS_OK)
{
if(hi_alarm==1||lo_alarm==1)
TR0=1;
else
TR0=0;
display_temperature();
}
else
{
P0=0;
P2=0;
}
}
}
请大家帮忙看看吧,谢谢各位了 |