各位大神,本人写的温度传感器驱动程序,显示数值是个死值,用手摸温度传感器,数值不变化。初始化程序和显示程序经测试是正确的。测试方法:初始化成功收到应答信号蜂鸣;单独给一个数字,显示正常。我怀疑算法那里出问题了,求大神指教,或者谈谈调试方法。
/*温度传感器输出的是二进制码,是以《1/16 摄氏度》为单位的。如果直接显示,其数值,就是实际温度的 16 倍,所以,需要除以 16,或乘以 0.0625*/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar bai,shi,ge,p,q=0;//显示位定义
uchar a;
sbit ENLED1=P1^4;//138使能端为低电平
sbit addr0=P1^0;//A
sbit addr1=P1^1;//B
sbit addr2=P1^2;//C
sbit addr3=P1^3;//138使能端为高电平
uchar code table []={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//0xff为熄灭符
uchar temper[2]={0x00,0x00};//定义一个数组用来存储高低8位温度数值
uchar dis_buf[5]={0x00,0x00,0x00,0x00,0x00};//显示缓冲;
sbit DQ=P3^2;//温度传感器
sbit BUZZ=P1^6;//蜂鸣器检测复位信号
bit yes;//ds18b20复位成功应答信号,返回信号是bit型数据,不能用uchar
/*显示延时函数,毫秒级别,用于人眼可以分别出来的延时*/
void delay1 (uchar z)
{
uchar x,y;
for(x=z;x>0;x--)
for(y=200;y>0;y--);
}
/*蜂鸣函数*/
void beep ()
{
BUZZ=0;
delay1(20);
BUZZ=1;
delay1(20);
}
/*ds18b20延时函数,微妙级别*/
void delay2 (uint y)
{
while(y--);
}
/*DS18B20复位函数*/
bit reset (void)
{
DQ=1;//释放数据总线
delay2(8);//延时一会,待数据稳定
DQ=0;//总线复位
delay2(90);//延时480us
DQ=1;//释放总线,等待ds18b20发出应答信号
delay2(8);//延时16-60us
yes=DQ;
delay2(100);
DQ=1;//释放总线
return( yes);
}
/*写一个字节*/
void writebyte (uchar dat)
{
uchar i;
DQ=1;//释放总线
delay2(8);
for (i=0;i<8;i++)
{
DQ=0;//准备写数据
DQ=dat&0x01;
delay2(5);//延时15us,等待ds18b20采样数据
DQ=1;//释放总线
dat>>=1;//写数据时低位在前
}
}
/*读一个字节*/
uchar readbyte (void)
{
uchar i,dat=0;
DQ=1;
delay2(5);//释放总线
for(i=8;i<0;i--)
{
DQ=0;//读数据时先将总线拉低
dat>>=1;//利用右移延时
DQ=1;//释放总线,准备读数
if(DQ)//如果数据为高,让它和0x80相与,如果数据为低,不用理睬?
dat|=0x80;
delay2(4);
}
return (dat);/*返回哪里(应该是返回本函数 哪里调用此函数 哪里得到这个返回值)*/
}
/*获取温度函数*/
void gettemperture ()
{
reset();
if(yes==0)//如果DS18B20复位成功,执行写命令,读数据操作,如果没有复位成功,那么跳出大循环或者蜂鸣
{
writebyte(0xcc);//直挂一个温度传感器,跳过序列号
writebyte(0x44);//启动温度转换
delay1(550);//等待750ms转换结束,时间需要仿真(此处仿真时间仿真不出来,更改延时数字由不变到变化)
reset();
writebyte(0xcc);//直挂一个温度传感器,跳过序列号
writebyte(0xbe);//读取温度寄存器
temper[0]=readbyte();//读取低8位
temper[1]=readbyte();//读取高8位
}
else beep();
}
/*温度数据处理函数*/
uchar convdata (void)
{
uchar temp;
temp=((temper[1]&0x0f)<<4)|((temper[0]&0xf0)>>4);//将高字节数据和0x0f相与去掉符号位(不完全),将低字节数据和f0相与去掉低字节的小数位,然后组成一个字节
return (temp);
}
/*显示函数*/
void display ()
{
ENLED1=0;
addr3=1;
a=convdata;//此处在display程序内部定义a的类型为uchar型必须给下边的程序加个while(1)循环;或者将a改为全局变量也行,奇怪
dis_buf[2]=a/100;P0=table[dis_buf[2]] ;addr0=0;addr1=1;addr2=0;delay1(8);//显示百位
dis_buf[1]=(a%100/10);P0=table[dis_buf[1]];addr0=1;addr1=0;addr2=0;delay1(8);//显示十位
dis_buf[0]=(a%100%10);P0=table[dis_buf[0]];addr0=0;addr1=0;addr2=0;delay1(8);//显示个位
}
/*主函数*/
void main ()
{
while(1)
{
gettemperture();
// convdata ();//刚开始写程序的时候并没有写此语句,因为display函数要用该函数的一个返回值,故可以认为调用了该函数
display();
}
}
|