stm32 USB получает более 1 байта - PullRequest
0 голосов
/ 30 января 2020

Я пытаюсь установить sh соединение USB между P C и MCU STM32. Я хочу получить целое число от P C. (диапазон целого числа от 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 ди git номеров. Должен ли я добавить оператор if в начало функции, и когда нажата клавиша enter, я должен получить его из буфера?

1 Ответ

2 голосов
/ 30 января 2020

Я предполагаю, что вы пытаетесь реализовать последовательное соединение (также называемое виртуальным COM-портом) через USB и что к нему подключено терминальное приложение на P C ...

Если Итак, вы должны понимать, что:

  • Символы, отправленные из P C в 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.
...