SPI超远距离长线通信方法,以及在SPI显示器上的应用

2019-12-11 18:26发布

本帖最后由 neqee 于 2018-12-3 10:43 编辑

这篇文章也许现在对你没什么用,但以后需要的时候希望能帮到你.
之前在论坛也有很多人讨论过长距离通信的最佳方案,希望能找到一种传输距离几十米,速度不要太慢,但又不需要太快,稳定可靠又简单的通信方法,我个人认为非SPI莫属,不过需要将SPI转换成差分信号传输才能做到稳定可靠的超长距离通信。相比之下,RS232、RS485、Can速度太慢, I2C、UART速度不行距离更不行,Ethernet、USB应用复杂成本高而且不够稳定可靠。
SPI作为同步、单向通信接口,时序严谨,支持推挽驱动,支持驱动缓冲,就算不转换为差分传输,如果布线和对地阻抗做地好的话,比如使用灰排线并且每根信号用地间隔,18MHz时钟频率,一般环境下,2米距离通信完全没有问题;但如果是强干扰环境,超远距离通信,就必须考虑将TTL信号转为差分传输,而常用、简单、高速、低成本的差分传输是LVDS:
image013.jpg (75.74 KB, 下载次数: 0) 下载附件 2018-12-3 10:29 上传

SPI作为同步、单向、推挽串行高速接口,它的扩展性和可转换性是非常强大的,我在想,以后工控设备主机是不是可以像串口DB9那样配备一个这样的"DVI接口"呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
46条回答
jianfengxixi
1楼-- · 2019-12-14 06:44
长距离时钟和数据分开是不稳定的,楼主可以参考一下同步编码的知识,时钟和数据编码到一根差分线中,这样就收发各一对差分线,成本几块钱加个cpld就行了
focus_hai
2楼-- · 2019-12-14 09:43
测井仪器
neqee
3楼-- · 2019-12-14 15:31
 精彩回答 2  元偷偷看……
dukelec
4楼-- · 2019-12-14 15:57
本帖最后由 dukelec 于 2018-12-11 12:53 编辑
neqee 发表于 2018-12-11 09:10
原来CDBUS是你自己发明的总线,厉害!
请问下是怎样实现10、20、30MHz的RS485异步信号采集?IP核里面校验 ...


跟 MCU 采样 UART 相似,都是用更高的频率来采样:
STM32 一般是固定 16x 倍频采样,部分型号支持 8x 倍频采样,不过该频率是独立产生,波特率生成计数器不会同步 开始位 的下降沿,优点是方便,节省资源。
cdbus_ip 采用的是动态倍频采样,可以指定任意大于等于 4x 的倍频采样,波特率生成计数器会在 开始位 的下降沿清零同步,优点是波特率计算方便、速率高、各节点同步性好。
(cdctl-b 主频默认是 40MHz,÷4x = 10Mbps,÷5x = 8Mbps 以此类推。)

固定倍频采样还方便多次采样,譬如 STM32 固定在中间的位置采样 3 次,以判断数据是否受到干扰;
而带完整协议的 cdbus_ip 每个 bit 只采样 1 次,最后通过 CRC 字段校验整个帧。

默认的校验机制你可以参考 cdbus_ip 文档中的动图,发送方 MCU 把不含 CRC 的一帧数据写入 cdbus_ip, cdbus_ip 在发送数据的时候计算 CRC 并在一帧的最后两个字节把生成的 CRC 发送出去;
接收方的 cdbus_ip 在接收包含 CRC 的完整一帧数据后,判断 CRC 是否正确,正确的话通知用户有新的待读数据,错误的话会置位接收错误位,告诉用户数据出错。
(只有在完整收到两个字节及以上的错误数据才可以置位接收错误位,因为 CDBUS 协议第二个字节是目的地址,至少要接收到它。)
(如果启用出错也保存的模式,收到的错误数据依然可以保存下来被 MCU 读取分析。)

如果 cdbus_ip 所在的器件离 MCU 距离较远,担心 SPI 端数据出错的话,可以启用用户 CRC 模式,这种方式下,发送方 MCU 需要把包含 CRC 在内的完整的一帧数据写入 cdbus_ip,
如果 SPI 传输时数据出错,该帧依然会发送出去,只不过接收方会检测到 CRC 错误,从而不会使接收端 MCU 误操作。

CRC 校验出错不会硬件自动重发,需要用户程序自行处理。(另有可选的上层 CDNET 协议栈可以在出错超时后负责重传。)

单片机不用理会总线状态,只要把一帧数据写入 cdbus_ip, 之后cdbus_ip 会自动尝试发送数据,发送完成之后,发送帧所在的内存页面会被硬件释放,
如果有更多数据等待启动发送,则可以使能对应的中断,cdbus_ip 有一个中断脚接到 MCU, 在中断处理程序中启动 SPI 的 DMA 操作,包括读取状态、搬运数据、启动发送等。
具体可以参考 DMA 操作 CDCTL SPI 的库代码:https://github.com/dukelec/cdnet/blob/master/dev/cdctl_it.c
(简单应用的话可以不用中断和 DMA, 在主循环中通过 SPI 访问 cdbus_ip 即可。)
(发送数据的内存页面是乒乓操作,下一帧的数据可以提前写入 cdbus_ip, 等待上一帧发送完毕,直接启动下一帧即可。)

已启动发送的帧,cdbus_ip 会不停的尝试发送,直到成功发送、发送错误、用户手动取消发送。
发送错误只存在 CDBUS-A 使能仲裁的模式下,如果首字节仲裁字段发送出去的数据为 0 而读回来的数据为 1 则置发送错误位并取消发送。
仲裁模式下,发生了仲裁,且因为自身优先级比其它节点低而暂缓发送,会置位冲突检测标志,但后续依然会不停的重试发送。
ak2368
5楼-- · 2019-12-14 20:54
感谢分享,收藏了!
huchunlei
6楼-- · 2019-12-14 23:45
非常好的经验,谢谢分享!

一周热门 更多>