1 votos

STM32F4 serial RXNE flag

Estoy tratando de recibir serie en un stm32f411.

Decidí monitorizar la bandera RXNE para comprobar el buffer serie. Puedo conseguir que la bandera funcione, sin embargo, la cuestión es que no creo que esté funcionando completamente.

Configuré una prueba para incrementar un contador basado en cuántas veces necesito leer el registro DR. El problema es que no consigo incrementar el contador más de una vez. Para verificar esto, simplemente hice un bucle para encender un LED basado en cuántas veces accedí al registro DR. Lo máximo que puedo hacer que el LED parpadee es 2 veces. ¿Está mal la lógica de mi código?

/* 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 */
}

1voto

Andrew Walker Puntos 9038

Tu código está escrito con la suposición implícita de un FIFO serie, pero ese FIFO sólo tiene 1 profundidad en hardware, y no se ha extendido a un tamaño mayor en software.

El primer elemento de su while() comprueba si se ha recibido un carácter, y si es así incrementará su contador, pero sólo puede incrementarlo una vez.

A continuación, el código introduce un bloqueo bucle 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 serie, pero como el hardware sólo tiene un único registro de retención, sólo puede indicar unas pocas 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 el registro se ha desbordado porque se ha recibido otro antes de vaciarlo.
  4. Se ha producido un error de formateo serie, con o sin alguna de estas otras cosas.

Cuando el código que comprueba la serie se ejecuta de nuevo, sólo puede interpretar correctamente los dos primeros estados, por lo que lo único que puede hacer es incrementar el contador. por uno o no, no es posible otro incremento.

Si desea contar los caracteres que entran durante una secuencia de parpadeo del LED de bloqueo, necesitará utilizar una interrupción de recepción serie. O podrías hacer el parpadeo del LED en una máquina de estado no bloqueante, en un bucle que también sondeara la serie.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X