检测软件UART中的起始位


9

我正在尝试使用GPIO引脚在微控制器上编写软件UART。这是为了在项目上临时添加一个UART通道,直到我们实现使用带有更多UART端口的uC的新设计。

我遇到的困难是正确检测串行流中的起始位。流的源是外部的,不需要担心我的设备何时开机。因此,很有可能我的设备将打开电源并开始在字节传输的中间看到数据位。毫无疑问,这将导致我的软件UART读取错误的值,因为它无法分辨起始位与任何其他高到低转换之间的差异。

这是UART通道不可避免的问题吗?还是uC制造商在其硬件UART中使用了一些巧妙的技巧?


好问题。您的外部设备是否持续发送字符?如果不是,则应检查起始位和停止位是否对齐。并且如果两者之间的数据与您的支票(总和/位)匹配?
Paul

您可以让外部UART流发送前同步码吗?像特殊数据流一样,它指示有流与起始位不同吗?如果您可以这样做,则可以确定是否在传输过程中加电时数据是否错误。
Funkyguy 2015年

1
如果串行流没有足够长的空闲时间-您的艺术就不可能从中恢复。如果您未在预期的地方收到“停止”位,则可以采用部分解决方案。然后,您将能够重置状态并重试。
尤金(Eugene Sh)。

1
您不需要特殊的序言...只是偶尔休息超过一个字符(包括开始,停止位)。或者,连续超过10个停止位,这是同一件事。
Brian Drummond

2
@Fuaze,外部设备连续发送一长串字符,但偶尔会空闲。最坏的情况是,我只能忽略输入,直到第一次空闲。
丹·拉克斯

Answers:


5

如果您使用容易从数据流其余部分中识别出的停止位长度(例如1.5位时间),那么应该很容易开始接收中间传输。但是,这是以增加开销为代价的。随着停止位长度的增加,总可用数据吞吐量将受到影响。

如果您不使用过多的总线,并且经常在帧之间留有间隙,那么可能只是等待这些间隙之一发生,然后选择第一个高保真传输作为开始您的事情。下一个起始位。

请记住,数据位的数量和帧大小应该是可预测的,因此,即使您使用的是总线容量的100%,并且停止位只有一个位时间,您仍然应该能够找到如果您收集到足够的帧,则从起始位开始。保证每个帧都具有高低过渡。停止位总是高位。起始位始终为低。假设数据是随机的(或足够随机的),则可以执行以下操作:创建一个与帧大小相同的缓冲区,设置其中的每一位,然后继续收集帧并将其与该缓冲区进行“与”运算,直到缓冲区只有1个。设置。这是您的止损位。之后的那一个是您的起点。瞧!找到了

如果使用奇偶校验位,另一种选择是获取两个帧的数据,选择第一个低位作为起始位,然后计算校验和并与奇偶校验位进行比较。如果匹配,则您(可能)已找到起始位。如果不是,请选择下一个低位并重复直到获得良好的校验和。如果您在两帧数据中找不到作为有效起始位签出的数据,则表明您的数据已损坏,您将需要再捕获两帧。


整齐的想法将AND帧合并在一起,直到只有起始位和停止位幸存下来。对于我的特定应用程序来说,这将是过多的开销,但是仍然很聪明。
丹·拉克斯

如果外部设备是OP无法控制的(他在对该问题的较早评论中已经指出),则他不太可能更改停止位的长度。
tcrosley 2015年

在我开始撰写此答案时尚未发表评论。但是,在停止位长度固定的情况下,我列出的其他三个选项仍然适用。
Funk博士2015年

3

硬件UART具有相同的问题。但这通常是短期内解决问题的方法。在每个帧的末尾,检查停止位,如果停止位不高,则丢弃该帧并等待下一个从高到低的过渡。假设来自源的数据不完全是病态的(例如,长字符串“ UUUU”或ASCII 0x55),则UART最终将“遍历”自身到真正的起始位。


1

假设传输为8N1。

您必须等待连续9个高或低位的字符串。

如果为高,则表示数据中的空闲间隙或0xFF字符和STOP位,
或者
为START时,则表示NULL 0x00字符。

这些条件之一将允许重新同步。

要加快速度:如果您知道数据中不可能包含的某些字符,则可以针对每个位重复(事实之后)解析传入的数据,并且如果获得了一系列7个无用的字符(高位设置,低位设置)大小写,控制代码,标点符号或其他任何字符)后跟有效字符,则可以确定您已重新同步。

当您使用内置的UART外设时,您将遇到类似的问题,无法进行按位评估,并且还必须记住将所有成帧错误位等(尤其是在上电时)复位。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.