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


11

我是研究团队的一名本科生,从事一个涉及RF传输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芯片进行解码,但这并不熟悉。


我不得不说,我很少看到我喜欢快速回答的许多建议能够很好地回答您的问题。我想了解更多有关数据突发的信息。它们是突发性的,突然的全速运行,然后是数据量较低的时段,还是您可能会连续使用较长时间的数据呢?
2012年

只要ASIC通电,它就会发送连续的数据流。一点也不爆裂。这是带有计算机读数的实时医学传感应用程序。见过心电图吗?
Keegan Jay

这里有很多很棒的答案。我看到了涉及中断更改的解决方案与涉及专用硬件/数字逻辑的解决方案之间的清晰区分。我熟悉但尚未体验过的FPGA和Verilog之类的东西,因此这意味着它们必须长期保存。在短期@rocketmagnets中,使用较少中断的方法就可以了。我非常喜欢将琐碎的任务专门用于数字逻辑并节省ARM进行真正计算的优雅。将来,ARM的功能将用于无线串行数据的分析和过滤。
Keegan Jay

信号是同步还是异步?
markrages 2012年

异步。4个起始位,10个数据位,2个停止位。由于正在传输的ASIC的性质,芯片之间的HI和LO时间差异很大。我已经写了一个算法来推断波特率。
Keegan Jay

Answers:


5

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

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

通常有可能编写一个主循环,以如此快的速度轮询所有内容,这是等待时间在规范范围内,而浪费的时间却很少。

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
    }        
}

对于某些事件,此方法的延迟可能会过高。例如,您可能需要一个非常准确的定时事件。在这种情况下,请在中断时发生该事件,然后将其他所有事件都置于循环中。


我比其他Rocketmagnet人更喜欢您的答案。Rocketmagnet建议您不要使用更多的硬件,更快的硬件,而是建议更多的事情:做得更少,更好,更简单。

好的,我已经看到很多情况下中断使解决方案好得多。它们做的很出色,允许结构良好的代码,低延迟和许多其他优点,但是我必须在这里同意您的观点。看起来过程是如此紧张,1控制器可能需要尽全力处理串行流。数字前端听起来对我来说很理想,但是很多时候您在学校项目中都拥有一些微型且没有FPGA的情况下,我可能会先专门为它处理一个微型,然后再尝试安装一个FPGA来代替它。成本。
Kortuk 2012年

在短期内,这可能是我将采用的解决方案。我希望避免这种情况,因为它涉及大量重写现有的串行驱动程序,但这是一个优雅的解决方案,在我的能力范围之内就是很短的时间。
Keegan Jay

1
@JayKeegan-是的,这可能是最快的解决方案。PSoC和FPGA可能是下一个项目的方法。
Rocketmagnet

6

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


从长远来看,这可能是一个很好的解决方案。我希望除了软件解决方案外,还能收到很多数字逻辑/硬件解决方案,因为现在我有借口来学习这些东西!不幸的是,我还没有使用FPGA的经验。
Keegan Jay

6

简便:使用PSoC5单片机

PSoC

您可以轻松使用微控制器,并且其中包含CPLD,因此您可以在Verilog中编写自己的硬件外设。只需在verilog中编写您的串行数据解码器,然后使用DMA将其流式传输到USB端口即可。

同时,功能强大的32位ARM内核可以使它的Thumb仪器发生变化。


概述页面未列出时钟频率,这引起了我的怀疑。数据表上说40MHz(在6MHz时我也注意到6mA)。这是OP现在的一半。“ MCU还必须处理许多其他任务”,因此这取决于哪些是好主意。
stevenvh 2012年

它们高达67MHz。因此,它几乎与OP当前的处理器一样快,除了大部分工作将在硬件中完成之外,从而使CPU拥有更多的空闲时间。
Rocketmagnet 2012年

1
我没有看所有的数据表。我选择的第一个是40MHz。
stevenvh 2012年

@stevenvh-他们有不同的速度等级。PN中的第三个数字是速度等级。(4 = 48MHz,6 = 67MHz)。
Rocketmagnet 2012年

1
从长远来看,这也是一个很棒的解决方案,非常类似于FPGA的想法。我从未听说过这种芯片,但是它将板子其余部分的许多功能带到了一块芯片中。将来,这可能意味着整个接收器都可以安装在拇指驱动器大小的东西上,这是我项目负责人的愿景。我将在下一个测量师中学习Verilog。
Keegan Jay

4

我认为您有一个经典的工程选择:快速,便宜,可行:选择两项。

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

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


这种解决方案通过减少基于中断的驱动程序的数量来补充了Rocketman的软件方法。我可能会将我提到的主要串行驱动程序保留为基于中断的。另外,我会尝试旋转直到您读完整个框架。
Keegan Jay

3

首先,我已经喜欢这里的一些答案,有些已经获得了我的投票。

但是只是抛出另一个可能的解决方案:给定项目的约束,添加第二个微控制器是否会很不好(会涉及到另一个电路板的运行)?也许是一个简单的8位微控制器,它通过SPI等快速外设连接到Cortex-M3。您选择的8位控制器将像选择的答案一样轮询位并形成字节,但是当它确实具有字节时,可以将其转储到SPI数据寄存器中以进行输出。

cortex-M3端会简单地中断接收到的SPI数据。这样可以将您之前的400 KHz外部边沿触发中断减少到50 KHz。

我建议这样做的两个原因是因为其他一些方法(PSoC或添加的FPGA)有点贵(尽管这对于少量的学术项目来说可能并不重要),并且因为它可以让您保留一些您当前代码的结构。

除此之外,我认为PSoC的想法很棒,因为您可以通过DMA将自己的定制外设传输到USB。


实际上,这是我在发布此主题时想到的计划。如果我不能通过减少对中断(选择的答案)的依赖来简化软件,那么我肯定会这样做。但是,是的,这将需要另外的电路板运行,可能需要两次,因为我很想在第一时间就完成设计。
Keegan Jay 2012年

@JayKeegan,哈哈欢迎来到俱乐部!
乔恩·L

2

如果您的数据格式类似于UART的数据格式,但波特率仍无法预测,则我倾向于使用CPLD将输入数据的每个字转换为SPI或标准异步格式。我认为没有必要一路推向CPLD领域。实际上,即使是离散逻辑也几乎可行。如果您生成的时钟是所需数据速率的5倍以上,则可以使用带有几个门的5分频和16分频计数器。排列五分频计数器,以便每当输入空闲且16分频计数器为零时,它将保持复位状态。否则,每当五分频计数器达到2时,就生成一个SPI时钟脉冲并撞击16分频计数器。

给定5x时钟,就可以使用16V8(目前最小,最便宜的可编程逻辑器件)生成SPI时钟。第二个16V8或22V10可以用作分数速率分频器以生成5x时钟,或者可以使用稍大的芯片(CPLD)并一并完成所有工作。

编辑/附录

经过进一步考虑,如果要使用CPLD,则可以轻松地为电路添加一些其他增强功能。例如,可以很容易地添加逻辑以使电路停顿,直到它收到停止位的至少1.5位时间,然后是起始位的3.5位时间为止。如果接收到的起始位太短,则应返回到寻找停止位。同样,如果使用的是SPI,则可以使用/ CS信号来确保接收设备将看到正确帧化的数据。如果接收SPI数据的设备可以处理10位帧,则可以直接发送此类帧。否则,可以将每个10位帧作为具有LSB设置(7位数据)的8位帧和带有所有LSB清除(3位数据)的帧发送。SPI时钟将在停止位期间加速,因此将发送所有数据。

一些微控制器具有相当通用的PWM生成模块,其中包括通过外部信号保持复位的能力,以及将其时序与这种信号的释放同步的功能。如果您的微控制器可以执行此操作,则取决于其确切功能,这可能会大大简化CPLD或时序生成电路。

Rocketmagnet在某种程度上涉及到的另一种方法是拥有一个微型微型计算机,其唯一目的是解码串行数据并将其转换为主微型计算机可用的格式。您的400KHz数据速率对于软件解码而言是非常快的,但是如果PIC不必同时执行其他任何操作,则可以处理类似PIC的数据。根据您所熟悉的设备,这可能比使用CPLD更容易或更难。


当设计用于解码的数字逻辑时,这将是非常有价值的。我确实将输出为SPI。现在,我只是使用独立的MCU(有时间限制)进行解码。谢谢!
Keegan Jay
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.