Proteus中仿真DS18B20读不出数据,程序如下,是因为时序不对吗?(单片机)
#include<REGX51.H>#include<intrins.h>#define_2us_nop_();_nop_();sbitled1=P1^0;sbitDQ=...
#include <REGX51.H>
#include<intrins.h>
#define _2us _nop_();_nop_();
sbit led1=P1^0;
sbit DQ=P2^1;
typedef unsigned char u8;
typedef unsigned int u16;
void DelayXus(u16 t)
{
while(t--);
}
u8 Init_ds18b20(void)
{
DQ=1;
_2us;
DQ=0;
DelayXus(750); //复位最低480us,不超过960us
DQ=1;
DelayXus(60); //复位低电平后,60us内,将返回一个低电平
if(DQ == 0)
{
DelayXus(500); //低电平最长将保持240us
DQ=1;
return 1; //复位成功
}
else
{
return 0;//复位失败
}
}
void Write_ds18b20(u8 dat)
{
u8 t;
DQ=0;
DelayXus(10);
for(t=0;t<8;t++)
{
if(dat & 0x01)
{
DQ=1;
}
else
{
DQ=0;
}
DelayXus(45);
dat >>= 1;
DQ=1;
_2us;
}
}
u8 Read_ds18b20(void)
{
u8 k,dat;
DQ=1;
_2us;
for(k=0;k<8;k++)
{
DQ=0;
DelayXus(10);
if(DQ)
{
dat |= 0x80;
}
DelayXus(50);
DQ=1;
_2us;
dat >>= 1;
}
return dat;
}
u8 Get_tam(void)
{
u8 TanH,TanL,k;
TanH = Init_ds18b20(); //复位
if(TanH == 0) //复位失败
{
return 0;
}
Write_ds18b20(0xcc); //跳过寻址,开始转换
Write_ds18b20(0x44);
DelayXus(500); //等待转换
TanH = Init_ds18b20(); //复位
if(TanH == 0) //复位失败
{
return 0;
}
Write_ds18b20(0xcc); //跳过寻址,读取数据
Write_ds18b20(0xbe);
TanH = Read_ds18b20();
TanL = Read_ds18b20();
Init_ds18b20(); //复位,不在接收后续数据
if(TanH & 0x80) //判断负数
{
k =1;
}
//数据转换
TanH &= 0x07;
TanH <<= 4;
TanL &= 0xf0;
TanL >>= 4;
TanH &= TanL;
if(k)
{
TanH = ~TanH;
TanH++;
}
TanH *=0.0625;
return TanH;
}
void main(void)
{
led1=0;
while(1)
{
if(Get_tam()) //有数据返回,则点亮LED
led1=1;
}
} 展开
#include<intrins.h>
#define _2us _nop_();_nop_();
sbit led1=P1^0;
sbit DQ=P2^1;
typedef unsigned char u8;
typedef unsigned int u16;
void DelayXus(u16 t)
{
while(t--);
}
u8 Init_ds18b20(void)
{
DQ=1;
_2us;
DQ=0;
DelayXus(750); //复位最低480us,不超过960us
DQ=1;
DelayXus(60); //复位低电平后,60us内,将返回一个低电平
if(DQ == 0)
{
DelayXus(500); //低电平最长将保持240us
DQ=1;
return 1; //复位成功
}
else
{
return 0;//复位失败
}
}
void Write_ds18b20(u8 dat)
{
u8 t;
DQ=0;
DelayXus(10);
for(t=0;t<8;t++)
{
if(dat & 0x01)
{
DQ=1;
}
else
{
DQ=0;
}
DelayXus(45);
dat >>= 1;
DQ=1;
_2us;
}
}
u8 Read_ds18b20(void)
{
u8 k,dat;
DQ=1;
_2us;
for(k=0;k<8;k++)
{
DQ=0;
DelayXus(10);
if(DQ)
{
dat |= 0x80;
}
DelayXus(50);
DQ=1;
_2us;
dat >>= 1;
}
return dat;
}
u8 Get_tam(void)
{
u8 TanH,TanL,k;
TanH = Init_ds18b20(); //复位
if(TanH == 0) //复位失败
{
return 0;
}
Write_ds18b20(0xcc); //跳过寻址,开始转换
Write_ds18b20(0x44);
DelayXus(500); //等待转换
TanH = Init_ds18b20(); //复位
if(TanH == 0) //复位失败
{
return 0;
}
Write_ds18b20(0xcc); //跳过寻址,读取数据
Write_ds18b20(0xbe);
TanH = Read_ds18b20();
TanL = Read_ds18b20();
Init_ds18b20(); //复位,不在接收后续数据
if(TanH & 0x80) //判断负数
{
k =1;
}
//数据转换
TanH &= 0x07;
TanH <<= 4;
TanL &= 0xf0;
TanL >>= 4;
TanH &= TanL;
if(k)
{
TanH = ~TanH;
TanH++;
}
TanH *=0.0625;
return TanH;
}
void main(void)
{
led1=0;
while(1)
{
if(Get_tam()) //有数据返回,则点亮LED
led1=1;
}
} 展开
2个回答
展开全部
读取DS18B20一般主要控制好读取数据时的时序。由于你的程序是在太长,需要时间理解。建议自己网上找找可用的源代码,学习理解该源代码再试。
可以参考:
http://zhidao.baidu.com/link?url=tPkQyG3TpE_XF985x1I8YhVuPyujLERPHQoHnOwclqf4XyQ5k4PViOJtGkmL6bcczz_bviHnr0kO7ER-fR4dYK
可以参考:
http://zhidao.baidu.com/link?url=tPkQyG3TpE_XF985x1I8YhVuPyujLERPHQoHnOwclqf4XyQ5k4PViOJtGkmL6bcczz_bviHnr0kO7ER-fR4dYK
追问
嗯,我在Proteus里看波形,发现好像成周期固定的矩形波了,妹的,那么多个小延时,我都怀疑,是系统给他吃啦……
光派通信
2024-09-03 广告
2024-09-03 广告
对光传输设备进行调试和维护,需要掌握以下关键点:1. **熟悉设备性能**:深入了解OTN/DWDM等光传输产品的性能特点,确保能够熟练使用设备。2. **按规范操作**:依据产品说明书和维护手册进行调试和维护,确保操作步骤正确无误。3. ...
点击进入详情页
本回答由光派通信提供
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询