2017-08-29 09:15 AM
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 #stm322017-08-29 10:02 AM
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
2017-08-29 10:46 AM
>>So what must I change in my code to prevent an overrun?
Stop Blocking!! Start thinking/processing concurrently not sequentially.
2017-08-30 02:09 AM
Please explain this more, this is the first time I have started developing for MCUs.
2017-08-30 02:10 AM
Thanks for the reply. So what do I do when I don't know how many bytes I want to receive?
2017-08-30 10:49 AM
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
Have a look also to this post of community
https://community.st.com/0D50X00009XkW2nSAF
Regards
vf
2017-09-04 10:46 AM
Thanks for the reply. I solved the problem by adding a 1ms character delay to characters sent to the STM32 to the PC.