Прерывание приема UART, проверяющее конец данных

Я хочу получать данные через UART от моего ESP2866 с помощью прерывания RX, поэтому мне не нужно опрашивать данные.

Код работает нормально, я вижу ответ в rx_buffer во время отладки, но как я могу проверить, когда мой ESP завершил отправку?

Последние символы, которые отправляет ESP, это \r\n, но он также делает это несколько раз во время передачи, поэтому я не могу на это полагаться.

Я знаю, что должен каким-то образом проверить буфер на терминатор '\0', но обработчик останавливается, когда получен последний символ. Так что проверка '\0' в обработчике не работает.

Это, вероятно, что-то простое, что мне не хватает, но я надеюсь, что кто-то может мне помочь.

int main(void)
{
  /* USER CODE BEGIN 1 */
    char* msg = "AT+GMR\r\n";
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_USART1_UART_Init();

  /* Initialize interrupts */
  MX_NVIC_Init();
  /* USER CODE BEGIN 2 */

    // Send AT+GMR to ESP module
    HAL_UART_Transmit(&huart1, (uint8_t *)msg, strlen(msg) + 1, HAL_MAX_DELAY); 

    // Receive character (1 byte)
    HAL_UART_Receive_IT(&huart1, &rx_data, 1);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */


  while (1)
  {

  /* USER CODE END WHILE */
  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
  HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY); 

  return ch;
}

GETCHAR_PROTOTYPE
{
  /* Place your implementation of fgetc here */
  /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
    char ch;
    HAL_UART_Receive(&huart2,(uint8_t*)&ch,1, HAL_MAX_DELAY);
  return ch;
}

/**
  * @brief  Rx Transfer completed callback
  * @param  UartHandle: UART handle
  * @note   This example shows a simple way to report end of DMA Rx transfer, and 
  *         you can add your own implementation.
  * @retval None
  */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{  
    if(huart->Instance == USART1){

        if(rx_index == 0){
            memset(&rx_buffer, 0, sizeof(rx_buffer));
        }

        rx_buffer[rx_index] = rx_data;      

        if(rx_buffer[rx_index] == '\0'){
            printf("%s", rx_buffer);
        }

        rx_index++;

        // Receive next character (1 byte)
        HAL_UART_Receive_IT(&huart1, &rx_data, 1);

    }
}       

person stickfigure4    schedule 24.04.2018    source источник
comment
Если вы передаете текст, вы можете завершить его, скажем, EOT (значение 4). Я знаю, что должен каким-то образом проверить буфер на терминатор '\0', но обработчик останавливается, когда получен последний символ. Вы должны передать файл '\0'.   -  person Weather Vane    schedule 24.04.2018
comment
Изменение @WeatherVane rx_buffer[rx_index] == 4 тоже не работает. Также я не могу сказать ESP отправить это «\ 0»?   -  person stickfigure4    schedule 24.04.2018
comment
Я не понимаю, почему вы не можете передать финальные 0 или 4. Альтернативой может быть обработка ввода всякий раз, когда получена новая строка. Нелегко понять, что вы делаете, потому что опубликованный код неполный. Но если HAL_UART_RxCpltCallback вызывается из обработчика прерывания, очень плохая идея использовать printf внутри него. Обычно обработчик прерывания должен буферизовать входящие данные и устанавливать флаг для верхнего уровня, когда готово полное сообщение. Если вы используете кольцевой буфер, прерывание может продолжать приниматься, пока обрабатывается предыдущий буферизованный ввод.   -  person Weather Vane    schedule 24.04.2018
comment
@WeatherVane FYI: ESP ожидает AT-команды и выводит для них ответы в фиксированном формате, поэтому 4 или 0 нельзя добавить. К сожалению, нет команды для изменения символа завершения командной строки. :)   -  person Bence Kaulics    schedule 24.04.2018
comment
@BenceKaulics спасибо, так что вернемся к моему предложению ответить на новую строку и, возможно, реорганизовать код.   -  person Weather Vane    schedule 24.04.2018
comment
у вас есть эта книга: https://leanpub.com/ESP8266_ESP32?   -  person user3629249    schedule 25.04.2018
comment
@WeatherVane printf в обработчике был предназначен для тестирования, я могу попробовать обрабатывать ввод в каждой новой строке, но это не то, что я действительно хочу делать.   -  person stickfigure4    schedule 25.04.2018
comment
Добавьте прерывание IDLE как продажу. Когда промежуток между байтами превышает 10 бит, этот флаг устанавливается и вызывается обработчик прерывания.   -  person 0___________    schedule 02.02.2021


Ответы (1)


Когда вы рассматриваете size of, char* msg = "AT+GMR\r\n"; сам считает \0 персонажем.

Поэтому вам не нужно добавлять +1 в функцию Transmit.

person saeid_dgn    schedule 02.02.2021
comment
Ваш ответ неверен, sizeof msg даст вам только размер указателя. Вам нужно сделать его массивом, если вы хотите получить размер: char msg[] = "AT+GMR\r\n"; Способ OP работает для обоих вариантов и работает для строк, переданных в качестве аргумента функции. - person the busybee; 02.02.2021