数码之家

标题: 不使用单片机!USB转串口直接读取DS18B20 [打印本页]

作者: liccil    时间: 2020-3-30 16:24
标题: 不使用单片机!USB转串口直接读取DS18B20
本帖最后由 liccil 于 2020-3-30 19:02 编辑

昨天晚上突发奇想,能不能用UART串口直接读写DS18B20呢
毕竟电平一致,例如空闲时为高电平,串口的起始位正好用于读写单总线器件。串口利用波特率发生器可以构造准确的延时,
通过改变串口波特率,或者构造特殊序列去模拟单总线信号。
中午午休时间简单试验了一下 成功了。
硬件原理如下:一片USB转CP2102的U转串小板,DS18B20一枚,一个1N4148二极管。因为CP2102的TXD为推挽模式,为了避免电平冲突,需要
加一个1N4148。
利用RXD天生的上拉电阻当接收,拉高DS18B20。
[attach]671742[/attach]
接下来就是用示波器 调波特率;
网上找的图,这个是UART串口的波形图:
[attach]671744[/attach]
当发送一个byte时,uart实际输出的是带起始位0和停止位1的。
我们可以利用起始位和停止位,和发送的数据,一起拼凑出需要的波形;
例如DS18B20复位命令,可以使用38400bps,停止位1bit,连续发送两个字节0x00和0xff;
0x00正好就是DS18B20的复位长脉冲;发送后电平被停止位自动拉高;此时DS18B20会自行拉低,表示自己的存在;
后面跟了个0xff,是串口输出高电平;但此时被DS18B20拉住了一段时间,所以发送0xff 回读实测是0xfe(串口是先发送、接收LSB)。由于串口与DS18B20是异步的,因此回读具体是什么
取决于波特率,与DS18B20本身的延时。但肯定不是0xff。
我们可以根据这个判断DS18B20是否存在。当然,波特率不能太高或太低,否则无法拼凑出合适的时间。
[attach]671769[/attach]
上图就是用示波器看DS18B20的复位波形;因为有TXD串联的二极管压降,所以DS18B20在拉低时波形更低。
[attach]671771[/attach]
发命令时,波特率需要提升至115200bps;如上图所示,要给DS18B20发1直接串口发0xFF,发0就发0x00;
上图为给DS18B20发送0xCC,即跳过ROM命令。
[attach]671783[/attach]
读取时也很简单。DS18B20回读时是2字节,因此可以串口发送2*8=16个0xff。
串口自行发送起始位/停止位,这让上位机的编程非常方便,只发送串口数据即可。延时的问题直接波特率发生器搞定。
写0xff后 如果回读的值不是0xff,那就表示DS18B20拉低了,如果还是0xff,那就是高。

中午利用剩余时间胡乱写了个C#的小程序,可以正常读取温度了。
[attach]671792[/attach]
[attach]671793[/attach]





作者: kindzhon    时间: 2020-3-30 17:04
牛啊,来个Python程序是不是更方便?:titter:画个小电路图呗。
作者: 人艰不拆了    时间: 2020-3-30 17:05
哈哈,自己跟自己过不去啊:titter:
作者: liccil    时间: 2020-3-30 17:06
人艰不拆了 发表于 2020-3-30 17:05
哈哈,自己跟自己过不去啊

尝试Geek一下
作者: liccil    时间: 2020-3-30 17:09
kindzhon 发表于 2020-3-30 17:04
牛啊,来个Python程序是不是更方便?画个小电路图呗。

Python应该更方便。不过我还不熟Py 其实C#也不熟 纯瞎写
电路简单 GND接GND 3.3V接VCC DQ接RXD RXD和TXD接个二极管 RXD正 TX负 没了
作者: 温力口    时间: 2020-3-30 17:12
脑洞大开,好牛B!
作者: bxak    时间: 2020-3-30 17:13
这个方案几年前就有了,串口、SPI都行。
因为普通方法读取过程不能开中断,而一些场合又不允许关中断,所以就有人想出来这样的方法

作者: liccil    时间: 2020-3-30 17:15
bxak 发表于 2020-3-30 17:13
这个方案几年前就有了,串口、SPI都行。
因为普通方法读取过程不能开中断,而一些场合又不允许关中断,所以 ...

学习了 以前没玩过 发现这个方式其实比普通io操作更方便一些
作者: la45088d1    时间: 2020-3-30 17:48
liccil 发表于 2020-3-30 17:15
学习了 以前没玩过 发现这个方式其实比普通io操作更方便一些

这样子相当于变相实现了一个1-wire总线的硬件接口,减少了软件模拟协议的开销。
你可以更进一步,写个通用库发布,使用MCU的USART进行1-wire通信,很多人会感谢你的。
作者: 595953427@qq    时间: 2020-3-30 21:44
la45088d1 发表于 2020-3-30 17:48
这样子相当于变相实现了一个1-wire总线的硬件接口,减少了软件模拟协议的开销。
你可以更进一步,写个通 ...

波特率要变来变去,还要保证高速的波特率,不是所有的单片机都支持的。测个温度搞这么麻烦,用NTC不好吗?
作者: la45088d1    时间: 2020-3-30 21:47
595953427@qq 发表于 2020-3-30 21:44
波特率要变来变去,还要保证高速的波特率,不是所有的单片机都支持的。测个温度搞这么麻烦,用NTC不好吗 ...

你试试呗,能做到DS18B20的精度?
人家器件卖4-5RMB一个,如果比不过几毛钱的NTC,人家早就倒闭了。
连STC这种垃圾MCU都可以随便设置波特率,哪个MCU不行?
作者: qrut    时间: 2020-3-30 22:04
有点意思,脑洞大开,示波器存储深度好差啊~
作者: 595953427@qq    时间: 2020-3-30 22:17
la45088d1 发表于 2020-3-30 21:47
你试试呗,能做到DS18B20的精度?
人家器件卖4-5RMB一个,如果比不过几毛钱的NTC,人家早就倒闭了。
连ST ...

我说的不是所有单片机都支持高速的波特率,不是说不支持任意设置波特率。
基本上所有单片机只要在上限波特率之下都可以任意设置,但是上限波特率不一定可以上到38400。
应用场景不同吧,我见过的绝大多数产品上都是用NTC测温度,只在开发板上见过用18B20测温度的。
作者: 2545889167    时间: 2020-3-31 11:08
595953427@qq 发表于 2020-3-30 22:17
我说的不是所有单片机都支持高速的波特率,不是说不支持任意设置波特率。
基本上所有单片机只要在上限波 ...

38400不是很简单么?一般不读跑115200?
作者: yzx0201    时间: 2020-3-31 12:55
你这非人类的操作,让我无尽的佩服:lol:
作者: cxw0102    时间: 2020-4-2 21:18
la45088d1 发表于 2020-3-30 21:47
你试试呗,能做到DS18B20的精度?
人家器件卖4-5RMB一个,如果比不过几毛钱的NTC,人家早就倒闭了。
连ST ...

看清楚,他不是楼主。
作者: liccil    时间: 2020-4-3 09:38
cxw0102 发表于 2020-4-2 21:18
看清楚,他不是楼主。

看来默认头像有风险哈
作者: cmheia    时间: 2020-4-6 17:57
串口怼18B20,老话题了。
美信官网就有一篇2002年的文章说明原理,
gayhub上有C代码,
MicroPython直接内置。


作者: 292861772    时间: 2020-4-15 16:58
595953427@qq 发表于 2020-3-30 22:17
我说的不是所有单片机都支持高速的波特率,不是说不支持任意设置波特率。
基本上所有单片机只要在上限波 ...

工业上的测温环境大多用的18B20,例如隧道,煤炭,冷库。单总线一下接几十个,施工简单。我们有这个产品
作者: zhangxy5277    时间: 2020-4-16 08:47
这tm是个人才,
还是ch551这样的芯片香
作者: 袁博1    时间: 2020-4-17 17:41
       工业温度采集用的最多的并不是18B20,用的最多的是PT1000的传感器,输出4-20mA。当然,讲究点的测温也会用AD590这种半导体温度传感器,工业上比较恶劣的环境,用18B20这种数字式传感器,一个干扰过来全完蛋。
       还有就是不要看不起热敏电阻,至少目前电子温度计大多数都用的是热敏电阻,甚至是体温计也是。校准后的热敏电阻,在室温范围内能做到很好的精度。高精度ADC配合查表法,热敏电阻可以做出很高的精度。

作者: c106czs    时间: 2020-5-16 20:51
厉害厉害,这样也行!
作者: 40560335    时间: 2020-5-16 22:19
人艰不拆了 发表于 2020-3-30 17:05
哈哈,自己跟自己过不去啊

我还见过更跟自己过不去的,使用手摸液晶屏IO的方式去控制LCD1602显示东西。。。
作者: lzkk1    时间: 2020-9-15 10:07
用串口调试助手,怎么发送什么就收到什么?小白感兴趣想玩一下,请楼主指点下如何收到温度数据
作者: 大道必成    时间: 2020-10-3 10:31
神仙操作
作者: hui223    时间: 2020-10-14 11:55
放上程序 讓大家試試呀

作者: 871881392    时间: 2020-10-17 16:53
工业温度采集用的最多的并不是18B20,用的最多的是PT1000的传感器,输出4-20mA。当然,讲究点的测温也会用AD590这种半导体温度传感器,工业上比较恶劣的环境,用18B20这种数字式传感器,一个干扰过来全完蛋。
       还有就是不要看不起热敏电阻,至少目前电子温度计大多数都用的是热敏电阻,甚至是体温计也是。校准后的热敏电阻,在室温范围内能做到很好的精度。高精度ADC配合查表法,热敏电阻可以做出很高的精度。
作者: leixingmin    时间: 2020-10-19 12:44
牛,触类旁通
作者: wave    时间: 2020-10-19 14:19
这个还真有人干过,2010年的时候折腾智能手机保护板做电量计的时候看到的:
https://www.codeproject.com/Articles/58958/1-Wire-USB-Interface

美信也有过这种介绍。
[attach]938635[/attach]

作者: oreisme    时间: 2020-10-20 19:15
技术上行得通,所以我选择花8毛钱上个MCU。:lol:
作者: lzkk1    时间: 2021-9-27 00:20
谁教教我,用串口调试助手,怎么发送什么就收到什么?请指点下如何收到温度数据

[attach]1287297[/attach]

作者: liccil    时间: 2021-9-27 08:19
lzkk1 发表于 2021-9-27 00:20
谁教教我,用串口调试助手,怎么发送什么就收到什么?请指点下如何收到温度数据

光发0xFF读不回来的 需要像正常读取DS18B20那么操作

1.38400波特率 发送 0x00 0xFF(初始化)

2.115200波特率 发送 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF(0xCC 跳过ROM)

3.115200波特率 发送 0x00 0x00 0xFF 0x00 0x00 0x00 0xFF 0x00 (0x44 转换温度)

4.38400波特率 发送0x00 0xFF(初始化)

5.115200波特率 发送 0x00 0x00 0xFF 0xFF 0x00 0x00 0xFF 0xFF(0xCC 跳过ROM)

6.115200波特率 发送 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0x00 0xFF (0xBE 读温度)

7.115200波特率 发送16个0xFF 看回读的数

我这返回的是 FF FC FF FF FF FF FF FC FF FC FC FC FC FC FC FC

转换一下 是 1011111010000000
LSB在前 因此要颠倒一下 再转换成十进制是381

381*0.0625=23.8125℃




作者: lzkk1    时间: 2021-9-27 17:48
liccil 发表于 2021-9-27 08:19
光发0xFF读不回来的 需要像正常读取DS18B20那么操作

1.38400波特率 发送 0x00 0xFF(初始化)

谢谢指点,我试试看

作者: safijadds    时间: 2021-9-27 21:37
有点意思,学习了
作者: devcang    时间: 2021-9-28 10:21
kindzhon 发表于 2020-3-30 17:04
牛啊,来个Python程序是不是更方便?画个小电路图呗。

下边是Python的示范(未包括转换结果)


import serial #导入模块
import serial.tools.list_ports
timex=5
def test18B20(portx):
    '''
    参数是串口名,COMx
    timex是超时设置全局变量
    '''
    global timex
    if None==portx: return
    uart=None
    try:
        #端口,GNU/Linux上的 /dev/ttyUSB0 等 或 Windows上的 COM3 等
        #波特率,标准值之一:50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,19200,38400,57600,115200
        #timeout 超时设置,None:永远等待操作,0为立即返回请求结果,其他值为等待超时时间(单位为秒)
        # 打开串口,并得到串口对象
        uart=serial.Serial(portx, 38400, timeout=timex)
        print("Serial Information:", uart)
        uart.write(b'00ff')
        uart.baudrate=115200  #库会自己重设置
        uart.write(b'0000ffff0000ffff')
        uart.write(b'0000ff000000ff00')
        uart.baudrate=38400  #38400
        uart.write(b'00ff')
        uart.baudrate=115200  #库会自己重设置
        uart.write(b'0000ffff0000ffff')
        uart.write(b'00ffffffff0000ff')
        uart.write(b'ffffffffffffffffffffffffffffffff')        
        print(uart.in_waiting)#获取输入缓冲区的剩余字节数
        print("---------------")
    except Exception as ex:
        print(ex)

    if None!=uart: uart.close()#关闭串口





#手头没有18B20,所以只是读回来,没有转换结果






作者: devcang    时间: 2021-9-28 10:22
devcang 发表于 2021-9-28 10:21
下边是Python的示范(未包括转换结果)

pip3 install pyserial==3.4

库安装
作者: hamilovee    时间: 2021-9-29 15:35
学习学习!
作者: wjhhhhh    时间: 2021-9-29 20:04
        实际工作中买元器件的花费不算多,施工时才能看到,用18B20一根线缆出去几十个测点都解决了,用PT100或其他元件,每个点放一根线缆,麻烦极了,各种费用急剧上升!  只在开发板上调试的很难体会。
       大于摄氏100多的 超过18B20极限 没有办法无可奈何,不在此列。
作者: kindzhon    时间: 2021-10-3 16:21
devcang 发表于 2021-9-28 10:21
下边是Python的示范(未包括转换结果)

:victory::victory:
作者: xueyeteng    时间: 2022-11-5 15:35
liccil 发表于 2021-9-27 08:19
光发0xFF读不回来的 需要像正常读取DS18B20那么操作

1.38400波特率 发送 0x00 0xFF(初始化)

楼主,这个创意很好。
正好我手头有个CH341A USB转串口的小板,按你的这个硬件接线接好了。调试的时候发现可以读回温度,但始终是初始值85℃。后来发现在发送0x44转换温度命令后串口会额外收到0x80 0x00两个数据,使用0xB4读供电模式回读的值是0xFC,也就是0 显示是寄生供电。但我确认硬件VDD接的是5V电压。这个是什么原因呢?
作者: xueyeteng    时间: 2022-11-5 17:36
xueyeteng 发表于 2022-11-5 15:35
楼主,这个创意很好。
正好我手头有个CH341A USB转串口的小板,按你的这个硬件接线接好了。调试的时候发 ...

换了一个DS18B20好了。不过原来的那个换到单片机系统里使用也好使,不知道到底因为啥不好用。
作者: 595953427@qq    时间: 2022-11-6 09:59
lzkk1 发表于 2021-9-27 00:20
谁教教我,用串口调试助手,怎么发送什么就收到什么?请指点下如何收到温度数据



楼主用的不是串口助手,是自己写的上位机软件
作者: wwb2002    时间: 2022-11-6 11:36
市面流行的usb串口好像都有gpio口,是不是方便一些
作者: hsccsh    时间: 2022-11-9 19:16
这样也可以吗?
作者: dz20062008    时间: 2022-11-10 15:55
干的漂亮,这绝对是高手
作者: dengdai510    时间: 2022-11-10 19:48
楼主,上位机软件贡献一下,上位机有曲线就更完美了
作者: aspirine520    时间: 2022-11-11 10:56
liccil 发表于 2021-9-27 08:19
光发0xFF读不回来的 需要像正常读取DS18B20那么操作

1.38400波特率 发送 0x00 0xFF(初始化)

老哥 你这python程序不就出来嘛
作者: zhxzhx    时间: 2022-11-13 21:07
la45088d1 发表于 2020-3-30 21:47
你试试呗,能做到DS18B20的精度?
人家器件卖4-5RMB一个,如果比不过几毛钱的NTC,人家早就倒闭了。
连ST ...

NTC 的精度可比 DS18B20 高 多了,校准好的 NTC 0.01℃都不是问题

作者: bg4jkl    时间: 2022-11-17 09:00
万能的串口,可惜现代的电脑都取消了串口
作者: xueyeteng    时间: 2022-11-24 10:15
bg4jkl 发表于 2022-11-17 09:00
万能的串口,可惜现代的电脑都取消了串口

楼主用的也不是标准的串口,而是USB转串口的模块。标准串口可能还要进行电平转换




欢迎光临 数码之家 (https://www.mydigit.cn/) Powered by Discuz! X3.4