stm32 USB接收的字节数超过1个

时间:2020-01-30 08:12:45

标签: c stm32

我正在尝试在PC和STM32 MCU之间建立USB通信。我想从PC接收一个整数。 (整数范围在0到20.000之间)。我添加了以下几行:

致usb_cdc_if.h:

_weak void CDC_ReceiveCallBack(uint8_t *buf, uint32_t len);

到usb_cdc_if.c

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
  CDC_ReceiveCallBack(Buf, Len);
  return (USBD_OK);
  /* USER CODE END 6 */
}
.
.
.
__weak void CDC_ReceiveCallBack(uint8_t *buf, uint32_t len)
{}

在主类中:

void CDC_ReceiveCallBack(uint8_t *buf, uint32_t len)
{

fan_speed=atoi(buf);
    memset(statusString,0x00,255);
statusStringLength = sprintf(statusString,"Fan Speed: %d ", fan_speed);
    CDC_Transmit_FS(statusString,statusStringLength);
}

所以我只能收到1位数字。是否应该在函数的开头添加if语句,并在按Enter键时从缓冲区接收它?

1 个答案:

答案 0 :(得分:2)

我假设您打算通过USB实现串行连接(也称为虚拟COM端口),并且在PC上已连接了终端应用程序...

如果是这样,您需要了解以下内容:

  • 从PC发送到MCU的字符可以分为任意数据包。无法确保同一封包中有一段文字。如果您输入的是终端程序,则每个字符甚至有可能以单独的数据包发送。如果将长文本粘贴到终端程序中,则很可能会收到最长64个字符的长数据包。

  • 接收到的数据是一个字符数组。它不是字符串(以'\ 0'结尾)。因此,除非将数据转换为字符串,否则不得使用诸如atoistrlen之类的字符串函数。

为了进步:

  • 添加代码,用于检测何时已接收到足够的数据来对其进行处理。一种典型的方法是使用换行符,即保存所有接收到的数据,直到收到整行为止。然后处理整个行。

  • 在保存的数据中,添加一个'\0'字符。这样,缓冲区就变成一个字符串,并且可以使用字符串函数进行处理。

它可能看起来像这样:

char line_buffer[80];
int line_len = 0;

void CDC_ReceiveCallBack(uint8_t *buf, uint32_t len)
{
    // append received data to line buffer
    memcpy(line_buffer + line_len, buf, len);
    line_len += len;

    while (1) {
        // check for linefeed character
        char* line_feed = memchr(buf, '\n', line_len);
        if (line_feed == NULL)
            break;

        // add string termination
        *line_feed = '\0';
        process_line(line_buffer);

        // copy remaining data to start of line buffer
        line_len -= line_feed + 1 - line_buffer;
        memcpy(line_buffer, line_feed + 1, line_len);
    }
}

void process_line(char* line) {
    // do something with the line; string functions are ok
}

请注意,代码不完整:

  • 它不检查接收到的数据是否适合line_buffer
  • 您可能会同时收到'\r''\n'字符作为行分隔符。因此,您可能要删除'\r'字符。
  • 我尚未测试代码。可能会丢失一些从void*char*或从uint32_tint的转换。
相关问题