关于DS18B20的读数问题,为啥一直是高电平?

wjhx 2021-02-08 08:40:31
硬件上加了一个10K上拉电阻,已经试过4.7K及两个4.7K并联,供电3.3V,不加上拉电阻是不能读出数据的。

读取代码:
unsigned char Ds18b20Read(void)
{
unsigned char Value = 0x00;
unsigned int i;
// ds18b20IO_1();
// Ds18b20Delay(3);
for(i=0;i<8;i++)
{
Value >>= 1;
//拉低
Ds18b20OutputInitial();
ds18b20IO_0();
Ds18b20Delay(3);
//释放
ds18b20IO_1();
Ds18b20Delay(3);
if(P2IN & BIT2)
Value |= 0x80;

Ds18b20Delay(60);
}
return Value;
}

读取:
Ds18b20Initial();
Ds18b20Write(0xcc); // 跳过读序号列号的操作
Ds18b20Write(0x44); // 启动温度转换
Ds18b20Delay(2000);

Ds18b20Initial();
Ds18b20Write(0xcc); //跳过读序号列号的操作
Ds18b20Write(0xbe); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
V1 = Ds18b20Read(); //低位
V2 = Ds18b20Read(); //高位

中间加了2000us的延时,试过800ms及200us各试验数据,波形:





从复位后的应答看,设备是可以正常回应的,而且这个设备替换过,应该不是设备问题,为啥这个回复的信息都是高电平,是哪里接错了致使18B20不能接低,还是延时问题时序不对?求指点
...全文
1899 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
worldy 2021-02-09
  • 打赏
  • 举报
回复
示波器检查一下各个脉冲是否符合时序要求 事实上,18B20读、写数还是比较容易实现的,另外,连接口一定要是弱上拉,不能是推挽输出
Edwin.Zhu 2021-02-09
  • 打赏
  • 举报
回复
一般这种使用ADC相关转换的,要么是芯片告知一个完成flag,要么是读取上次的结果的。 这是我之前写的一份18B20的驱动,时间太久远了,不记得能不能用了,可以参考下。 u8 DS18B20_reset(void) { u8 response; DQ_SET_OUT(); DQ = 0; delay_us(480); DQ = 1; DQ_SET_IN(); delay(20); response = DQ; delay_us(400); return response; } u8 DS18B20_read_bit(void) { u8 response = 0; DQ_SET_IN(); DQ = 0; DQ = 1; delay_us(60); if(DQ) response = 1; return response; } u8 DS18B20_read_byte(void) { u8 i; u8 response = 0; for (i = 0;i < 8;i++) { response <<= 1; response |= DS18B20_read_bit(); delay_us(100); } return response; } void DS18B20_write_byte(u8 data) { u8 i; DQ_SET_OUT(); DQ = 1; for (i = 0;i < 8;i++) { DQ = 0; DQ = data & 0x01; delay_us(45); DQ = 1; data >>= 1; } delay_us(45); } float read_temperature(void) { u8 flag; int temp; float response; DS18B20_reset(); DS18B20_write_byte(0xcc); DS18B20_write_byte(0x44); delay_us(4500); DS18B20_reset(); DS18B20_write_byte(0xcc); DS18B20_write_byte(0xbe); temp = DS18B20_read_byte(); temp <<= 8; temp |= DS18B20_read_byte(); response = temp * 0.0625; return response; }
wjhx 2021-02-09
  • 打赏
  • 举报
回复
昨天对着示波器看了一天,还是没有解决。转换后加了800ms的延时,也按一些资料中的试过2/12/50的读取,改过2、3、4等不同组合,还能有什么原因,我用的1M的晶振,应该没有影响吧
wjhx 2021-02-09
  • 打赏
  • 举报
回复
感谢两位,问题已经解决,的确过了这个槛儿之后发现,问题并不是太难,只是进入了一个误区。我的问题并没有出在这个读写的时序上,代码本身没有问题,问题出在晶振上,之前用的1M,今天发现使用2us的延时用示波器看能到30左右,无论怎么改或者去掉这个延时都不行,就提高到了8M,然后就正常了。
wjhx 2021-02-08
  • 打赏
  • 举报
回复
感谢两位回复。我自己感觉,我应该是出在读上,但是却无从下手了,我对两个延时更改了一下,如下: unsigned char Value = 0x00; unsigned int i; ds18b20IO_1(); Ds18b20Delay(3); for(i=0;i<8;i++) { Value >>= 1; //拉低 Ds18b20OutputInitial(); ds18b20IO_0(); Ds18b20Delay(10); //释放 ds18b20IO_1(); Ds18b20Delay(3); if(P2IN & BIT2) Value |= 0x80; Ds18b20Delay(47); Ds18b20Delay(3); } return Value; 。说一下我对这个读时序的理解: 1,主机为输出拉低,延时10us 2,释放改为输入,延时3us等待稳定 3,读取,1与2的延时要小于15us 4,延时47,凑够读时隙的60us 5,恢复延时3us 我这样理解对吗? 另一个问题,手册上看,转换数据是12位约750ms,但是查看了很多的代码中没有这么长,是不是会有影响,或者说本次读取的数据,是上次的转换的结果? 谢谢
worldy 2021-02-08
  • 打赏
  • 举报
回复
18B20对时歇的长短要求比较高,应尽量准确
Edwin.Zhu 2021-02-08
  • 打赏
  • 举报
回复
程序中没有体现Ds18b20Delay(3);的延时时间,楼主可以参考下时序图看看是否时序有问题

27,521

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧