Electronic – STM32F031K6 HAL UART Interrupts problem

interruptsmicrocontrollerstm32stm32f0uart

enter image description hereI got a new STM32F0 31 K6 nucleo board and I need to make a GSM UART interface on that board. I need to send an AT and receive an OK from the GSM board as a first step.I am able to transmit AT successfully
But cannot receive anything. I am using IAR.
I am using PA9 – TX and PA10 – RX.
How to create a transmit and receive code using interrupts using this HAL library.
I wrote code using interrupts and it's not giving a single character.
This is my code

     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)
  {
  }
}

IRQ handler

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

Receive callback function

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

And when I am debugging the code stuck at this point .

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

My actual application is to send an SMS to the GSM board using UART and collect the reply in a buffer and then parse it.First i need to make this interface
And I cannot use DMA as there is no idea on how much data is received on this commuunication.

please help guys..

Regards,
olivia

Best Answer

A basic UART initialization with interrupts using HAL looks something like the one below. I do not want to descirbe the parameters as they are quite obvious. It is an actual pins configuration and the UART peripheral configuration. HAL_UART_MspInit is called by HAL_UART_Init, to use it you only need to call 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
  }
}

The interrupt handling is the following:

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

This is the actual ISR, and HAL_UART_IRQHandler(&huart1) is a HAL definied handler function. It checks which interrupt source flag has been set, calls a callback or wait for more byte to be received and clears the interrupt flags.

In case of RX interrupts this handler counts the received bytes and when the desired amount is received calls this callback function:

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

The callback has a weak declaration, you have to implement it.

Now about usage. To send, the following HAL function can be used, this is the simplest:

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

To receive with interrupt one must use the following function:

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

where pData is a pointer to the receive buffer and size is the number of bytes you are expecting. The HAL_UART_IRQHandler(&huart1) will call the callback if the number of received bytes equal to size.

All of this can be generated by using STM32CubeMX code generator, except the callbacks, those are not generated.


The GSM module probably has echo mode enabled by default, so to AT\r it will respond with \r\nAT\r\n\r\nOK\r\n, 12 bytes should be waited.

Echo mode can be disabled by ATE0 command and saved as default with the AT&W command. From that the answer will be \r\nOK\r\n to the AT\r.