STM32 USB CDC不会返回数据

时间:2018-04-03 02:49:03

标签: c usb stm32 cdc

我正在尝试使用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.由于某种原因,此函数似乎没有被调用。

0 个答案:

没有答案