cancel
Showing results for 
Search instead for 
Did you mean: 

modbus with RS_485 communication

Lchal.1
Associate II

HI, i am using RS_485 as a serial communicator with modbus in stm32f103. But i am confused with TXEN pin used in Rs_485. i have read information it is used as transmitter and receiver . when transmitting the pin is set to high . while receiving it should be set to low. but i am confused how to write a code for it and where to use it . can anyone help me with it please.

HAL_GPIO_writePin(GPIO_PORT, rs_485_txen_Pin, GPIO_SET) // while Transmitting.

HAL_GPIO_writePin(GPIO_PORT, rs_485_txen_Pin, GPIO_RESET) // while Receiving.

i have written like this . is this valid code or should i add still or not. and in which part this code should be wriiten like before using HAL_UART_ Transmit() and HAL_UART_Receive() or can i use anywhere in my code. can anyone help me with please . if i need to add let me know what i need to add.

Thank you

3 REPLIES 3
KnarfB
Principal III

Set the transceiver chip to transmit immediatedly before you transmit something. Send it back to receive as soon as transmit finished.

Jack Peacock_2
Senior III

The USART should be configured for half duplex mode, meaning you cannot send and receive at the same time. The Modbus protocol is designed for this type of operation. The reason for half duplex is the shared serial bus for all nodes. Only one node at a time can transmit, but all others can receive (except the transmitting node). If two transmitters are on at the same time a collision occurs and data is lost.

Since STM32 USARTs are buffered you need to account for the time it takes to shift out the last byte of a transmission. That's why there's a separate transmission complete (TC) status and interrupt. You cannot disable the transmitter until the TC event occurs, otherwise you lose part of the last character and cause an error.

Handling the USART with RS-485 is more complex since you must manage the serial bus. At the end of a transmission there has to be a delay (i.e. the turnaround time) where the transmitter is disabled, allowing for the latency in handling the last data byte at the remote receiver. Ideally you want to disable the transmitter shortly after the TC event, which also enables the receiver for the response from the remote node.

Modbus expects one master node which manages the bus, originating addressable messages to other nodes in the network (either a broadcast or unicast to one node). Responses always go to the master node; two remote nodes cannot directly pass messages between each other.

If you use RTU mode Modbus (I.e. binary) you need to be careful about the inter-character and inter-message timing, since this is used to frame messages. I recommend using DMA for all transmissions to minimize inter-character delay. Do not use RTS-CTS flow control as this breaks RTU protocols (and there are no RTS/CTS signals on an RS-485 bus anyway).

Most RS-485 transceivers have separate TX and RX enable pins. This is so you can monitor your own transmissions by operating in full duplex to receive your own message back from the serial bus. It is a method to detect hardware faults, such as a stuck transmitter on a remote node or a missing termination resistor. If you don't need the fault detection, then connect the RX and TX enable pins together and configure for half duplex.

Aside from the complications, later STM32 USARTs have excellent support for Modbus, with address detection and idle frame mark sensing. Older STM32s like the 'F1 don't have this but it can be done in software.

Jack Peacock

i didn't understood clearly . can you help me how to start to write code for TXEN. i am confused .

HAL_GPIO_writePin(GPIO_PORT, rs_485_txen_Pin, GPIO_SET) // while Transmitting.

HAL_GPIO_writePin(GPIO_PORT, rs_485_txen_Pin, GPIO_RESET) // while Receiving.

whether i need to use this as condtion then use UART to transmit and receive;

if(HAL_GPIO_ReadPin(GPIO_PORT, rs_485_txen_Pin) == SET)

{

HAL_UART_Transmit(&huart1, buffer, 2,1000);

}

else if(HAL_GPIO_ReadPin(GPIO_PORT, rs_485_txen_Pin) == RESET)

{

 HAL_UART_Receive_IT(&huart1,(uint8_t *)Rx_Data,1);

}

can you say me if it is corrrect or not. If so how to write a code for it. Please help me with this .

Thank you