2020-04-07 01:52 PM
Hello,
I'm working with an STM32G4 MCU and I want to listen the UART3 with interruption. I am testing with a code which changes the color of a led. The following code works fine :
//main.c
#include "main.h"
FDCAN_HandleTypeDef hfdcan3;
FDCAN_HandleTypeDef hfdcan4;
char uart3_buffer[64]={0};
uint8_t RxChar3;
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FDCAN3_Init();
MX_UART4_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* Listen the USART3. */
HAL_UART_Receive_IT(&huart3, &RxChar3, 1);
/* Copy only the non null characters into the buffer. */
if(RxChar3==49){ // ASCII of character 1.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
}
else if(RxChar3==50){ // ASCII of character 2.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);/* Function to light on a led activating a GPIO. */
}
else if(RxChar3==51){ // ASCII of character 3.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
}
/* Sends the current value of Rxchar3 variable (only for debugging). */
snprintf(uart3_buffer, sizeof(uart3_buffer), "Rxchar3: %u\n", RxChar3);
HAL_UART_Transmit(&huart3, (uint8_t*)uart3_buffer, strlen(uart3_buffer), 0xFFFFFFFF);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Nevertheless, as I have more than one than one serial port configured in the MCU I want to put the 'HAL_UART_Receive_IT' function within another function which receives as input parameter the number of serial interface. I have done as follows:
main.c
//main.c
FDCAN_HandleTypeDef hfdcan3;
FDCAN_HandleTypeDef hfdcan4;
char uart3_buffer[64]={0};
uint8_t RxChar3;
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FDCAN3_Init();
MX_UART4_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* Listen the USART3. */
UART_RX_String01(3); // Listen UART3
/* Copy only the non null characters into the buffer. */
if(RxChar3==49){ // ASCII of character 1.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
}
else if(RxChar3==50){ // ASCII of character 2.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);/* Function to light on a led activating a GPIO. */
}
else if(RxChar3==51){ // ASCII of character 3.
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_1, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_RESET); /* Function to power off a led deactivating a GPIO. */
}
else{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET); /* Function to light on a led activating a GPIO. */
}
/* Sends the current value of Rxchar3 variable (only for debugging). */
snprintf(uart3_buffer, sizeof(uart3_buffer), "Rxchar3: %u\n", RxChar3);
HAL_UART_Transmit(&huart3, (uint8_t*)uart3_buffer, strlen(uart3_buffer), 0xFFFFFFFF);
HAL_Delay(500);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
uart_func.h
//uart_func.h
#ifndef INC_UART_FUNCTIONS_H_
#define INC_UART_FUNCTIONS_H_
#include "stm32g4xx_hal.h"
extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart4;
void UART_RX_String01(uint8_t);
#endif /* INC_UART_FUNCTIONS_H_ */
uart_func.c
//uart_func.c
#include "uart_func.h"
void UART_RX_String01(uint8_t port_number){
uint8_t RxStringBuffer;
HAL_StatusTypeDef RX_State;
/* Select the UART port to be listened. */
if (port_number==3){
RX_State = HAL_UART_Receive_IT(&huart3, &RxStringBuffer, 1);
/* Send the function's return value. */
snprintf(uart_buffer, sizeof(uart_buffer), "Rx State %u", RX_State);
HAL_UART_Transmit(&huart3, (uint8_t*)uart_buffer, strlen(uart_buffer), 0xFFFFFFFF);
}
if (port_number==4){
RX_State = HAL_UART_Receive_IT(&huart4, &RxStringBuffer, 1);
/* Send the function's return value. */
snprintf(uart_buffer, sizeof(uart_buffer), "Rx State %u", RX_State);
HAL_UART_Transmit(&huart4, (uint8_t*)uart_buffer, strlen(uart_buffer), 0xFFFFFFFF);
}
}
The 'main.h' header file includes the 'uart_func.h' header. The problem I have with this is that in this case the MCU blocks around 20 seconds when I send a character to the serial interface. Then it continues turning. Why does this happen? Or isn't it possible to call this function out of the main.c ?
2020-04-16 11:30 PM
Exactly.
In order to be properly sent, data (located at an address in stack when declared as local) should remain consistent until transfer is completed : that's why it works when adding a delay. Without delay, after function exits, stack content is overwritten by further functions calls and parameters of your code.
Using HAL, use of a buffer declared as local as in your example, is possible only with "polling mode" function : HAL_UART_Transmit()
This function exits only when transfer is completed, so msg buffer content could be overwrtitten without impacting the transfer.
Regards
2021-12-09 08:31 AM
Totally agree...