STM32 UART shows inconsistent outputs
From what I understand, the UART gets a char/byte one by one. I am trying to test this by adding '-' between each character of the string I send to the UART. However, the outputted values are very inconsistent when more than 1 character is sent to the UART.
When 1 character is sent via serial console,
the output is correct: A-
When more than 1 character is sent, for example:
input:ABCDEFGH
output:A-C-F-H
The outputted values are different when sending the same string multiple times.
What is the cause of this issue and how do I get it to consistently receive and output data?
Thank you for your help.
uint8_t byte;
int main(void)
{
HAL_Init();
SystemClock_Config();
PeriphCommonClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
while (1)
{
HAL_UART_Receive_IT(&huart6, &byte, sizeof(byte));
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
uint8_t ya[]="-";
if (huart->Instance == USART6)
{
HAL_UART_Receive_IT(&huart6, &byte, sizeof(byte));
HAL_UART_Transmit(&huart6, &byte, sizeof(byte), 0);
HAL_UART_Transmit(&huart6, &ya, sizeof(ya), 0);
}
}Edit 1:
I have tried updating the code and using HAL_UART_Transmit_IT() without the hyphen in between characters. The output consistently missing the consecutive character. E.g.
input:ABCD
output:AC
Could this imply that using interrupts is too slow? If so, would polling or DMA be quicker?
Edit 2:
I have updated my code and tried using flags and avoiding using the blocking function in the callback loop.
The aim of this uart is to only get values within '[' and ']'.
E.g. data "abc" is received when "[abc]" is sent to the uart.
However, I noticed that there are 2 problems:
- The code outputs garbage text e.g. ˆ.
- The uart only receives once. I have to manually press reset for it to receive data again.
//Note: string format: [abcedfg]
char getChar=0; //get character
int read_flag=0;
int stop_reading_flag=0;
char str[100]; //string
int main(void)
{
HAL_Init();
SystemClock_Config();
PeriphCommonClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_USART6_UART_Init();
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart6, &getChar, 1);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(stop_reading_flag==1)
{
HAL_UART_Transmit(&huart6, str, strlen(str),0);
stop_reading_flag=0;
memset(str, 0, sizeof(str)); //flush string
}
}
/* USER CODE END 3 */
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART6)
{
if (byte=='[') //Start reading from UART
{
read_flag=1;
stop_reading_flag=0;
}
else if (byte==']') //Stop reading from UART
{
read_flag=0;
stop_reading_flag=1;
}
else if (read_flag==1)
{
strncat(str,getChar,1); //appends to string
}
byte=0; //flush buffer
HAL_UART_Receive_IT(&huart6, &getChar, 1);// start the next round of reception
}
}
static void MX_USART6_UART_Init(void)
{
/* USER CODE BEGIN USART6_Init 0 */
/* USER CODE END USART6_Init 0 */
/* USER CODE BEGIN USART6_Init 1 */
/* USER CODE END USART6_Init 1 */
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
huart6.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart6.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart6) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART6_Init 2 */
/* USER CODE END USART6_Init 2 */
}