如何有效解码非标准串行信号

电器工程 微控制器 USB 串行 嵌入式 设计
2022-01-29 09:18:07

我是一个研究团队的本科生成员,该团队正在从事一个涉及射频传输 ASIC 及其最终应将数据发送到 PC 的无线接收器的项目。

接收器输出快速、连续、异步、非标准的串行信号(即不是 SPI、I2C、UART 等),所以我的工作是编写微控制器软件将接收器连接到计算机。目前我的方法是使用边缘触发的中断将数据放置在循环缓冲区中,并在主循环中进行整个逐位解码过程。微控制器必须同时使用 USB(虚拟 com 端口)将此数据输出到计算机。

这是我遇到的一个问题,也是我期待的一个问题:

  1. 即使使用功能强大的 72 MHz ARM Cortex M3 处理器,我也无法足够快地处理缓冲数据。比特率为 400 Kbps (2.5 us / bit)。作为参考,每个比特只剩下 180 个周期(包括解码和 ISR,它有大约 30 个周期的开销哎哟!)。MCU 还必须处理它在主循环中轮询的许多其他任务。

  2. USB 虚拟 com 端口驱动程序也是基于中断的。这让我几乎可以肯定,驱动程序最终会让处理器中断很长时间,以至于错过了可以传输位的 2.5 微秒(180 个周期)窗口。我不确定通常如何解决这样的中断冲突/竞赛。

所以问题很简单,可以做些什么来解决这些问题,或者这根本不是正确的方法?我也愿意考虑较少以软件为中心的方法。例如,使用带有某种硬件状态机的专用 USB 芯片进行解码,但这是一个陌生的领域。

4个回答

您可以使用 FPGA 而不是微控制器来解码和缓冲无线数据流。然后使用 ARM 处理器刷新 FPGA 缓冲区(例如使用 SPI 接口)并将内容发送到 USB Comm 端口。这是可行的,但是只要您能够经常维护它以保证其硬件缓冲区不会溢出(或者您可以在协议的更高级别处理丢弃的数据),FPGA 应该能够轻松跟上)。

简单:使用PSoC5 微控制器

PSoC

您拥有微控制器的所有易用性,加上它包含一个 CPLD,因此您可以在 Verilog 中编写自己的硬件外围设备。只需在 verilog 中编写您的串行数据解码器,然后使用 DMA 将其流式传输到 USB 端口。

同时,强大的 32 位 ARM 内核可以旋转其 Thumb 指令。

另一个答案:停止使用中断。

人们太容易跳到使用中断。就个人而言,我很少使用它们,因为正如您所发现的那样,它们实际上浪费了很多时间。

通常可以编写一个主循环,该循环如此快速地轮询所有内容,以至于它的延迟在规范范围内,并且浪费的时间很少。

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

循环中的某些事情可能比其他事情发生得更频繁。例如,也许传入的位,在这种情况下,会添加更多的这些测试,以便更多的处理器专用于该任务。

loop
{
    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (serial_byte_ready)
    {
        // decode serial data
    }

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (enough_serial_bytes_available)
    {
        // more decoding
    }        

    if (serial_bit_ready)
    {
        // shift serial bit into a byte
    }

    if (usb_queue_not_empty)
    {
        // handle USB data
    }        
}

对于某些事件,这种方法的延迟可能太高。例如,您可能需要一个非常准确定时的事件。在这种情况下,让该事件中断,并让其他所有内容都在循环中。

我认为你有一个经典的工程选择:快速、便宜、有效:选择两个。

@vicatcu 的解决方案当然是一个不错的解决方案,但如果您不能或不会为其添加更多硬件(这包括更快的处理器),那么您必须做出选择。如果此串行链路是最重要的,那么您应该坐在 ISR 中,直到收集完所有位。每位 180 条指令实际上一点也不差,但不要试图做所有事情。当您检测到传输开始时,旋转直到传输完成。将结果填充到 FIFO 中,然后恢复正常处理。

您没有说每次传输有多长时间,但如果它们很短且突发,这将是一个可行的解决方案。我敢打赌,您的虚拟 COM 端口实现也有一些硬件缓冲,因此它的“滞后”中断服务不应该带来太多麻烦。至于 MCU 需要做的其他事情……您需要做出一些设计决策。