USART Rx & Tx communication code
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 12:53 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 2:01 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 2:45 AM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 4:39 AM
> 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 5:46 AM
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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 5:48 AM
Line noise? You don't have an external-pull up on the pin?
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 1:37 PM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-10 3:42 PM
use the DMA, is works perfectly...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-12 12:58 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-11-12 1:00 AM
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.
