cancel
Showing results for 
Search instead for 
Did you mean: 

USART Rx & Tx communication code

VDesa
Associate II

Hello,

I am a beginner to Nucleo-64 board programming and I am trying to work on USART communication of it. I am using NUCLEO-L476RG board and STM32CubeLL library for configuring USART and starting communication with it.

Programming Scenario:

I have connected Tx and Rx of USART2 together on the board. I want to transmit a string and receive the same string on the corresponding Rx pin. I have used interrupt based reception and I don't want to use DMA for it. I am getting the string on the Rx pin but the receive buffer is getting populated with the characters from aRxBuffer[2] position. Please help me to find the reason behind it.

My code:

void   SystemClock_Config(void);

void   Configure_GPIO(void);

void SendTo_USART(void);

void   Configure_USART(void);

uint8_t aTxBuffer[] = "TANTRAGYAAN";

uint8_t *tx=aTxBuffer;

uint8_t aRxBuffer[16]="";

uint8_t *rx=aRxBuffer;

int main(void)

{

 SystemClock_Config();

 Configure_GPIO();

Configure_USART();

SendTo_USART();

}

void SendTo_USART(void)

{

for (int index=0; index<11; index++)

{

LL_USART_TransmitData8(USART2,*(tx++));

while (!LL_USART_IsActiveFlag_TXE(USART2))

{

}

}

LL_USART_ClearFlag_TC(USART2);

}

void USART2_IRQHandler ( void )

{

while (!LL_USART_IsActiveFlag_RXNE(USART2))

{

if (LL_USART_ReceiveData8(USART2)!='0'||0||"")

{

*(rx++)=LL_USART_ReceiveData8(USART2);

inc=inc+1;

LL_USART_ClearFlag_RTO(USART2);

}

}

void Configure_USART(void)

{

//LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);

LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_2, LL_GPIO_MODE_ALTERNATE); 

LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_2, LL_GPIO_AF_7);

 LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_2, LL_GPIO_SPEED_FREQ_HIGH);

 LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_2, LL_GPIO_OUTPUT_PUSHPULL);

 LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_2, LL_GPIO_PULL_UP);

LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE);

 LL_GPIO_SetAFPin_0_7 (GPIOA, LL_GPIO_PIN_3, LL_GPIO_AF_7);

 LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_3, LL_GPIO_SPEED_FREQ_HIGH);

 LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_3, LL_GPIO_PULL_UP);

LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);

LL_RCC_SetUSARTClockSource(LL_RCC_USART2_CLKSOURCE_PCLK1);

LL_USART_SetTransferDirection(USART2, LL_USART_DIRECTION_TX_RX);

LL_USART_EnableDirectionTx(USART2);

LL_USART_ConfigCharacter(USART2, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);

LL_USART_SetBaudRate(USART2, SystemCoreClock,LL_USART_OVERSAMPLING_16, 115200);

 LL_USART_SetHWFlowCtrl(USART2, LL_USART_HWCONTROL_CTS);

 LL_USART_SetOverSampling(USART2, LL_USART_OVERSAMPLING_16);

LL_USART_Enable(USART2);

NVIC_SetPriority(USART2_IRQn, 0);  

 NVIC_EnableIRQ(USART2_IRQn);

LL_USART_EnableIT_RXNE (USART2);

}

void SystemClock_Config(void)

{

 /* MSI configuration and activation */

 LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);

LL_RCC_MSI_EnableRangeSelection();

LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_7);

 LL_RCC_MSI_Enable();

 while(LL_RCC_MSI_IsReady() != 1) 

 {

 };

  

 /* Main PLL configuration and activation */

 LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2);

 LL_RCC_PLL_Enable();

 LL_RCC_PLL_EnableDomain_SYS();

 while(LL_RCC_PLL_IsReady() != 1) 

 {

 };

  

 /* Sysclk activation on the main PLL */

 LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);

 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);

 while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL) 

 {

 };

  

 /* Set APB1 & APB2 prescaler*/

 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);

 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);

 /* Set systick to 1ms in using frequency set to 80MHz */

 /* This frequency can be calculated through LL RCC macro */

 /* ex: __LL_RCC_CALC_PLLCLK_FREQ(__LL_RCC_CALC_MSI_FREQ(LL_RCC_MSIRANGESEL_RUN, LL_RCC_MSIRANGE_6), 

                 LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2)*/

 LL_Init1msTick(80000000);

  

 /* Update CMSIS variable (which can be updated also through SystemCoreClockUpdate function) */

 LL_SetSystemCoreClock(80000000);

}

Please help me.

Thank you.

13 REPLIES 13

Hi Pavel,

My task is to send some character string from Tx to Rx pin of same USART2. But, to the best of my knowledge, I think that during transmission, only a single character is taken from the string as the TDR register of Tx can hold only 1 byte. So, if I don't use interrupt and send all the characters, then Rx will not be able to sense the incoming characters and I don't see anything being updated in RxBuffer.

I have removed the below line. It was to check whether I am getting any of these characters in 2 subsequent iterations.

if (LL_USART_ReceiveData8(USART2)!='0'||0||"")

I hope my understanding is right and please correct me if I am wrong.

Hi waclawek,

I tried setting 4 MHz i.e., LL_RCC_MSIRANGE_6. But again the same problem. But this time the first 2 characters are getting repeated on 11th and 12th position in RxBuffer.

VDesa
Associate II

Hi All,

When I forcefully assigned the aRxBuffer, like the one shown below, the code worked.

*(rx)=LL_USART_ReceiveData8(USART2);

aRxBuffer[inc]=*(rx);

But I don't understand why it was not taking automatically since rx is defined as pointer to the aRxBuffer.