cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F3 USART Receive Interrupt hangs after receiving first set of data from Arduino

mj31382
Associate
Posted on May 20, 2014 at 14:34

hi, everyone.

i am using STM32F3 Discovery Kit to communicate with Arduino. i use EWARM IDE for coding and Putty, for serial terminal.

i did an echo test on stm32f3 usart2. The data is displayed on the serial terminal correctly, so i confirmed the usart communication is working as expected.

then, i try to transfer data from arduino to stm32f3 periodically but the usart on stm32f3 hangs after getting the first set of data (the stm32f3 debug shows the it keeps on checking USART_GetITStatus). The first set of the data is displayed on the serial terminal but most of the time, is garbled up with garbage characters.

i have been stuck for quite some time now. can anyone help? thanks in advance. Below is the coding i used for usart2. baudrate is set 9600.

/***********************************************************************************************************/

&sharpdefine LINEMAX 15 // Maximal allowed/expected line length

 

volatile char line_buffer[LINEMAX + 1]; // Holding buffer with space for terminating NUL

volatile int line_valid = 0;

/**

  * @brief  Initialize USART2 for PD6 (USART2_RX) and PD5 (USART2_TX)

  *         used for receiving mouse data from arduino

  * @param  baudrate; by default is 115200

  * @retval None

  * link: http://eliaselectronics.com/stm32f4-usart-example-with-interrupt/

  */

void init_USART2(int baudrate)

{

 USART_InitTypeDef USART_InitStructure;    // this is for the GPIO pins used as TX and R

 GPIO_InitTypeDef GPIO_InitStructure;      // this is for the USART1 initilization

 NVIC_InitTypeDef NVIC_InitStructure;      // this is used to configure the NVIC (nested vector interrupt controller)

 

 /* Configure USART1 pins:  Rx and Tx ----------------------------*/

 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);

 GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(GPIOD, &GPIO_InitStructure);   

 

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_7);

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_7);

 

 /* Configure USART1 pins:  --------------------------------------*/

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

 

 USART_DeInit(USART2);

 USART_InitStructure.USART_BaudRate = baudrate;

 USART_InitStructure.USART_WordLength = USART_WordLength_8b;

 USART_InitStructure.USART_StopBits = USART_StopBits_1;

 USART_InitStructure.USART_Parity = USART_Parity_No;

 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

 USART_Init(USART2,&USART_InitStructure);

 USART_Cmd(USART2, ENABLE);

 

 /* Here the USART2 receive interrupt is enabled

  * and the interrupt controller is configured

  * to jump to the USART2_IRQHandler() function

  * if the USART2 receive interrupt occurs

  */

 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // enable the USART2 receive interrupt

 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;        // we want to configure the USART1 interrupts

 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;         // this sets the priority group of the USART1 interrupts

 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // this sets the subpriority inside the group

 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // the USART2 interrupts are globally enabled

 NVIC_Init(&NVIC_InitStructure);        // the properties are passed to the NVIC_Init function which takes care of the low level stuff

 // finally this enables the complete USART2 peripheral

 USART_Cmd(USART2, ENABLE);

}

void serial_prints (USART_TypeDef* USARTx, volatile char *buffer)

{

/* transmit till NULL character is encountered */

while(*buffer)

{

 USART_SendData(USARTx, *buffer++);

 while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);

 delay_us(5);

}

}

void USART2_IRQHandler(void)

{

  static char rx_buffer[LINEMAX];   // Local holding buffer to build line

  static int rx_index = 0;

 

  if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) // Received character?

  {

char rx =  USART_ReceiveData(USART2);

 

if ((rx == '\r') || (rx == '\n')) // Is this an end-of-line condition, either will suffice?

{

if (rx_index != 0) // Line has some content?

memcpy((void *)line_buffer, rx_buffer, rx_index); // Copy to static line buffer from dynamic receive buffer

line_buffer[rx_index] = 0; // Add terminating NUL

line_valid = 1; // flag new line valid for processing

serial_prints(USART2, rx_buffer);    

rx_index = 0; // Reset content pointer

}

}

else

{

if (rx_index == LINEMAX) // If overflows pull back to start

rx_index = 0;

 

 rx_buffer[rx_index++] = rx; // Copy to buffer and increment

}

  }

}

/*********************************************************************************************************/

for arduino reference, i use the following code and the data is displayed correctly in the serial terminal.

printf(''%d, %d \n'', X, Y);

thanks in advance.

#usart #interrupt #stm32f3
1 REPLY 1
Posted on May 20, 2014 at 16:15

Yes, I wouldn't be back testing TXE, delaying, and otherwise dwelling in the USART IRQ Handler outputting data.

Fix the string output, and do it in the foreground task/loop from the buffer it's been copied too.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..