STM32F031K6 HAL UART Interrumpe el problema

1

Tengo una nueva placa de núcleo STM32F0 31 K6 y necesito hacer una interfaz GSM UART en esa placa. Necesito enviar un AT y recibir un OK de la tarjeta GSM como primer paso. Puedo transmitir AT correctamente Pero no puede recibir nada. Estoy usando IAR. Estoy usando PA9 - TX y PA10 - RX. Cómo crear un código de transmisión y recepción utilizando interrupciones utilizando esta biblioteca HAL. Escribí código usando interrupciones y no está dando un solo carácter. Este es mi código

     int main(void)
{

  HAL_Init();
  /* Configure the system clock to 48 MHz */
  SystemClock_Config();
    /* Configure LED3 */
  BSP_LED_Init(LED3);
  UART_Init();
  BSP_LED_Off(LED3);
  if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aTxBuffer, TXBUFFERSIZE,100)!= HAL_OK)
  {
    Error_Handler();
  }

    if(HAL_UART_Receive_IT(&UartHandle, (uint8_t *)aRxBuffer,6) != HAL_OK)
  {
    Error_Handler();
  }
   /*##-5- Wait for the end of the transfer ###################################*/   
  while (UartReady != SET)
  {
  } 
    /* Reset transmission flag */
  UartReady = RESET;
  /*if(HAL_UART_Transmit(&UartHandle, (uint8_t*)aRxBuffer, 6,1000)!= HAL_OK)
  {
    Error_Handler();
  }*/
  while (1)
  {
  }
}

controlador IRQ

void USARTx_IRQHandler(void)
{
  HAL_UART_IRQHandler(&UartHandle);
}

Recibir la función de devolución de llamada

void  HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
  if(UartHandle->Instance == USARTx)
  {  
    /* Set transmission flag: transfer complete */
    UartReady = SET;
    BSP_LED_On(LED3); 
  }
}

Y cuando estoy depurando el código atascado en este punto.

/*##-5- Wait for the end of the transfer ###################################*/   
  while (UartReady != SET)
  {
  } 

Mi aplicación real es enviar un SMS a la placa GSM utilizando UART y recopilar la respuesta en un búfer y luego analizarla. Primero, necesito hacer esta interfaz Y no puedo usar DMA ya que no tengo idea de la cantidad de datos que se reciben en esta comunicación.

por favor ayuda chicos ..

Saludos, olivia

    
pregunta Olivia Christy

3 respuestas

2

Una inicialización de UART básica con interrupciones usando HAL se parece en algo al siguiente. No quiero describir los parámetros ya que son bastante obvios. Es una configuración real de pines y la configuración periférica UART. HAL_UART_MspInit es llamado por HAL_UART_Init , para usarlo solo necesitas llamar a MX_USART1_UART_Init .

#include "stm32f0xx_hal.h"

UART_HandleTypeDef huart1;

void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart1);
}

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  if(huart->Instance==USART1)
  {
    __USART1_CLK_ENABLE();

    /**USART1 GPIO Configuration    
    PA2     ------> USART1_TX
    PA3     ------> USART1_RX 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);       
    HAL_NVIC_EnableIRQ(USART1_IRQn);               // Enable Interrupt
  }
}

El manejo de interrupciones es el siguiente:

void USART1_IRQHandler()
{
  HAL_UART_IRQHandler(&huart1);
}

Este es el ISR real, y HAL_UART_IRQHandler(&huart1) es una función de manejador definida por HAL. Comprueba qué indicador de fuente de interrupción se ha establecido, llama a una devolución de llamada o espera a que se reciba más byte y borra los indicadores de interrupción.

En caso de interrupciones de RX, este controlador cuenta los bytes recibidos y, cuando se recibe la cantidad deseada, llama a esta función de devolución de llamada:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  if (huart->Instance == USART1)
  {
    // Your buffer is full with your data process it here or set a flag
  }
}

La devolución de llamada tiene una declaración débil, tienes que implementarla.

Ahora sobre el uso. Para enviar, se puede utilizar la siguiente función HAL, esta es la más sencilla:

HAL_UART_Transmit(&huart1, (uint8_t*)"AT\r", 3, 0xFFFFFF)

Para recibir con interrupción se debe usar la siguiente función:

HAL_UART_Receive_IT(&huart1, uint8_t *pData, uint16_t size)

donde pData es un puntero al búfer de recepción y size es el número de bytes que está esperando. HAL_UART_IRQHandler(&huart1) llamará a la devolución de llamada si el número de bytes recibidos es igual a size .

Todo esto se puede generar mediante el uso del generador de códigos STM32CubeMX , excepto las devoluciones de llamada, No se generan.

El módulo GSM probablemente tiene el modo eco habilitado de forma predeterminada, por lo que para AT\r responderá con \r\nAT\r\n\r\nOK\r\n , se deben esperar 12 bytes.

El modo de eco puede deshabilitarse con el comando ATE0 y guardarse como predeterminado con el comando AT&W . A partir de eso, la respuesta será \r\nOK\r\n al AT\r .

    
respondido por el Bence Kaulics
0

Recientemente enfrenté un problema similar con mi módulo LTE. Resulta que muchos de estos módulos tienen el control de flujo de hardware habilitado de forma predeterminada. También puede usar el control de flujo HW en su extremo o simplemente conectar el pin CTS de los módulos a tierra.

También por alguna razón en mi caso, el etiquetado para RX / TX y RTS / CTS se invirtió. Entonces, la solución anterior no funcionó, puedes probar con las conexiones intercambiadas.

    
respondido por el creature5d
0

Gracias chicos por la discusión! Me enfrenté al problema similar. En mi caso, habilité las interrupciones (NVIC_EnableIRQ), escribí la llamada HAL_UART_RxCpltCallback () y HAL_UART_Receive_IT ().

Pero me perdí esto:

void USART1_IRQHandler ()    {        HAL_UART_IRQHandler (& huart1);    }

Sin el controlador que se encuentra arriba, la interrupción no puede ser detectada por HAL_UART_RxCpltCallback () y la aplicación. entra en un bucle sin fin, ya que no ve ningún controlador de interrupción.

    
respondido por el диана котик

Lea otras preguntas en las etiquetas