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
CVoro
Associate II

Hello Vibha,

I have reviewed your code considering the issue you have described, currently I am unable to understand the issue as your pointer arithmetics as well as other logic related things seem correct to me. However, where does this come from:

inc=inc+1;

Keep me updated on your findings.

VDesa
Associate II

Hello Christian,

Thank you for your reply! I used the variable 'inc' in order to know whether the particular loop is getting entered or not. I watched the variable 'inc' in watch window.

The issue is when i watch aRxBuffer in watch window, it shows:

aRxBuffer[0]=0x00

aRxBuffer[1]=0x00

aRxBuffer[2]='T'

aRxBuffer[3]='A'

aRxBuffer[4]='N'

aRxBuffer[5]='T'

aRxBuffer[6]='R'

aRxBuffer[7]='A'

aRxBuffer[8]='G'

aRxBuffer[9]='Y'

aRxBuffer[10]='A'

aRxBuffer[0]='A'

aRxBuffer[0]='N'

My question is why the 0th and 1st position are empty?

> LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_7);

MSI range 7 is 8MHz

  

> LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_MSI, LL_RCC_PLLM_DIV_1, 40, LL_RCC_PLLR_DIV_2);

8MHz / 1 * 40 / 2 = 160MHz

That's way too much, maximum PLL output and system clock is 80MHz.

JW

Should also start with the 4 MHz MSI, as I recall.

One should test output, and print out clock statistics without reprogramming clocks/plls, confirm that works, then increase the speeds.

One might also want to try HAL code examples to confirm behaviour there.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Line noise? You don't have an external-pull up on the pin?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Pavel A.
Evangelist III

1. Do not do this in a interrupt handler:

while (!LL_USART_IsActiveFlag_RXNE(USART2)){}

It could be some other interrupt, not RXNE. Handle it and return ASAP.

2. This line does not do what you think. Fix it.

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

-- pa

T J
Lead

use the DMA, is works perfectly...

VDesa
Associate II

Hi TJ,

I used DMA, and as you said, it worked well. But since we are building it in a resource constrained system, I do not want to go for DMA.

Hi,

I have not connected an external pull up on the pin. I have simply shorted Tx and Rx pins in the Nucleo-L476RG board. Please suggest regarding this.