STM32L031 Rutina del transceptor de puerto serie HAL (interrupción con sondeo)

STM32L031 Rutina del transceptor de puerto serie HAL (interrupción con sondeo)

Entorno de código

  1. Herramientas de desarrollo: STM32CUBEIDE
  2. Chip: STM32L031K6T6
  3. Puerto: UART2

Configuracion basica

Inserte la descripción de la imagen aquí

Inserte la descripción de la imagen aquí
Entre ellos, la entrada de PA9 (RX) se levanta y se configura en el GPIO de System Core.
Inserte la descripción de la imagen aquí

Diseño TX (transmisión)

La parte TX agrega archivos bsp_usart.cy bsp_usart.h para soportar la sobrecarga de printf.

bsp_usart.h contenido

#ifndef __BSP_USART_H
#define __BSP_USART_H

#include "stm32l0xx_hal.h"
#include "stdio.h"	 	  	

int fputc(int ch, FILE *f);

#endif

bsp_usart.c contenido

#include <bsp_usart.h>

extern UART_HandleTypeDef huart2;

/* USER CODE BEGIN 1 */
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
 set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
/**
 * @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, 0xFFFF);
	return ch;
}
/* USER CODE END 1 */


Introduce el archivo de encabezado en el archivo main.c

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include "bsp_usart.h"

Luego, puede usar printf ("uart2 datos de salida =% d \ r \ n", datos) ;.

Diseño RX (recepción)

El diseño de recepción de puerto serie convencional necesita diseñar el reconocimiento de tiempo de espera después del byte recibido actual.Si hay un tiempo de espera, se considera que la recepción ha terminado. Incluso si se trata de una transmisión de longitud de bytes fija, es necesario diseñar el reconocimiento de tiempo de espera como el final de la transmisión para situaciones anormales.
La biblioteca STM32 HAL admite la recepción de datos en serie en el modo de tiempo de espera de sondeo (HAL_StatusTypeDef HAL_UART_Receive (UART_HandleTypeDef * huart, uint8_t * pData, uint16_t Size, uint32_t Timeout)) y también admite la recepción de datos en serie en el modo de interrupción (HAL_DefReceTive_ pData, uint16_t Size)), así que considere combinar los dos métodos para simplificar el diseño del juicio de tiempo de espera.
Las principales ideas de diseño son: 1. Recibir el primer byte mediante interrupción 2. Recibir bytes posteriores mediante sondeo.

Inicialice el código relevante antes de la función main (), y STM32CUBEIDE genera automáticamente parte del código:

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
#define UART2_RX_STOP 0
#define UART2_RX_START 1
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
/* USER CODE BEGIN PV */
uint8_t aRxBuffer;			//RX int buffer, 1 byte
uint8_t Uart2_RxBuff[10] = {
    
    0};		//Rx buffer,should be adjusted according to Rx max byte length per communication.
uint8_t uart2_rx_flag = UART2_RX_STOP;
HAL_StatusTypeDef uart2_status_rx;
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_USART2_UART_Init(void);

Código relacionado con la función Main (), parte del código es generado automáticamente por STM32CUBEIDE:

int main(void)
{
    
    
  /* USER CODE BEGIN 1 */
  /* 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_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  if (HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1)!=HAL_OK) printf("UART2 IT FAILED! \r\n");
  while (1)
  {
    
    
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
     if (uart2_rx_flag == UART2_RX_START)
     {
    
    
    	 uart2_status_rx = HAL_UART_Receive(&huart2, Uart2_RxBuff+1, 9, 100); 
    	 printf("uart2 got rx data: %d  %d %d %d %d %d %d %d %d %d\r\n", Uart2_RxBuff[0], Uart2_RxBuff[1], Uart2_RxBuff[2], Uart2_RxBuff[3], Uart2_RxBuff[4], Uart2_RxBuff[5], Uart2_RxBuff[6], Uart2_RxBuff[7], Uart2_RxBuff[8], Uart2_RxBuff[9]);
    	 uart2_rx_flag = UART2_RX_STOP;
    	 memset(Uart2_RxBuff, 0, sizeof(Uart2_RxBuff));
    	 MX_USART2_UART_Init(); 
    	 HAL_UART_Receive_IT(&huart2, (uint8_t *)&aRxBuffer, 1);

     }
	  HAL_Delay(1);   //must for timing
  }
  /* USER CODE END 3 */
}

La respuesta a la interrupción se realiza recargando la función HAL_UART_RxCpltCallback (UART_HandleTypeDef * UartHandle).

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
    
    

	Uart2_RxBuff[0] = aRxBuffer;
	uart2_rx_flag = UART2_RX_START;

	  //printf("uart2 get rx interrupt!\r\n");
      return;
}

Precauciones

  1. HAL_UART_Receive () no se puede procesar en la función HAL_UART_RxCpltCallback () y el tiempo de espera de HAL_UART_Receive () no será válido. Esto se debe a que la prioridad de interrupción de SysTick es menor que la del UART periférico y no se puede responder a la interrupción de SysTick durante el procesamiento de interrupciones de UART. (Si debe poner HAL_UART_Receive () en la función HAL_UART_RxCpltCallback (), necesita ajustar la prioridad de la interrupción SysTick).
  2. El bucle while (1) en main () necesita retrasar HAL_Delay (1), y el tiempo es normal.

-Final-

Supongo que te gusta

Origin blog.csdn.net/hwytree/article/details/103138655
Recomendado
Clasificación