cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 G080RB USART1 Modbus RTU Master without RTOS and UART Interrupts

arunachalamram
Visitor

I am trying to configure STM32 G080RB as Modbus RTU Master to send commands to a slave and receive response. I have connected MAX485 - TTL to RS485 board. Powered with 5V, DE and RE connected to USART1 DE Pin. Board's A and B are connected to slave (VFD) at a distance of less than 2 meters.

I am able to send commands and slave works fine. The response from salve received is not echo of the command as expected. UART reports Parity error and Noise error :1h and 2h => 3h.

When the slave was connected to PC and same commands were sent using QModBus, slave works the same way (as expected) and response received is correct (echo of the command).

UART1 configuration:

huart1.Instance = USART1;

huart1.Init.BaudRate = 9600;

huart1.Init.WordLength = UART_WORDLENGTH_9B;

huart1.Init.StopBits = UART_STOPBITS_1;

huart1.Init.Parity = UART_PARITY_EVEN;

huart1.Init.Mode = UART_MODE_TX_RX;

huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

huart1.Init.OverSampling = UART_OVERSAMPLING_16;

huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;

huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;

huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

if (HAL_RS485Ex_Init(&huart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)

 

This is the send receive function and code:

void send_modbus_write_register(UART_HandleTypeDef *huart, uint16_t reg_addr,
uint16_t reg_value, const char* cmd_name)
{
uint8_t request[8], response[8];
int uart_receive_error = HAL_ERROR;

// Build Modbus frame

...


// TX PHASE
HAL_StatusTypeDef tx_status = HAL_UART_Transmit(huart, request, 8, 100);
if (tx_status != HAL_OK) {
printf("%s: UART Transmit Error[%d]\r\n", cmd_name, tx_status);
}

// RX PHASE
// RX PHASE - HAL manages DE automatically. You still need a small delay
// for the VFD *processing time* (Modbus turnaround delay).
// Add VFD *processing time* delay only (no pin switching delay needed)
HAL_Delay(50); // Increased delay to 100ms for safety

uart_receive_error = HAL_UART_Receive(huart, response, 8, 200);

// Debug print
printf("%s Request: ", cmd_name);
printHexArray(request, 8);
printf("%s Response: ", cmd_name);
printHexArray(response, 8);

if (uart_receive_error != HAL_OK) {
printf("%s: UART Receive Error[%d]\r\n", cmd_name, uart_receive_error);

...
}

This is the debug message:

Setting 40.00 Hertz
SET SPEED Request: Hex values to / from VFD: 0x01 0x06 0x20 0x01 0x0F 0xA0 0xD6 0x42
SET SPEED Response: Hex values to / from VFD: 0x1C 0x00 0x00 0x20 0x0A 0x00 0x00 0x00
SET SPEED: UART Receive Error[3]
Sending START signal
START Request: Hex values to / from VFD: 0x01 0x06 0x20 0x00 0x00 0x01 0x43 0xCA
START Response: Hex values to / from VFD: 0xF1 0x4F 0x00 0x08 0x68 0x02 0x00 0x20
START: UART Receive Error[3]
Sending STOP signal
STOP Request: Hex values to / from VFD: 0x01 0x06 0x20 0x00 0x00 0x05 0x42 0x09
STOP Response: Hex values to / from VFD: 0xF1 0x4F 0x00 0x08 0x68 0x02 0x00 0x20
STOP: UART Receive Error[3]

------------------------------------

I do not want to use manual DE / RE controlling / RTOS and Interrupt handling of UART Tx / Rx to make it simple.

Data sent by STM32 are received by slave but STM32 does not receive data sent by slave.

Any pointers?

1 REPLY 1
AScha.3
Super User

>The response from slave received ->UART reports Parity error and Noise error

Did you check with a scope, what signal really comes back to master ?

+

Do you have error handling , on receive : ( one (!) error stops uart, until you start it again ) ?

If you feel a post has answered your question, please click "Accept as Solution".