2023-09-07 03:21 AM - edited 2023-09-07 03:25 AM
Hello,
I'm new to STM controllers and working on a project where the STM gets data over serial line from another microcontroller. For this UART1 is turned active and mapped to ports PA_9 (TX) and PA_10 (RX), so data from other controller flows in on PA_10 (RX) pin.
For debugging purpose I directly watch serial data by connecting a serial port (RS-232) cable to these pins. For some unknown reason reception of data only works if UART1 is configured only for RX and TX is turned off on ST side:
/**
* @brief USART1 Initialization Function
* None
* @retval None
*/
static void MX_USART1_UART_Init(void)
{
printf("setup USART1\r\n");
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
(huart1 init mode set to UART_MODE_RX). I also reduced speed to 9600 Baud, because I need only to transfer 1-2 chars every other second.
UART1 is configured with global interrupt mode and my receive callback function looks roughly like
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) //if STM32 receives Data
{
if (Rx_indx == 0)
{
for (uint8_t i = 0; i < 2; i++) {
RxData[i] = 0;
}
printf("RxData cleared\r\n");
}
if (Rx_data[0] != 13) {
RxData[Rx_indx++] = Rx_data[0]; // add data to RxData buffer
}
else {
Rx_indx = 0;
printf("RxData = %02x %02x %02x %02x\r\n", RxData[0], RxData[1], RxData[2], RxData[3]);
if (RxData[0] == '0')
{
return;
}
// [...] processing received char codes etc.
}
HAL_UART_Receive_IT(&huart1, Rx_data, 1); // activate UART receive interrupt
}
Receiving one code is finished if I get CR char.
I have a global receive buffer:
uint8_t RxData[rxSIZE] = "00\r\n";
uint8_t Rx_data[2];
uint8_t Rx_indx;
UART1 receive interrupt is triggered in main() after configuration of peripherals:
/* 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_USART2_UART_Init();
MX_CAN1_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_TX_MAILBOX_EMPTY) != HAL_OK)
{
Error_Handler();
}
if (HAL_CAN_Start(&hcan1) != HAL_OK)
{
Error_Handler();
}
init();
//Activate UART interrupt
HAL_UART_Receive_IT(&huart1, Rx_data, 1);
Unfortunately I only get interrupt if I enter chars directly in serial console window but not if chars are sent over serial line (see attached picture, left serial console of cable connected to UART1 input pins, right: serial console of UART2 output port for debug printfs).
I'd be glad if anybody could give me any pointers why data sent over serial line does not trigger UART1 interrupt...
Thanks & Best Regards,
Lorky
2023-09-07 04:20 AM
Not exactly sure what the picture illustrates, but the printf() under interrupt context is not buffered and will block input for a dozen character times. Probably Ok for a human expecting it, less so for a machine blasting a string of characters at the input.
Check for and clear overrun or similar error status.
2023-09-07 11:52 PM
Hello @Tesla DeLorean ,
thanks for your reply. I tested without printf in HAL_UART_RxCpltCallback function but this makes no difference.
What I suspect is some difference between serial line input because if I send data from other microcontroller to STM UART1 input, I can see the data if I directly connect serial cable to RX pin (PA_10) (see screenshot below Putty windows: COM9 - serial console from controller that sends data, COM5 - serial console from cable directly connected to STM UART1 input pins (PA_9, PA_10), COM15 - serial console from cable directly connected to STM UART2 output pins (debug/printf redirection)).
It can be seen that UART1 RX interrupt fires once when directly entering data in Putty COM5 window, but never when data comes from other controller (debug xx commands on the left).
Thanks for any suggestions, Regards,
Lorky
2023-09-08 01:29 AM
Show us, how do you have connected things electrically. To me, it sounds that you are trying to tie together two transmitters. Observing signals using oscilloscope would be revelatory in such cases.
JW
2023-09-08 10:13 AM - edited 2023-09-08 10:14 AM
Still not clear if you're checking the UART for error/fault status
There's unbounded array indexs in the handler, and I don't see these being initialized. Should perhaps start by just echoing back the returned characters, directly, not in the array you subsequently create.
It could just be that it isn't receiving anything properly, there you'd need to look at the physical plumbing, levels, pin configurations, etc. Diagram your system, circuitry, or connectivity.
The STM32 is using CMOS levels, not RS232. Different boards, or MCU, would need a common ground.