cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4+ USART RX+Interrupt Not working

ControlFreak
Associate III

Hello,

I am trying to configure USART1 on Nucleo-32 board using HAL. Code is suppose to first it receive the message and then it transmits the same message.

My problem is RDR is showing reading garbage value. Can someone point out was is wrong?

(Please ignore my indentation of code- this is just my test run)

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

You say "RDR is showing reading garbage". But you are not accessing RDR directly. Do you mean your rx buffer shows something other that what you expect? If so, what were you expecting to receive and what did you actually receive? When you first transmit your canned "aTxBuffer", does whoever receives that get THAT data OK? Can you loop-back your TX to your RX (perhaps on the far side of the LTC2873) and see if you can receive the same thing that you send.

I don't see you supplying an error callback function. Do you know if any of the error bits are getting set?

You configure the LTC control lines then immediately start sending. Does the LTC part need any specific delay between changing control lines and actually being able to rx/tx data?

Are you currently looping back the serial port, such that you are expecting to receive the same 5 bytes that you first sent before the while() loop? If so, the 1 second delay after the HAL_UART_Transmit_IT() call will cause you to miss that data.

FYI - it is perhaps better forums etiquette to actually include your source in your post as opposed to requiring us to download it. As your user name implies, I am also a control freak and very hesitant/paranoid about downloading files of unknown content, even from forums that I hope and presume would filter files before allowing them to be posted 🙂

View solution in original post

15 REPLIES 15
Bob S
Principal

You say "RDR is showing reading garbage". But you are not accessing RDR directly. Do you mean your rx buffer shows something other that what you expect? If so, what were you expecting to receive and what did you actually receive? When you first transmit your canned "aTxBuffer", does whoever receives that get THAT data OK? Can you loop-back your TX to your RX (perhaps on the far side of the LTC2873) and see if you can receive the same thing that you send.

I don't see you supplying an error callback function. Do you know if any of the error bits are getting set?

You configure the LTC control lines then immediately start sending. Does the LTC part need any specific delay between changing control lines and actually being able to rx/tx data?

Are you currently looping back the serial port, such that you are expecting to receive the same 5 bytes that you first sent before the while() loop? If so, the 1 second delay after the HAL_UART_Transmit_IT() call will cause you to miss that data.

FYI - it is perhaps better forums etiquette to actually include your source in your post as opposed to requiring us to download it. As your user name implies, I am also a control freak and very hesitant/paranoid about downloading files of unknown content, even from forums that I hope and presume would filter files before allowing them to be posted 🙂

Bob S
Principal

Deleted. ^%#% browser retry - reposted same answer 3 times.

Bob S
Principal

Deleted. ^%#% browser retry - reposted same answer 3 times.

ControlFreak
Associate III

My expected result of this code First STM32L4 USART will transmit the default character which is ABCDE (aTXBUFFER value) and then in continuous loop STM32L4 USART should Transmit back 5 character that STM32L4 is receiving from Termite/ TeraTerm.

I say that I am receiving garbage character because my RDR (in debug mode) sometimes shows 0xF8 and sometime should 0xc0 as received value.

I guess while trying to make changes to code I must have accidentally deleted error function,but flag as as expected.

As far as my transmission is concern, first transmission value is correct "HAL_UART_Transmit_IT( &UartHandle,aTxBuffer,TXBUFFERSIZE);"

But transmission of received data using "HAL_UART_Transmit_IT( &UartHandle,aRxBuffer,RXBUFFERSIZE);" shows just 00.

I did add some delay to check if there is some start up time issue for transreceiver chip, but no change in expected result.

(As far as your response to including my source code is concern I will definitely keep in mind. for other I am posting the code )

#include "stm32l4xx.h"

#include "stm32l4xx_nucleo_32.h"

UART_HandleTypeDef UartHandle;

void SystemClock_Config(void);

void GPIO_Toggle(void);

void LTC_2873(void);

static GPIO_InitTypeDef GPIO_InitStruct;

uint8_t aTxBuffer[] ={0x41,0x42,0x43,0x44,0x45};

#define TXBUFFERSIZE  5

#define RXBUFFERSIZE  5

uint8_t aRxBuffer[RXBUFFERSIZE];

uint8_t rx_cplt=0;

uint8_t i=0;

void software_delay(__IO uint32_t nCount);

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 GPIO_Toggle();

 LTC_2873();

HAL_Delay(250);

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);

 UartHandle.Instance    = USART1;

 UartHandle.Init.BaudRate  = 9600;

 UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

 UartHandle.Init.StopBits  = UART_STOPBITS_1;

 UartHandle.Init.Parity   = UART_PARITY_NONE;

 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

 UartHandle.Init.OverSampling=UART_OVERSAMPLING_16;

 UartHandle.Init.OneBitSampling=UART_ONE_BIT_SAMPLE_DISABLE;

 UartHandle.Init.Mode    = UART_MODE_TX_RX  ;

 if(HAL_UART_DeInit(&UartHandle) != HAL_OK)

 {

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

 }

 if(HAL_UART_Init(&UartHandle) != HAL_OK)

 {

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

 }

 //RS232 Transmitter Mode

 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); // Mode

 HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); // Slow Rate

 HAL_UART_Transmit_IT( &UartHandle,aTxBuffer,TXBUFFERSIZE);

 //HAL_Delay(500);

 while(1)

 {

do

{

while(HAL_UART_Receive_IT( &UartHandle,aRxBuffer,RXBUFFERSIZE)!=HAL_OK);

}while(rx_cplt!=1);

if(rx_cplt==1)

HAL_UART_Transmit_IT( &UartHandle,aRxBuffer,RXBUFFERSIZE);

 }

}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)

{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);

}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{

rx_cplt=1;

}

void software_delay(__IO uint32_t nCount)

{

 while(nCount--)

 {

  //Do nothing, decrement counter

 }

}

void LTC_2873(void)

{

 __HAL_RCC_GPIOB_CLK_ENABLE();

 // Mode

 __HAL_RCC_GPIOB_CLK_ENABLE();

 GPIO_InitStruct.Pin = GPIO_PIN_7;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 //TE485- unimplemented

 __HAL_RCC_GPIOC_CLK_ENABLE();

 GPIO_InitStruct.Pin = GPIO_PIN_14;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

 //RE485^/DE485/F232

 __HAL_RCC_GPIOB_CLK_ENABLE();

 GPIO_InitStruct.Pin = GPIO_PIN_4;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

 }

void GPIO_Toggle(void)

{

 GPIO_InitTypeDef GPIO_InitStruct;

 __HAL_RCC_GPIOB_CLK_ENABLE();

 GPIO_InitStruct.Pin = GPIO_PIN_3;

 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

 GPIO_InitStruct.Pull = GPIO_NOPULL;

 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

void HAL_UART_MspInit(UART_HandleTypeDef *huart)

{

  GPIO_InitTypeDef GPIO_InitStruct;

 __HAL_RCC_GPIOA_CLK_ENABLE();

 GPIO_InitStruct.Mode   = GPIO_MODE_AF_PP;

 GPIO_InitStruct.Pull   = GPIO_PULLUP;

 GPIO_InitStruct.Speed   = GPIO_SPEED_FREQ_HIGH;

 GPIO_InitStruct.Pin    = GPIO_PIN_9;

 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 GPIO_InitStruct.Pin    = GPIO_PIN_10;

 GPIO_InitStruct.Alternate = GPIO_AF7_USART1;

 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 __HAL_RCC_USART1_CLK_ENABLE();

 /* NVIC for USART, to catch the TX complete */

 HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);

 HAL_NVIC_EnableIRQ(USART1_IRQn);

 }

void SystemClock_Config(void)

{

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 /* MSI is enabled after System reset, activate PLL with MSI as source */

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;

 RCC_OscInitStruct.MSIState = RCC_MSI_ON;

 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;

 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

 RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;

 RCC_OscInitStruct.PLL.PLLM = 1;

 RCC_OscInitStruct.PLL.PLLN = 40;

 RCC_OscInitStruct.PLL.PLLR = 2;

 RCC_OscInitStruct.PLL.PLLP = 7;

 RCC_OscInitStruct.PLL.PLLQ = 4;

 if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

  /* Initialization Error */

  while(1);

 }

 /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2

   clocks dividers */

 RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

 if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)

 {

  /* Initialization Error */

  while(1);

 }

}

// Interupt .c

void USART1_IRQHandler(void)

{

 HAL_UART_IRQHandler(&UartHandle);

}

T J
Lead

this is the most obvious issue

when you test for a flag, then if its true, you must make it false to reset the trigger.

ie.

#define true 1
#define false 0
 
if ( rx_cplt )
{
   rx_cplt=false;
}

ControlFreak
Associate III

Thats true. but my receiver buffer is accepting the correct value

T J
Lead

but you say "RDR is showing reading garbage"

T J
Lead

but you say "RDR is showing reading garbage"

ControlFreak
Associate III

Plese find Print screen attached below