| 
 
| 各位大神,本人写的温度传感器驱动程序,显示数值是个死值,用手摸温度传感器,数值不变化。初始化程序和显示程序经测试是正确的。测试方法:初始化成功收到应答信号蜂鸣;单独给一个数字,显示正常。我怀疑算法那里出问题了,求大神指教,或者谈谈调试方法。 /*温度传感器输出的是二进制码,是以《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();
 }
 }
 
 
 | 
 |