我正在尝试使用GPIO引脚在微控制器上编写软件UART。这是为了在项目上临时添加一个UART通道,直到我们实现使用带有更多UART端口的uC的新设计。
我遇到的困难是正确检测串行流中的起始位。流的源是外部的,不需要担心我的设备何时开机。因此,很有可能我的设备将打开电源并开始在字节传输的中间看到数据位。毫无疑问,这将导致我的软件UART读取错误的值,因为它无法分辨起始位与任何其他高到低转换之间的差异。
这是UART通道不可避免的问题吗?还是uC制造商在其硬件UART中使用了一些巧妙的技巧?
我正在尝试使用GPIO引脚在微控制器上编写软件UART。这是为了在项目上临时添加一个UART通道,直到我们实现使用带有更多UART端口的uC的新设计。
我遇到的困难是正确检测串行流中的起始位。流的源是外部的,不需要担心我的设备何时开机。因此,很有可能我的设备将打开电源并开始在字节传输的中间看到数据位。毫无疑问,这将导致我的软件UART读取错误的值,因为它无法分辨起始位与任何其他高到低转换之间的差异。
这是UART通道不可避免的问题吗?还是uC制造商在其硬件UART中使用了一些巧妙的技巧?
Answers:
如果您使用容易从数据流其余部分中识别出的停止位长度(例如1.5位时间),那么应该很容易开始接收中间传输。但是,这是以增加开销为代价的。随着停止位长度的增加,总可用数据吞吐量将受到影响。
如果您不使用过多的总线,并且经常在帧之间留有间隙,那么可能只是等待这些间隙之一发生,然后选择第一个高保真传输作为开始您的事情。下一个起始位。
请记住,数据位的数量和帧大小应该是可预测的,因此,即使您使用的是总线容量的100%,并且停止位只有一个位时间,您仍然应该能够找到如果您收集到足够的帧,则从起始位开始。保证每个帧都具有高低过渡。停止位总是高位。起始位始终为低。假设数据是随机的(或足够随机的),则可以执行以下操作:创建一个与帧大小相同的缓冲区,设置其中的每一位,然后继续收集帧并将其与该缓冲区进行“与”运算,直到缓冲区只有1个。设置。这是您的止损位。之后的那一个是您的起点。瞧!找到了
如果使用奇偶校验位,另一种选择是获取两个帧的数据,选择第一个低位作为起始位,然后计算校验和并与奇偶校验位进行比较。如果匹配,则您(可能)已找到起始位。如果不是,请选择下一个低位并重复直到获得良好的校验和。如果您在两帧数据中找不到作为有效起始位签出的数据,则表明您的数据已损坏,您将需要再捕获两帧。