cancel
Showing results for 
Search instead for 
Did you mean: 

Baudrate issue with STM32F0 with Modbus implementation.

KRami
Associate II

Problem

i have configure Modbus over rs-485

While Receiving modbus data on rs485 on the baudrate it configured on, which is 115200 , it works fine.

but when i query modbus register to get value on different baudrate like 9600 , my board getting restart.

Hardware is working fine and having all pull-ups and termination registers.

there is observation while problem occurs,

USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE

over run error and frame error bits are set while problem occurs

Modbus Configuration:

void MX_USART1_UART_Init(void)

{

 huart1.Instance = USART1;

 

 huart1.Init.BaudRate = 115200;

 huart1.Init.WordLength = UART_WORDLENGTH_8B;

 huart1.Init.StopBits = UART_STOPBITS_1;

 huart1.Init.Parity = UART_PARITY_NONE;

 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.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_DMADISABLEONERROR_INIT;

 huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;

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

 {

    _Error_Handler(__FILE__, __LINE__);

 }

}

there are few changes/logics i have added in HAL layer, which are mentioned below.

1) while receiving data, i consider the buffer to be processed further when there is more than 3.5 character delay between the characters.

  • to do so, i have configured a timer and timeout value set as below,

/**

 * @brief Enables the MODBUS t3,5 char timer.

 * @param huart pointer to a UART_HandleTypeDef structure that contains

 *              the configuration information for the specified UART module.

 */

void UART_EnableT35(UART_HandleTypeDef* huart)

{

   assert_param(huart);

   // manually initialize registers for t3.5 timing

   huart->Instance->CR2 |= USART_CR2_RTOEN; // Receiver timeout enable

   huart->Instance->CR1 |= USART_CR1_RTOIE; // Receiver timeout interrupt enable

   huart->Instance->RTOR |= 38; // Receiver timeout value (11 * 3.5)

}

whenever timer time's out it raises an interrupt and on that interrupt i'm processing my buffer.

Note:

above logic is not originally comes with a standered library.

8 REPLIES 8
AvaTar
Lead

> but when i query modbus register to get value on different baudrate like 9600 , my board getting restart.

Most likely from a watchdog, activated by some opaque Cube code.

I don't use Cube.

> While Receiving modbus data on rs485 on the baudrate it configured on, which is 115200 , it works fine.

Modbus RTU is specified only up to 38,4kBaud.

You will hardly find many devices working with higher rates.

And the device with the lowest upper limit in the network will restrict the actual possible settings.

KRami
Associate II

@Community member​  : Thanks for the response.

> Modbus RTU is specified only up to 38,4kBaud.

is there any document which specify this standards ?

I will try with lower baud rate and let you know.

> I don't use Cube

because of the complexity of the components we have to use cube for the connections , is there any possible solution i can try ?

KRami
Associate II

Hello @Community member​  ,

As you suggest , i tried to lower the baudrate, i set it 38400 ,

if works fine when i try to query at 38400 baudrate.

but when i tried to query device at 9600 baud rate , i'm still getting the same issue. board is keep on restarting.

> is there any document which specify this standards ?

Get the documents, like from modbus.org. The specs have no official status, there is no international norm.

However, said documents "end" at 38,4kBaud. You can support higher baudrates, but market facts (other devices) will limit the usability.

The modbus is over 30 years old, and thus characterizes requirements and capabilities of slightly "outdated" hardware.

For high throughputs, consider Modbus TCP.

> but when i tried to query device at 9600 baud rate , i'm still getting the same issue. board is keep on restarting.

As said, check your Cube code for references to WDG/IWDG code. It might activate it without you having asked for it ...

> because of the complexity of the components we have to use cube for the connections

That is really a matter of perspective.

IMHO Cube rather obfuscates and complicates things, instead of making it easier.

At least when you leave the narrow path their pre-defined use cases and examples.

KRami
Associate II

Hello @Community member​ ,

I have tried one more thing,

After Disabling this below function (containing 3.5 character delay) , now my board is not getting restart when i query modbus at 9600 baud-rate , but modbus functionality is also not working, i am not able to read or write in any registers in modbus after this change even at 115200 baud-rate.

/**

 * @brief Enables the MODBUS t3,5 char timer.

 * @param huart pointer to a UART_HandleTypeDef structure that contains

 *              the configuration information for the specified UART module.

 */

void UART_EnableT35(UART_HandleTypeDef* huart)

{

   assert_param(huart);

   // manually initialize registers for t3.5 timing

   huart->Instance->CR2 |= USART_CR2_RTOEN; // Receiver timeout enable

   huart->Instance->CR1 |= USART_CR1_RTOIE; // Receiver timeout interrupt enable

   huart->Instance->RTOR |= 38; // Receiver timeout value (11 * 3.5)

}

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

is this above settings are proper ?

> After Disabling this below function (containing 3.5 character delay) , now my board is not getting restart when i query modbus at 9600 baud-rate ...

I think you need to investigate deeper. "Getting restarted" probably means Cube enabled a watchdog behind your back, and it is not served.

The second issue - check that ALL interrupts are handled.

> huart->Instance->CR1 |= USART_CR1_RTOIE; // Receiver timeout interrupt enable

There should be an interrupt handler associated.

Additionally, check for receive errors (error, nois, overflow) in the UART interrupt handlers. If you do not clear this flags, yo will not receive anything subsequently.

As said, I do not use Cube, the code hurts my eyes...

Hello @Community member​  ,

In this case we are actually working on 115200 Baud rate as a Slave and But once we start sending query at 9600 baud rate from master we are getting Board Reboot because of Watch Dog, So we assume that data other than set baud rate needs to be ignored at HAL Layer itself once we clear the flag and ISR should not come recursively and should not affect ISR to stuck.

We have checked with WD OFF and we can see it is there is continuously going in ISR only for serial and doesn’t Reboot and using code without cube MX will be difficult at this stage as 90% code is done, still we can try later without cube MX but if you can suggest some specific things so we can go ahead with it to solve the issue.

> ... we are getting Board Reboot because of Watch Dog,

You have the options to either remove the watchdog code, or keep it and serve it properly.

> We have checked with WD OFF and we can see it is there is continuously going in ISR only for serial.

This is IMHO a bug you need to fix.

Probably you do not check/reset all interrupt flags, and thus it re-enters immediately.

Since it happens only at a low baudrate (9600), and not 115200, presumably related to timing (receiver timeout).

Debug the serial interrupt handler, and check all interrupt-causing flags at exit.

Be aware that debuggers can be intrusive.