我正在尝试在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键时从缓冲区接收它?
答案 0 :(得分:2)
我假设您打算通过USB实现串行连接(也称为虚拟COM端口),并且在PC上已连接了终端应用程序...
如果是这样,您需要了解以下内容:
从PC发送到MCU的字符可以分为任意数据包。无法确保同一封包中有一段文字。如果您输入的是终端程序,则每个字符甚至有可能以单独的数据包发送。如果将长文本粘贴到终端程序中,则很可能会收到最长64个字符的长数据包。
接收到的数据是一个字符数组。它不是字符串(以'\ 0'结尾)。因此,除非将数据转换为字符串,否则不得使用诸如atoi
或strlen
之类的字符串函数。
为了进步:
添加代码,用于检测何时已接收到足够的数据来对其进行处理。一种典型的方法是使用换行符,即保存所有接收到的数据,直到收到整行为止。然后处理整个行。
在保存的数据中,添加一个'\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_t
到int
的转换。