我正在尝试使用STM32F303发现板通过USB发回数据,但遇到了一些问题。以下是问题发生的代码:
void CDC_Receive_Callback(uint8_t *_buff, uint16_t _len) {
uint8_t *sub_buff; // Buffer to store sub strings (extracted data)
uint8_t outputMsg[256] = ""; // Buffer for output message
uint8_t command; // Command
uint8_t value; // Command value
// Extract the command
sub_buff = (uint8_t *) strtok((char *) _buff, " ");
command = (uint8_t) atoi((char *) sub_buff);
// Extract the command value
sub_buff = (uint8_t *) strtok(NULL, " ");
value = (uint8_t) atoi((char *) sub_buff);
// Check for extraneous data
if (strtok(NULL, " ") != NULL) {
command = 0;
}
// Perform command
switch(command) {
/* ...Command Options... */
case CMD_LED_ON:
//Acknowledge command
CDC_Transmit_FS((uint8_t *) MSG_LED_ON,
strlen(MSG_LED_ON));
//Turn on LED
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_12, GPIO_PIN_RESET);
break;
case CMD_RETURN_DATA:
//Acknowledge command
CDC_Transmit_FS((uint8_t *) MSG_RETURN_DATA,
strlen(MSG_RETURN_DATA));
calculateData();
//Build return message
strcat((char *) outputMsg, "Calculation Results: \n");
uint8_t value_as_string[100];
sprintf((char *)value_as_string, "Data: %u\n", getData());
strcat((char *) outputMsg, (char *)value_as_string);
CDC_Transmit_FS((uint8_t *) outputMsg,
strlen((char *)outputMsg));
break;
CMD_LED_ON命令完全有效(LED亮起,返回MSG_LED_ON)。但是,CMD_RETURN_DATA命令仅通过USB发送MSG_RETURN_DATA,但没有其他内容。我曾尝试过两次发送MSG_RETURN_DATA:
case CMD_RETURN_DATA:
//Acknowledge command
CDC_Transmit_FS((uint8_t *) MSG_RETURN_DATA,
strlen(MSG_RETURN_DATA));
CDC_Transmit_FS((uint8_t *) MSG_RETURN_DATA,
strlen(MSG_RETURN_DATA));
break;
但MSG_RETURN_DATA只显示一次。我认为问题是两次调用CDC_Transmit_FS(),所以我尝试在outputMsg中包含MSG_RETURN_DATA只调用一次CDC_Transmit_FS():
case CMD_RETURN_DATA:
calculateData();
//Build return message
strcat((char *) outputMsg, MSG_RETURN_DATA);
strcat((char *) outputMsg, "Calculation Results: \n");
uint8_t value_as_string[100];
sprintf((char *)value_as_string, "Data: %u\n", getData());
strcat((char *) outputMsg, (char *)value_as_string);
CDC_Transmit_FS((uint8_t *) outputMsg,
strlen((char *)outputMsg));
break;
并且RealTerm中没有显示任何内容。这是我的CDC_Transmit_FS()代码:
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
USBD_CDC_HandleTypeDef *hcdc =
(USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if(hcdc->TxState != 0) {
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
return result;
}
当我尝试调试时,似乎在给出CMD_RETURN_DATA命令时,CDC_Transmit_FS()总是返回USBD_BUSY,此时代码跳转到CDC_Receive_FS(),原因我不明白。以下是CDC_Receive_FS()的代码:
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
CDC_Receive_Callback(Buf, *Len);
return (USBD_OK);
}
我不知道如何让CMD_RETURN_DATA成功返回数据。任何帮助将不胜感激。
编辑:为了扩展我的问题,在进行一次传输后,似乎TxState永远不会变为0.我修改CDC_Transmit_FS()以等待TxState:
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if(hcdc->TxState != 0) {
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
//Wait for transmission to finish
while(hcdc->TxState) ;
return result;
}
并且程序在while循环中挂起。我已经尝试发送CMD_LED_ON,并且计算机接收到它应该的消息,所以我知道传输已经完成,但程序仍然停留在循环内。我的期望是PCD_EP_ISR_Handler()应该调用HAL_PCD_DataInStageCallback(),它调用USBD_LL_DataInStage(),它调用pdev-> pClass-> DataIn(),这是USBD_CDC_DataIn()的另一个名称。此USBD_CDC_DataIn()将TxState设置为0.由于某种原因,此函数似乎没有被调用。