2014-05-20 05:34 AM
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 NULvolatile 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 #stm32f32014-05-20 07:15 AM
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.