Serial port – 接收字节数

huangapple go评论78阅读模式
英文:

Serial port - receive bytes count

问题

我从stm32传输了256字节,然后在Visual Studio中通过SerialPort接收。为什么我接收到了2次字节?首先是32,然后是224。

stm32 USART配置:

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
uint8_t memory[256];
for (int i = 0; i < 256; i++)
memory[i] = 0xFF;
HAL_UART_Transmit(&huart2, memory, sizeof(memory), HAL_MAX_DELAY);

Visual Studio:

private void readerSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  if (!this.readerSerialPort.IsOpen) return;
  int bytes = this.readerSerialPort.BytesToRead;
  byte[] buffer = new byte[bytes];
  this.readerSerialPort.Read(buffer, 0, bytes);
  MessageBox.Show(buffer.Length.ToString());
}

为什么会发生这种情况?

英文:

I transmit 256 bytes from stm32 and receive it by SerialPort in Visual studio. Why i receive bytes 2 times? 32 and then 224.

stm32 USART configuration:

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
uint8_t memory[256];
for (int i = 0; i &lt; 256; i++)
memory[i] = 0xFF;
HAL_UART_Transmit(&amp;huart2, memory, sizeof(memory), HAL_MAX_DELAY);

Visual studio:

private void readerSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  if (!this.readerSerialPort.IsOpen) return;
  int bytes = this.readerSerialPort.BytesToRead;
  byte[] buffer = new byte[bytes];
  this.readerSerialPort.Read(buffer, 0, bytes);
  MessageBox.Show(buffer.Length.ToString());
}

Why is this happening?

答案1

得分: 2

串行协议以及USB大容量端点,这些很可能在微控制器和您的计算机之间使用,都是流协议。它们假定字节的流是恒定的,不使用定界符来传输原始数据块的边界。

这与传输和保留独立数据块的面向消息的协议相对立。

因此,您用于提交数据的块的大小不会被保留。多个块可能会被合并成一个单一的块,一个单一的块也可能会被分割成多个块,就像您所经历的那样。

如果您需要面向消息的协议,您需要在流协议的基础上自行实现它。典型的方法包括:

  • 定义一个带有消息长度的消息头的消息结构。
  • 使用定界符(如果传输文本数据,最简单的情况下使用CR/LF)。
英文:

The serial protocol as well as USB bulk endpoints, which are likely used between the microcontroller and your PC are stream protocols. They assume a constant flow of bytes and do not use delimiters to transmit the boundaries of the original data chunks.

This is opposed to message-oriented protocol that transmit and retain distinct chunks of data.

As a consequence, the size of the chunks you used to submit the data are not retained. Multiple chunks might be joined into a single one, and a single chunk might be split into multiple ones as you have experienced.

If you require a message-oriented protocol, you need to implemented it yourself on top of the stream protocol. Typical approaches are:

  • Define a message structure with a message header containing the message length.
  • Use delimiters (CR/LF in the simplest case if text data is transmitted).

huangapple
  • 本文由 发表于 2023年5月18日 01:16:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76274641.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定