I am currently working on the half duplex RS485 Network related stuff.
It seems that, the most popular implementation is to use the 9th-Bit (Parity Bit) as an identifier to identify the Address-bytes and Data-bytes.
For most micro-controllers, they do support such a mechanism, for example AT91SAM7Sxxx.
According to the AT91SAM7S Series Preliminary: 31.6.3.6 Multidrop Mode This mode differentiates the data characters and the address characters. Data is transmitted with the parity bit at 0 and addresses are transmitted with the parity bit at 1. 31.6.6 RS485 Mode The USART features the RS485 mode to enable line driver control. The behavior of the RTS pin is controlled by the TXEMPTY bit.
# SENDA: Send Address 0: No effect. 1: In Multidrop Mode only, the next character written to the US_THR is sent with the address bit set.
# PARE: Parity Error Interrupt Enable
What software needs to do:
For Master/Transmitter 1. Set 'Multidrop Mode' on 2. Set SENDA bit 3. Send an Address-byte 4. Send the Data-bytes
For Master/Receiver General half duplex Receiver
For Slave/Transmitter General half duplex Transmitter
For Slave/Receiver 1. Interrupted by a 'Parity Error Interrupt', check the Address-byte. 2. If the Address-byte is correct, receive the following Data-bytes.
Unfortunately, LPC2xxx does not support such a mechanism; so I will have to implement it by software:
For Master/Transmitter 1. Poll UART Line Status Register to see if 'Transmitter Empty' is true. 2. Turn off the UART FIFO. 3. Set 'Forced "1" stick parity' and enable it in UART Line Control Register. 4. Send an Address-byte. 5. Poll UART Line Status Register to see if 'Transmitter Empty' is true. 6. Disable 'parity generation and checking' in UART Line Control Register. 7. Turn on the UART FIFO. 8. Send the Data-bytes.
For Master/Receiver General half duplex Receiver.
For Slave/Transmitter General half duplex Transmitter.
For Slave/Receiver 1. Interrupted by every incoming bytes, check if 'Parity Error' happens. 2. If 'Parity Error' happens, check the Address-byte. 3. If the Address-byte is correct, receive the following Data-bytes.
In the olden days, the micro-controllers were not very powerful, so we had to reduce the communication load. But for now, LPC2xxx is a 32bits micro-controller, usually running on 48MHz, I think it is powerful enough. And if my understanding is correct (not confident), I don't see any communication load reduction with LPC2xxx and 9th-Bit mechanism.
Thus, is it a good idea, to use a packet instead of a byte? maybe 140 bytes or 1524 bytes for a packet, including both address and data. (SMS message or Ethernet packet) Though our system requirement is not well defined. I believe the communication load will not be heavy, maybe several kilo-bytes a day. If this is a practicable idea, then how can I implement it? I am not smart, so it is better to follow a existing small protocol, but I almost don't know anything about network protocols, which one should I choose?
Please correct me and give me some hints. Many thanks in advance.
Of course you can use packets. The cpu is fast enough and more importantly: It has RAM enough to buffer full packets.
But note one thing about the ninth address bit contra packets: You need to let your processors be able to synchronize somehow. You can't use all eight bits in a packet but would require that a packet is stuffed so that you have an unique way to detect the start of a new frame. If not, then the other processors that reboots or gets connected while transfers are already ongoing or gets a transfer error would never be able to figure out what represents a packet.
The stuffing may use a magic character only allowed as start-of-frame. Possibly another for end-of-frame (to inform when silence is likely). Or the stuffing may allow all bytes to be used in a packat but with the limitation that a specific byte value may not happen twice directly after each other unless used to synchronize the start of a new packet.
One thing: Are you sure you should select so big packets as a full kB? You will likely run with way lower baudrates than Ethernet, in which case the maximum packet size will affect latencies in the network, i.e. how soon you may finish the transfer of a low-priority packet and be able to start with a high-priority packet.
http://datacomm.org/rfc.html
RFC 1149 - A Standard for the Transmission of IP Datagrams on Avian Carriers, D. Waitzman, 4/1/1990, 2 pp.
Hi Per,
Many Thanks for all your help.
> It has RAM enough to buffer full packets.
I have 32kB SRAM on LPC2378, I assume that my RS485 buffer size must be larger than my packet size. If so, how large will be an proper buffer size? 2 times larger, or 4 times larger?
I didn't know things about start-of-frame / end-of-frame / bit-stuffing / bit-destuffing, so I read some articles, after that, I think, I will simplify these issues at this stage.
Now I know that 1524 bytes for a packet is not a good idea.
My plan is:
packet size: 160 bytes RS485 buffer size: 320 bytes start of frame: 0x88 + 0x88, 2 bytes The content of packet: ASCII characters only, 0x00 to 0x7F end of frame: 0x8F + 0x8F, 2 bytes It will look like this: {0x88,0x88}CMD=Command|Item=Data|Ack=OK/Err|{CRC}{0x8F,0x8F}
The detailed rule for send/receive/Ack is still under considering. (Is there any tips?)
Many thanks.
Lost one thing.
packet size: 160 bytes RS485 buffer size: 320 bytes start of frame: 0x88 + 0x88, 2 bytes address byte: 1 byte The content of packet: ASCII characters only, 0x00 to 0x7F end of frame: 0x8F + 0x8F, 2 bytes It will look like this: {0x88,0x88}{address}CMD=Command|Item=Data|Ack=OK/Err|{CRC}{0x8F,0x8F}
My very simple rules for send/receive/Ack:
For information gathering:
Master sends a REQUEST packet out, and waits for an INFO packet. Each slaves receive the REQUEST packet, only the target slave sends an INFO packet back.
If Master does not receive an INFO packet within 0.1 second (roughly), Master resends a REQUEST packet for at most 3 times (roughly).
-> Target Slave Down. -> Master receives the INFO packet.
For heartbeat detection:
Master sends a HEARTBEAT packet out, and waits for an Ack. Each slaves receive the HEARTBEAT packet, only the target slave sends an Ack back.
If Master does not receive an Ack within 0.1 second (roughly), Master resends a HEARTBEAT packet for at most 3 times (roughly).
-> Target Slave Down. -> Target Slave Running.
For command execution:
Master sends a COMMAND packet out, and waits for an Ack. Each slaves receive the COMMAND packet, only the target slave sends an Ack back.
If Master does not receive an Ack within 0.1 second (roughly), Master resends a COMMAND packet for at most 3 times (roughly).
-> Target Slave Down. -> Target Slave receives COMMAND.