2021-06-05 02:42 PM
I'm using STM32F103C8T6 processor with an 8MHz internal clock, 9600 baud rate, 8bit + 1stop bit and no parity. For receiving uart data, I'm using a global interrupt.
While I'm receiving data with usart1 or usart2, I can not receive null bytes. Now I already try to turn off all other peripheries. I'm did not help. I also turn on internal pullups on usart2 to test if that was a problem. The end result was negative.
My global usart1 handler is very simple. Every byte that I receive, is sent back to the computer with usart1.
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
LCD_port_var.LCD_RX_State = HAL_UART_Receive_IT(&huart1,LCD_port_var.LCD_RX_Buffer,1);
Send_data_userP(&huart1,LCD_port_var.LCD_RX_Buffer);
/* USER CODE END USART1_IRQn 1 */
}
Initialization sequence. Was generated with STMCube.
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
Picture below is showing send data to MCU with blue color and received data back to the computer with red color. The null bytes are missing.
What can I do.
2021-06-05 03:00 PM
What does Send_data_userP do? Note that you should be using separate TX and RX buffers, but probably doesn't affect anything if you're doing 1 character at a time at low rates.
2021-06-05 03:02 PM
The "Send_data_userP" is just data transmit with selected usart.
void Send_data_userP(UART_HandleTypeDef *huart, char *string)
{
//---Send_data---//
HAL_UART_Transmit(huart,(uint8_t *) string, strlen((const char *)string), 2000); // transmit in blocking mode
}
2021-06-05 03:04 PM
2021-06-05 03:14 PM
Note that this would have been caught had you been monitoring the return status from HAL_UART_Transmit.
2021-06-05 03:19 PM
OK so now I add HAL_Uart_transmit directly to the usart1 global interrupt handler. Is a little better but there are still some bytes missing.
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
LCD_port_var.LCD_RX_State = HAL_UART_Receive_IT(&huart1,LCD_port_var.LCD_RX_Buffer,1);
HAL_UART_Transmit(&huart1,LCD_port_var.LCD_RX_Buffer,1, 2000); // transmit in blocking mode
//Send_data_userP(&huart1,LCD_port_var.LCD_RX_Buffer);
/* USER CODE END USART1_IRQn 1 */
}
2021-06-06 08:13 AM
Since HAL_UART_Transmit blocks, the system isn't ready to receive the next byte by the time it arrives. If your incoming data has pauses between bytes, it would work okay. Blocking functions in IRQ handlers often causes issues like this.
A better method would be to store incoming data into a FIFO and send out when ready.
2021-06-06 01:32 PM
Ok I will try it.