Hi,
I am currently testing the USART on my STM32F103C8 Blue Pill, which I should be able to send text to and it will echo back anything typed and respond to various commands.
I'm finding something a little odd, though. It prints the start up messages fine and goes into the main loop to wait for characters from the USART, which it echoes back to the terminal. The problem is it ignores the first 10 chars every time it restarts. Every time.
Here's the basic code:
/* Initialize all configured peripherals */ MX_GPIO_Init(); MX_TIM2_Init(CLKSPD); MX_TIM3_Init(); MX_USART2_UART_Init(); // Clear the terminal window HAL_UART_Transmit(&huart2, (uint8_t *)12, 1, HAL_MAX_DELAY); // Start progress logging HAL_UART_Transmit(&huart2, (uint8_t *)"GPIO, Timers and UART set up.\r\n", 32, HAL_MAX_DELAY); /* USER CODE BEGIN 2 */ HAL_TIM_Base_Start(&htim2); HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); HAL_TIM_Base_Start(&htim3); HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); HAL_UART_Transmit(&huart2, (uint8_t *)"Clock outputs enabled.\r\n", 26, HAL_MAX_DELAY); //__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer, RXBUFFERSIZE); HAL_UART_Transmit(&huart2, (uint8_t *)"aRxBuffer set up.\r\n", 21, HAL_MAX_DELAY); // USART INTERRUPTS NVIC_SetPriority(USART2_IRQn, 0); NVIC_EnableIRQ(USART2_IRQn); /* USER CODE END 2 */ HAL_UART_Transmit(&huart2, (uint8_t *)"USART Interrupts enabled.\r\n", 28, HAL_MAX_DELAY); /* Infinite loop */ /* USER CODE BEGIN WHILE */ uint8_t buffer[40] = ""; int bufferRxPtr = 0; uint8_t CR[4] = "\r\n"; HAL_UART_Transmit(&huart2, (uint8_t *)"Entering main loop...\r\n", 24, HAL_MAX_DELAY); while (1) { HAL_UART_Receive(&huart2, &buffer[bufferRxPtr], 1, HAL_MAX_DELAY); if (buffer[bufferRxPtr] == 13) { // CR & LF HAL_UART_Transmit(&huart2, CR, sizeof(CR), HAL_MAX_DELAY); bufferRxPtr = 0; } else if (buffer[bufferRxPtr] == 35) { // End of Line char '#' detected - interpret command buffer[bufferRxPtr] = '\0'; bufferRxPtr = 0; HAL_UART_Transmit(&huart2, CR, sizeof(CR), HAL_MAX_DELAY); // Check for command char at the start of the buffer if (buffer[0] == 37) { // Now get the command switch (buffer[1]) { case 67: // Uppercase C case 99: // Lowercase c ToggleClkSpeed(true, buffer[2]); break; case 82: // Uppercase R case 114: // Lowercase r HAL_UART_Transmit(&huart2, (uint8_t *)"Resetting...\r\n", 14, HAL_MAX_DELAY); SystemReset(); break; case 83: // Uppercase S case 115: // Lowercase s HAL_UART_Transmit(&huart2, (uint8_t *)"%S", 2, HAL_MAX_DELAY); HAL_UART_Transmit(&huart2, &CLKSPD, 1, HAL_MAX_DELAY); HAL_UART_Transmit(&huart2, (uint8_t *)"#", 1, HAL_MAX_DELAY); break; case 88: // Uppercase X case 120: // Lowercase x ToggleClkSpeed(false, buffer[2]); break; default: HAL_UART_Transmit(&huart2, (uint8_t *)"Unrecognised command: ", 22, HAL_MAX_DELAY); HAL_UART_Transmit(&huart2, buffer, strlen((char*)buffer), HAL_MAX_DELAY); HAL_UART_Transmit(&huart2, CR, sizeof(CR), HAL_MAX_DELAY); break; } } } else { HAL_UART_Transmit(&huart2, &buffer[bufferRxPtr], 1, HAL_MAX_DELAY); // Check for potential buffer overflow if (bufferRxPtr > sizeof(buffer) - 2) { bufferRxPtr = 0; } else { bufferRxPtr += 1; } }
Now, I know it's not interrupt driven, I'm just trying to get the basics working first. In the terminal window, on reset, I'm seeing everything up to "Entering main loop..." - I then have to tap a key 11 times - on the 11th time, I see the char echoed back in the terminal window.
Any ideas why it's ignoring me for 10 chars?
>>with one of those cheap ST-LINK V2 devices you can get on eBay (so not the full debugger one you get from STM.)
Ok, so why wouldn't that debug in exactly the same way as any other external, or on-board, ST-LINK? Keil doesn't know the difference.
Most probable reason for data loss is that HAL_UART_Transmit() blocks for dozens of character times, and you're not concurrently receiving data.
You should manage data reception in an interrupt, with reasonably deep buffering.
... is that HAL_UART_Transmit() blocks for dozens of character times
I don't think that's the case here.
OP speaks of "tapping keys", so sounds like the input data is being provided manually - so unlikely to be overrunning ?