【问题标题】:GPS receiver uart buffer line breakGPS接收器uart缓冲断线
【发布时间】:2019-08-09 22:36:22
【问题描述】:

我正在尝试从我的 gps 接收器读取整个消息流,我需要在一个消息块和下一个消息块之间对流结束进行某种识别。

我尝试读取具有各种尺寸(100、200、500、1000)的缓冲区,显然如果太短我会中断消息,如果太长我会发现重复相同的消息块,例如:

GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC

这就是我希望在接收时接收到的每个中断(例如,使用 HAL_UART_ReveiveIT(),但在其他平台上,这个概念也是相同的)。

相反,关于我提供的缓冲区大小,我有如下数据:

GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXX

GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXX

GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXX

我无法检测到消息块的结尾,它会再次重复,例如:

GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC GNGGA,XXXXXXXXX*CC GNGNS,XXXXXXXX*CC GNRMC,XXXXXXXXXXX*CC GNGSV,XXXXXXXXXX*CC

我尝试检测接收到的字符的中断,因此检查当前字符是“\r”还是“\n”,但是这适用于每一行,它只检测一行的结尾,而不是块的结尾

我想从 uart 读取,在完成接收时中断或在 DMA 上中断,只有完整的消息块,然后再读取下一个块,但是 我找不到任何标志或终止字符这可以帮助我区分块

另外,根据每条消息的数据,块可以有不同的大小,所以我不能给出一个固定长度的数组。

我在考虑硬件流控制或者使用来自gps的fix LED信号来发送一个可以触发块结束的外部中断...

  • 你有什么想法吗?
  • 这完全是使用解析器进行后处理的问题吗?
  • 可能会丢弃或覆盖多个同类句子中的字段?

感谢您的帮助

【问题讨论】:

  • “这都是使用解析器进行后处理的问题吗?” -- 正确,否则您在中断级别和 UART 驱动程序上尝试做太多事情。 UART 没有行或块的概念,只有单个字符的帧。帧之间存在中断条件和计时暂停(例如 Modbus),但这些完全在发送方的控制下发生。
  • 感谢锯末,我希望在中断方面可以做更多的事情,但显然情况并非如此。干杯
  • 是这个协议吗:navspark.mybigcommerce.com/content/NMEA_Format_v0.1.pdf?如果是这样,您真的应该只是在每条消息的末尾通过 CR+LF 解析消息。这将比通过其他方式(例如使用 IDLE 中断)将数据拆分为消息更加健壮。

标签: gps buffer line stm32 uart


【解决方案1】:

由于您作为 GPS 接收器的输出发布的内容似乎始终具有相同的结构和最重要的相同长度,我建议您计算一下您收到的 UART 消息。

如果不是这种情况,并且由于前导零的抑制而导致行的长度会有所不同,您也可以计算您告诉您已经可以识别的行。

如果由于您的块似乎从GNGGA 开始,甚至块的长度都发生了变化,您可以在线路末端触发以最小化中断负载(如果您将 UART 接口配置为字符匹配则更好)并且您会发现一行从GNGGA 开始,你知道缓冲区中的每一行之前的每一行都是一个块。

当您确切知道一个块有多长时,您可以让 DMA 为您完成计数工作,并在配置的字节数在您的缓冲区中时生成设置 fleg 的中断。这会给你一个自制的“EndOfBlock”标志/中断。

【讨论】:

    【解决方案2】:

    我不太关心直接在 UART 接收器代码中检测块结束。

    我宁愿让 UART 接收器使用循环缓冲区。 有一个简单的解析器尝试在循环缓冲区填满时查找每一行,然后将一行和一行转发给 (NMEA) 解析器。

    让 NMEA 解析器在接收数据时存储数据,直到收到完整的消息,然后将其转发到您的主程序流程。

    (所以基本上,做一些简单的层,每一层都应该易于调试,因为它只负责一个任务)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      • 2021-06-16
      • 2014-10-30
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多