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.
2018-11-10 02: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.
2018-11-10 02: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?
2018-11-10 04: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
2018-11-10 05: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.
2018-11-10 05:48 AM
Line noise? You don't have an external-pull up on the pin?
2018-11-10 01: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
2018-11-10 03:42 PM
use the DMA, is works perfectly...
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.
2018-11-12 01: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.