STM32F4 serial RXNE flag

1

Estoy intentando recibir un serial en un stm32f411.

Decidí monitorear el indicador RXNE para verificar el búfer en serie. Puedo conseguir que la bandera funcione, sin embargo, el problema es que no creo que esté funcionando completamente.

Configuré una prueba para incrementar un contador según la cantidad de veces que necesito leer el registro DR. El problema es que no puedo hacer que incremente el contador más de una vez. Para verificar esto, simplemente hice un bucle para encender un LED según la cantidad de veces que accedí al registro DR. El máximo que puedo hacer que el LED parpadee es 2 veces. ¿Mi lógica en mi código es incorrecta?

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"

/* USER CODE BEGIN Includes */

#include <stdbool.h>

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
uint8_t pdiddy_increment = 0;

int pdiddy[15];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

// detect if anything is in serial buffer
uint8_t Serial_Available(UART_HandleTypeDef *huart)
{
    uint32_t RX_State;

    RX_State = huart->Instance->SR & UART_FLAG_RXNE;

    //something is in the buffer 
    if (RX_State > 0)
    {
        return 1;
    }
    //nothing is there 
    return 0;
}
/* USER CODE END 0 */

int main(void)
{
  /* MCU Configuration----------------------------------------------------------*/

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

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

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

  while (1)
  {
      while (Serial_Available(&huart1))
      {
        /*read DR and put value in array*/
        /*Reading DR, increment shift*/
        pdiddy[pdiddy_increment] = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
        pdiddy_increment++;
     }

     while (pdiddy_increment > 0)
     {
       HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
       HAL_Delay(400);
       HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
       HAL_Delay(400);
       pdiddy_increment--;
     }
  }
  /* USER CODE END 3 */
}
    
pregunta Verosity

1 respuesta

1

Su código se escribe con la suposición implícita de un FIFO en serie, pero ese FIFO tiene solo 1 profundidad de hardware y no se ha extendido a un tamaño mayor en el software.

El primer elemento de su bucle while() comprueba si se ha recibido un carácter y, de ser así, incrementará su contador, pero solo podrá incrementarlo una vez.

A continuación, su código ingresa en un bloqueo de drenaje que no saldrá hasta que el contador se haya drenado a cero.

Durante el bucle de drenaje de bloqueo, se podría recibir cualquier número de caracteres en serie, pero como el hardware solo tiene un único registro de retención, el hardware solo puede indicar algunas cosas distintas:

  1. No se ha recibido ningún carácter
  2. Se ha recibido un carácter
  3. Se ha recibido un carácter y luego se ha desbordado el registro porque se recibió otro antes de que se vaciara.
  4. Se ha producido un error de formato de serie, con o sin algunas de estas otras cosas.

Cuando su código que comprueba la serie se ejecute de nuevo, solo puede interpretar correctamente los dos primeros estados, de modo que lo único que puede hacer es incrementar el contador en uno , o no, ningún otro incremento es posible.

Si desea contar los caracteres que entran durante una secuencia de flash de bloqueo del LED, deberá usar una interrupción de recepción en serie. O puede hacer que el LED parpadee en una máquina de estado sin bloqueo, en un bucle que también sondea la serie.

    
respondido por el Chris Stratton

Lea otras preguntas en las etiquetas