写在前面:
时间: 2024_04_09, 需求为制作UART与SDI-12协议的转换硬件,本文参考了Jolon Behrent在github上的硬件设计,并做了翻译及仿真,后续会补充软件的通讯实现。原文链接为:
1.SDI-12 协议与UART协议转换的硬件仿真
1.1 前情提要
如果你了解此协议,请直接绕道仿真实现,如果并不了解SDI-12协议到底是什么,我来做一个大概笼统的介绍。
1.1.1 什么是SDI-12
The SDI-12 (serial digial interface at 1200 baud) protocol was first released in 1988 designed by the US Geological Surbey’s Hydrologic Instrumentation Facility and some private companies. The SDI-12 specification is maintained by the SDI-12 Support group.
SDI-12 is a protocol often used for environmental monitoring due to it’s low power operation. It is intended for use in systems that are battery powered, low cost, and require a multiple sensors attached to one cable. The SDI-12 protocol supports at least 10 sensors each with a cable length of 60 metres (200 feet). One key reason for using SDI-12 sensors is that all SDI-12 sensors follow the protocol in the exact same way (barring slight differences between versions), so a variety of sensors can be used with little to no changes to the system.
SDI-12(1200波特率串行数字接口)协议最早在1988年由美国地质调查局的水文仪器设施和一些私营公司设计发布。SDI-12规范由SDI-12支持组维护。
SDI-12是一种常用于环境监测的协议,因其低功耗操作而受到青睐。它旨在用于电池供电、低成本,并需要将多个传感器连接到一根电缆的系统中。SDI-12协议支持至少10个传感器,每个传感器的电缆长度为60米(200英尺)。使用SDI-12传感器的一个关键原因是所有SDI-12传感器都以完全相同的方式遵循协议(除了版本之间的轻微差异),因此可以在系统中使用各种传感器,几乎不需要对系统进行任何更改。
1.1.2 SDI-12协议
SDI-12 的具体协议内容见下边的网址。
http://www.sdi-12.org/specification.phpwww.sdi-12.org/specification.php
接口介绍:
SDI-12协议采用三条线来传输数据,分别为:(12volt line)电源线,(ground line)地线,(serial data line)串行数据线,下图展示了SDI-12传输的线路连接示意图。12V电源线必须保持在9.6V及16V之间。
左侧为SDI-12 数据记录设备(本项目为STM32系列)右侧为SDI-12 传感器
串行数据线是一条双通道数据传输线(也就是说SDI-12 是半双工协议),使用反转逻辑电平(也是就高电平表示0而低电平表示1)。下表展现了SDI-12的电平状态:
- 状态 二进制表示(这边我也忘了这玩意叫什么) 电压范围(蛮重要的)
- 标志 1 -0.5-1.0V
- 空置 0 3.5-5.5V
- 转换 未定义(这边就是高低电平的中间态) 1.0-3.5V
通讯过程:
SDI-12 协议规定,主从双方的通讯在信号传输线上通过可打印的ASCLL码进行数据的传输。传输范围为16进制的20到7E。此外,传感器接到主方的询问之后的回复信号以\r\n结尾。CRC码可能使用不可打印的ASCLL码。通过高容量二进制命令返回的数据包。关于什么是可打印的ASCLL码,去看一眼ASCLL码表一目了然。关于什么是高容量的二进制命令,我还没遇到,遇到再补充吧。
传输的每一个字符被7个数据位代表,完整的数据包结构为:1起始位,7数据位,1奇偶校验位,1停止位。且数据传输的第一个字符一定要是传感器(从设备)地址。默认为0(不知道就?),也可以是0-9,一些传感器还支持A-Z和a-z。具体的各种命令看传感器手册,或者上边的pdf里有详细的介绍。主设备的结束一定要以!结尾。比如我要查询从设备地址就可以发送?!,从设备会返回设备的地址回来。
时序:
前边介绍了SDI-12 之所以叫这个名字是因为他的波特率固定为1200,算一下可以得到每一位的时间约为0.833ms,所有的电平时序都有一个±0.4ms(约半位的时间)的阈值,但是一个信息的截止位和下一个信息的开启位之间要保持超过1.66ms,也就是两位时间。
break时间为唤醒,唤醒后主设备发送命令,从设备做出回复。完成一次通讯
注意:这个图里的是电平状态(voltage level)而不是逻辑状态(binary states)。
主设备(data recorder)通过将数据线设置为空闲状态(5 V)至少 12 毫秒来发送(break)唤醒信号。传感器将不会识别少于 6.5 毫秒的唤醒信号,并始终识别大于 12 毫秒的唤醒信号。 主设备在 8.33 毫秒(10位数据)内发送标记信号(0 V)(等待起始位的到来)。此时间不能超过 100 毫秒,否则传感器将进入休眠状态(等时间太长,传感器就会睡着,需要再次唤醒)。 主设备发送命令给传感器。 数据记录仪在最后一个停止位结束后的 7.5 毫秒内放弃对数据线的控制,并等待接收数据。一次通讯结束。如果你换传感器了,那要喊他起来,或者太久没有信号在数据线上(超过87ms),此刻传感器又眯住了,还得把他喊醒。
重试(retries):
主设备一定要支持重试,如果发生了以下事情,主设备就要多试一试。
- 传感器(从设备)在收到命令后的16.67ms(20位)后不搭理。
- (在接到从设备起始位后的8.33ms之内电平全低)8.33 ms of marking on the data line, after receiving the start bit of the response。这里我感觉是接收到从设备起始位但并未接收到从设备的停止位。
- 无效回复
第一次的重试可以安排到上个命令停止位的16.67ms到87ms之间,太早可能人家刚要搭理,与主设备信号冲突,太晚从设备又睡着了还得喊一下。如果在至少两次重试后(其中一次重试在中断结束后超过 100 毫秒),仍未收到有效响应,则应将唤醒和重试的整个序列重复两次。(如果你没有看懂没有关系,我也没有看懂,需要重试的时候再来看)。
1.2电路实现
建议去看看原作者的文章,非常清晰,我们的目标是将这些信号更广泛地传播,并为不同微控制器提供备选方案。
标准的一个实现如下图所示:
第一眼看这图可能有点懵,DIR是连接主设备的一个控制电平,因为UART是全双工串行通讯,而SDI-12为半双工串行通讯,所以需要DIR来作为开关来使能三态缓冲器,从而进行数据收发的转换,Fout作为唤醒信号的输出控制信号。中间的2-channel tri-state buffer为三态缓冲器,原作者因为元器件库没有三态缓冲器的仿真从而自制了一个三台缓冲器的模型。而右边的SDI-12 Receive,Send虽然在图上是两条线通过一个开关控制但是实际电路里是单条的数据线,仿真的需要因而做出了开关。
就在作者写文章的后一天,原作者更新了文章,给出了新的原理图,一目了然。
不过,他也提出了此原理图的三个问题,第一电平没有进行反转,UART与SDI-12的电平刚好相反,第二如果你使用5V的主控那此图没什么问题,而如果你使用的是3.3V的主控,那3.3V的电压在SDI-12中却被识别为转换态而不是1.第三,唤醒的信号无法通过Tx来发出,不过前一张图的Fout恰好可以解决这个问题。此外由于本项目使用的为3.3V的STM32所以,第二个问题在后边也会遇到,我们后边仿真时再做解决。
1.3电路仿真
好好好!终于来到了仿真阶段,或者你之前非常了解SDI-12 直接跳到了这里,赶紧开始。
我们采用了Ti公司的三款芯片,非门CD74HC04,三态缓冲器SN74AHCT125,与门SN74HC08。 我们前边提到过,由于SDI-12 并不能识别3.3V电平究竟是高电平还是低电平,所以我们要将3.3V的电平抬升到5V(左右)以保证SDI-12可以正确识别高电平。这个工作我们通过上边的三个芯片来实现,我们来简单的看看其中的非门芯片的数据手册。在6.3节,推荐运行状态表中,Ti公司给出了供电电压(Vcc)分别为2V,4.5V,6V时的最小可以被识别的高电平已经最大可以被识别的低电平。如果直接用4.5V倒是可以准确识别,但是5V和3.3V是什么情况就不怎么清楚(我们之后仿真)。不过我们发现当输入为低电平时,输出为Vcc。恰好我们需要电平反转以及电平的抬升。其他的两款芯片同样也有这个表,有兴趣可以去看看。
闲言少叙,直接开始仿真,在Ni multisim中导入非门CD74HC04,三态缓冲器SN74AHCT125,与门SN74HC08。搭建原理图如下图所示:
SWG1,2为一个字符发生器,简单来说就是产生串行序列信号(例如:010111),而监测端为示波器。
两个开关用来控制是发送还是接收,你可以对比这个图与上方的原理图,聪明如你一定能看得懂。通过将部分门电路的电平改为3.3V供电而部分门电路的电平改为5V供电。从而可以实现逻辑转换,电平爬升。
仿真的效果如下图所示:
可以看到,已经完成了电平的转换与爬升,左侧1为3.3V而右侧的1为5V,满足双方通讯的逻辑判断
如果你对如何仿真好奇,请在评论区直接问我。我会私信仿真文件给你,如何导入这三个原件,如果有人好奇,我可以出个教程。
写在最后
感谢原作者Jolon的贡献,开源声明:
MIT License
Copyright © 2024 wushuai xue
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SDI-12 for Arduino 示例程序下载链接:
https://download.csdn.net/download/ybj520lcx/89338789?spm=1001.2014.3001.5503