cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 F103xx HAL UART echo

Tom Eaton
Associate II
Posted on August 29, 2017 at 18:15

I am trying to implement a simple echo program using the HAL drivers. Here is my code

#include 'stm32f1xx.h'
#include 'stm32f1xx_hal.h'
#include 'stm32f1xx_hal_conf.h'
void Error_Handler(void);
void SystemClock_Config(void);
void Startup_Sequence(void);
UART_HandleTypeDef UartHandle;
__IO ITStatus UartReady = RESET;
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) {
 UartReady = SET;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle) {
 UartReady = SET;
}
void USART1_IRQHandler(void) {
 HAL_UART_IRQHandler(&UartHandle);
}
int main(void) {
HAL_Init();
 SystemInit();
 SystemClock_Config();
 GPIO_InitTypeDef GPIO_InitStruct;
 // Enable GPIO and USART1 clocks.
 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOB_CLK_ENABLE();
 __HAL_RCC_USART1_CLK_ENABLE();
 // Setup LED pin
 GPIO_InitStruct.Pin = GPIO_PIN_15;
 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 // Setup UART TX Pin
 GPIO_InitStruct.Pin = GPIO_PIN_9;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_PULLUP;
 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 //Setup UART RX Pin
 GPIO_InitStruct.Pin = GPIO_PIN_10;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 HAL_Delay(1000);
 //Setup UART Instance
 UartHandle.Instance = USART1;
 UartHandle.Init.BaudRate = 9600;
 UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
 UartHandle.Init.StopBits = UART_STOPBITS_1;
 UartHandle.Init.Parity = UART_PARITY_NONE;
 UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 UartHandle.Init.Mode = UART_MODE_TX_RX;
 //Error handling
 if(HAL_UART_DeInit(&UartHandle) != HAL_OK) {
 Error_Handler();
 }
 if(HAL_UART_Init(&UartHandle) != HAL_OK) {
 Error_Handler();
 }
 HAL_NVIC_SetPriority(USART1_IRQn, 0, 1);
 HAL_NVIC_EnableIRQ(USART1_IRQn);
 uint8_t msg[] = '';
 Startup_Sequence();
 while(1) {
 if(HAL_UART_Transmit_IT(&UartHandle, &msg, sizeof(msg))!= HAL_OK) {
 Error_Handler();
 }
 while (UartReady != SET){}
 UartReady = RESET;
 if(HAL_UART_Receive_IT(&UartHandle, &msg, sizeof(msg)) != HAL_OK) {
 Error_Handler();
 }
 while (UartReady != SET){}
 UartReady = RESET;
 }
}
/**
 * Blinks external LED (PIN B15) if error encountered.
 */
void Error_Handler(void) {
 while(1) {
 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_15);
 HAL_Delay(1000);
 }
}
void Startup_Sequence(void) {
 int i;
 for(i=1;i<10; i++) {
 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_15);
 HAL_Delay(1000 * (1.0/i));
 }
 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);
}
void SystemClock_Config(void) {
 RCC_ClkInitTypeDef clkinitstruct = {0};
 RCC_OscInitTypeDef oscinitstruct = {0};
 oscinitstruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 oscinitstruct.HSEState = RCC_HSE_ON;
 oscinitstruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
 oscinitstruct.PLL.PLLState = RCC_PLL_ON;
 oscinitstruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
 oscinitstruct.PLL.PLLMUL = RCC_PLL_MUL9;
 if (HAL_RCC_OscConfig(&oscinitstruct)!= HAL_OK) {
 while(1);
 }
 clkinitstruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
 clkinitstruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 clkinitstruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 clkinitstruct.APB2CLKDivider = RCC_HCLK_DIV1;
 clkinitstruct.APB1CLKDivider = RCC_HCLK_DIV2;
 if (HAL_RCC_ClockConfig(&clkinitstruct, FLASH_LATENCY_2)!= HAL_OK) {
 while(1);
 }
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I am having problems with this however. Characters are being lost, I think because of an overrun. Below is an image of transmitted data vs received.

http://i.imgur.com/GTupBhK.png

So what must I change in my code to prevent an overrun?

Many thanks.

#stm32f1-uart #stm32
6 REPLIES 6
Posted on August 29, 2017 at 19:02

Hello!

>> uint8_t msg[] = '';

>> HAL_UART_Transmit_IT(&UartHandle, &msg, sizeof(msg)) >>

HAL_UART_Receive_IT(&UartHandle, &msg, sizeof(msg)

)  sizeof can not be used at runtime to take the length of a string. in your case msg has only one byte length.   msg is an array . you use this array indirectly (&)  try to define a buffer like uint8_t buf[50]; and use it like  

HAL_UART_Receive_IT(&UartHandle, buf, length

);  length is the number of bytes want to receive.  Regards  

Posted on August 29, 2017 at 19:46

>>So what must I change in my code to prevent an overrun?

Stop Blocking!! Start thinking/processing concurrently not sequentially.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 30, 2017 at 09:09

Please explain this more, this is the first time I have started developing for MCUs.

Posted on August 30, 2017 at 09:10

Thanks for the reply. So what do I do when I don't know how many bytes I want to receive?

Posted on August 30, 2017 at 17:49

This question is difficult to answer.

It depends to what you want to do. (some protocol etablished)

An approach is to wait for a single byte,

after to proccess the byte fast enough before the next byte arrives.

and after transmit or not an echo byte(or something other you want.)

But for sure must not blocking the execution by writing while(someting){;}

The TX part of USART must not blocked from RX part and vise versa.

Handle the RX and Tx part asynchronously . something like below

UartReadyTx must be set inside

HAL_UART_TxCpltCallback

UartReadyRx must be set inside

HAL_UART_RxCpltCallback

0690X0000060853QAA.png

Have a look also to this post of community

https://community.st.com/0D50X00009XkW2nSAF

Regards

vf

Posted on September 04, 2017 at 17:46

Thanks for the reply. I solved the problem by adding a 1ms character delay to characters sent to the STM32 to the PC.