![]() |
Technical Articles |
This is the home of Potificus, technical Guru of GadgetWerks. Please feel free to contact Pontificus with any questions of a technical nature by clicking this link. All questions will be answered discretely. Select answers will be published on this page and a special reward will be sent out to the originator at the sole discretion of Gadgetwerks. |
Gadgeticus®
08apr05 Part of the “Grazing the technical grass” series by PONTIFICUS This months topic: Serial Data Communications As an ancient observer I’ve watched with some amusement as, over the years, terms and definitions that I thought were written in stone (pun un-intentional) have evolved till they bear little resemblance to their original meaning. RS-232 is a case in point. It is one of the oldest, most widely used and most widely mis-understood specifications in the computer world today. Perhaps I can push back the cloying mists of obscurity and allow the clear light of truth to shine through (colored, of course, by my own biases and precepts). Since the early days I’ve heard RS-232 referred to as a “protocol” specification. It is not, has never been, will never be a protocol specification or definition. What it actually is is a specification of a serial communication transport system. In other words, it specifies a group of data and flow-control signals and their associated signal levels and timing requirements. It defines signal type and minimum transmitter and receiver parameters, rough cable requirements and maximum bit-rate, etc. In order to make sense of the signal names and intents you need also to understand that RS-232 was designed to address communications between a computer or terminal (DTE, data terminal equipment) and a modem (DCE, data communication equipment). Many of the control signals were therefore designed to control the operation of the modem, or at least to hand-shake with it. Given that understanding, here is a look
at the most commonly used signals: SIGNAL GROUND TRANSMIT DATA (TxD) RECEIVE DATA (RxD) A note from Pontificus: REQUEST TO SEND (RTS) First, the term is derived from the terms “modulate” and “demodulate”; ergo, modem. This is relevant because (most common) modems communicated with each other over phone lines. They did this by means of a modulated carrier (no, we are absolutely not going to discuss carriers, modulation schemes…..). Second, the modem could be configured so that the carrier was always on or was “keyed on” (controlled) by the DTE. So the signal that keys the carrier on/off is RTS. This tells the modem to turn on the carrier and get ready to modulate it with data. This would be a necessary step prior to sending data. CLEAR TO SEND (CTS) · DTE asserts RTS DATA TERMINAL READY (DTR) DATA SET READY (DSR) DATA CARRIER DETECT (DCD) Because most of today’s serial communications applications don’t require modems we can safely ignore the rest of the signals defined by RS-232 and concentrate on the ones named above. What we see most often today is a host computer (a PC or other) and one or more peripheral computers connected via either RS-232 or RS-422/485 interfaces. These systems tend to want to use the minimum number of signal wires and the maximum reliable speed (bit-rate). In these cases the minimum implementation is quite often seen; GND, TxD & RxD. Given that today’s computers (even embedded ones) have a great deal of processing power compared to those of previous centuries, it is reasonable to drop the hardware handshake (RTS/CTS, etc.) and do it in software instead (as part of the communications protocol (more on this later)). The next most common RS-232 implementation is the 5-wire interface, consisting of GND, TxD, RxD, RTS & CTS. The addition of RTS & CTS provides for flow control or “pacing”. Typically, RTS from each end goes to CTS on the other end. Each end then follows the simple rule that it can only transmit when its CTS is asserted; thus when one end is in danger of having buffer over-runs, or is otherwise too busy, it can de-assert its RTS which removes the other ends CTS which stops the transmission till RTS is re-asserted. Pontificus realizes that some implementations have made use of the other signals (DCD, DTR & DSR) but their usefulness is quite rare, and they usually just need to be strapped somewhere somehow. This is the only reason we’re discussing them here. In order to understand why we have to care about DCD, DTR & DSR we need to say something about UARTs. First, what the heck does it mean? It means Universal Asyncronous Receiver / Transmitter. When Pontificus was a lad a serial interface was made up of 10 to 15 discrete SSI ICs. Sometime later this stuff was integrated into an LSI IC called a UART. A common feature of UARTs is that they assumed they were connected to a modem, and they tried to assist in the flow-control tasks. For instance their receiver circuits wouldn’t work unless DCD was asserted, and they would give an error if DSR de-asserted. This situation persisted for many years, but with the advent of highly-integrated microcontrollers things changed a bit. When the UART was integrated into the microcontroller DCD and DSR were relegated to being status signals rather than controlling signals. In other words the CPU could read the state of these signals but communications didn’t depend on it. (Pontificus likes this; it makes life easier) Still, you will find many systems in today’s world which have discrete LSI UARTs. In fact it is still common to have to jumper (strap) DCD and DSR to DTR on one or both ends of a communications channel. DTR is a controllable output, and strapping it to DCD and DSR allows you to control their state. Another common practice is to connect RTS to CTS at each end. This makes the three-wire RS-232 interface possible (GND, TxD & RxD). A Word About Signal Levels The spec requires that the negative rest-state be </= –3VDC and the positive rest-state be >/= +3VDC. The actual range is –3 to –25VDC on the negative side and +3 to +25VDC on the positive side. In ancient times common practice was to use + & - 12VDC power supplies for the RS-232 drivers, so the rest-state was either + or – 12VDC. In more recent times we mostly see special RS-232 interface ICs which run off of +5VDC and include boost and inversion circuitry to produce internal supplies of somewhere in the range of +/- 7 to +/- 10VDC. While this is lower than the older situation it is still well within spec and perfectly acceptable. Typical examples of such ICs would be the MAX232 from Maxim or DS14C232 from National Semiconductor. In addition to the two rest-states the signal has two other states, i.e. the transition from “rest-at-minus” to “rest-at-positive”, and the transition from “rest-at-positive” to “rest-at-minus”. The RS-232 spec has definite things to say about the speed at which the signal moves from one rest-state to the other. In fact, they say that the speed shouldn’t exceed 30V / micro-second. This restriction is included to limit the amount of “cross-talk” in the cable (signal interference between wires – and yes, it does depend significantly on transition speed). So now that we know the four possible states of the signal(s) we might say something about which state they might be expected to be in. We will define the TxD signal from the output pin on the sending UART to the input pin (RxD) on the receiving UART. By definition the TxD pin of the UART rests hi (typically at or near +5V) when it isn’t asserted; that pin is wired to the transmit driver, which is an inverter with a boosted power supply, whose output must be in the range of –3 to –25VDC. The output of the transmit driver is connected to the communication cable and eventually arrives at the other end’s RS-232 receiver. This is a device whose input can withstand (typically) +/- 30VDC. It is also an inverter, so when its input is negative its output, which is tied to the RxD pin on the local UART, is positive. Therefore, we can see that a signal from one UART to the other is inverted twice which is equivalent to no inversion, and if the TxD pin on the transmitting UART is hi the receive pin on the other UART is also hi. Before we close out this section we probably should say a bit about communication speed. Pontificus was aware, even before putting pen to paper, that many of you would say “yo, Ponti’ baby, everyone knows what 2400-baud means”, whereupon we say unto you “I doubt that very much, pizza-boy”. First, as was mention in the first paragraph of this rant, the original meaning of things get lost, or at least shifted, so those of you who think that “Baud” means bits-per-second are… In the beginning there was some Frenchy guy named Baudot. For some inexplicable reason he was allowed to define the term “Baud”, which he defined as: bits-per-second divided by bits-per-character. So what the term really means is Characters-per-second. Got that? Not bits-per-second, characters-per-second. Well, if we will discuss characters-per-second we might want to know how many bits make up a character. Those of you who jump up and shout “8 bits” should stagger on back to the back of the class. You can’t define bits-per-character without first deciding if you’ll be using synchronous or asynchronous communications. If your communications method is synchronous you most likely will indeed be using 8-bit characters. However, the really widely used method is asynchronous, so we’ll discuss that and ignore the other one. Remember that serial communications, and especially the RS-232 specification, had their genesis in teletype communications. The teletype was a strange and ungainly beast which no really intelligent species would ever invent. We bring it up because the standard bits-per-character that we use today evolved from it, but we will speak no more of it. Anyone who has written a serial communications driver for a standard UART knows that you may choose 5, 7 or 8 data-bits per character (Pontificus knows of UARTs which allow 9). The 5 or 7 choices come directly from the teletype. No “right-thinking” person would choose them, although in fact some systems do still use 7 (Pontificus is nowhere near smart enough to understand or explain human nature, so we’ll just accept that on its face and go on). So you might say “OK, we’ll choose 8 bits-per-character” and that’s the end of the story. Again, you’re wrong. Remember that we’ve decided this is asynchronous communications. What we mean by that is that the transmitting end and receiving end aren’t necessarily synchronized. This is a key issue in serial communications and it needs to be understood. Synchronous communications typically requires that the clock (or timing information) be sent with the data (that’s why its called synchro..). This requires more complex and expensive hardware on each end of the link, which is why the asynchronous method is vastly more popular. In asynchronous communications synchronization is performed for each character. This is accomplished by surrounding the data bits with a start-bit and at least one stop-bit (could be two but is usually one). In addition, in order to aid in error detection, you can also choose to include a “parity” bit. So now your 8-bit character is 10, 11 or 12 bits. Anyone else want to jump up and say “I know what 2400 baud means”? All that aside, the electronics industry has produced a set of standard bit-rates (bits-per-second) that pretty much everyone adheres to. Ignoring teletypes, they are: 600, 1200, 2400, 4800, 9600, 19200 and 38400. I know that some higher ones have come into vogue recently, but we don’t need to consider them; the vast majority of applications will be somewhere between 2400 and 38400, and I don’t recall ever seeing a bit-rate that wasn’t one of the ones listed above. We can’t leave this part of the discussion without considering just what is meant by a “bit” (at least as it applies to RS-232 serial communications). Recall that in a previous paragraph we said that the UART’s transmitter pin was resting hi (at or near +5VDC for instance). For all UARTs that I’ve ever dealt with this is the “idle” state of the output, and also represents a logical “0”. So when communications isn’t occurring the UART’s transmitter is sending a constant “0”, and the RxD pin of the receiving UART is seeing this “0”. Both UARTs define a start-bit as a “low” on the TxD / RxD pins (which corresponds to a “1”). Suppose we consider one “character-envelop” of 1 start-bit, 8 data-bits, no parity-bit and 1 stop-bit. This gives us the minimum envelop of 10 bits. If we have chosen a bit-rate of 9600 bits-per-second (hereinafter bps) we see that we can transmit a character in 0.00104 seconds, or about 960 characters per second (1/9600 yields a “bit-cell” of 0.0001042 seconds, times 10-bits/char = 0.001042 seconds per char; 1/0.001042 = 960). The concept of a “bit-cell” is important. If your bit-rate is 9600bps the start-bit, each data bit and the stop-bit all have a “validity-window” of 1/9600 seconds. The way that the transmitter and receiver synchronize is thus: by definition the transmitting UART’s TxD pin idles hi (0); the first bit of any character is, by definition, the start-bit which is always a low (1). The receiving UART also idles as long as its RxD pin remains hi. When the RxD pin goes low for at least 60% (typically) of the bit-cell the UART recognizes it as a valid start-bit and then starts looking for data bits, etc. So the start-bit provides synchronization for the rest of the character. A word about errors. In today’s world, with PCs being connected together with short RS-232 or RS-422/485 links, you don’t see much trouble with errors. And even if they do occur the communication drivers on each end tend to be pretty well written and provide (usually) transparent error correction and recovery. Back in the days when everything went
over 1200 or 2400 bps modems it was a different story. Telephone voice-grade
(3002) lines are notoriously noisy; using them for data communications
can be quite an adventure. Although the comm. drivers sometimes included
either simple or complex error detection/correction/recovery schemes,
the hardware transport system (RS-232) also provided for minimal error
detection. This was done by including a “parity” bit with
the data bits. The parity bit is defined thusly: So if odd parity is selected, and the receiving UART sees an even number of “1” bits, this means that at least one bit got changed during transmission. The work of processing the parity bit is handled by the hardware in the UART; the comm. drivers only chose odd or even (or no) parity. The receiving UART would also report an error (parity error, of course) if the received character had the wrong number of “1” bits.
The term “Protocol”, in this context, means (to me) the set of rules that govern the transmission and receipt of messages over the serial link. Think of it as the recipe by which the serial cake is baked. So a protocol is something of a central issue to the communication driver on each end of the link. The protocol can be fairly simple or quite complex; it depends mostly on the communications medium (phone lines, rf or hardwired) and the “hardness” required (hardness, in this instance, refers to the amount of error detection/recovery required). If two computers 20 feet apart need to communicate at low speed a simple RS-232 interface will probably suffice, and if its done correctly you can almost guarantee no errors. This situation requires little in the way of error correction/recovery in the comm. driver. If, on the other hand, you need to communicate between two computers on opposite sides of a large industrial park you have a much more difficult problem. In this case the choice of transport medium is crucial; you can choose RF with modems, phone lines with modems or, perhaps, RS-422/485 without modems. No matter which of these three options you choose you must assume that you will have communications errors do deal with. If you’re working in an (assumed)
error-free environment the serial comm. driver isn’t terribly difficult
to write. Your protocol would include: Do you recall the famous “N-8-1” sequence in the old DOS comm. setup? N(o parity), 8(data-bits), 1(stop-bit). In addition, your protocol might want to include such things as message byte-count, command code and data-field definitions, etc. It might also want to include a message parity scheme and ACK(knowledge) / NAK(negative acknowledge) and transmission re-try and such. If your application must deal with communication errors the driver protocol gets much more complex. You will probably want more than one layer of error detection/correction/recovery. You will have to develop a complex mix of ACK/NAK and transmission re-try / abort schemes. Pontificus shudders at the thought. Positively shudders. |
| back to top
| Home | PolyCom
| DACC | SBC | MaxTerm
| New Products |
Technical Articles | Order | WebRing
| Links |
|
|
Technical Support: techsupport@gadgetwerksinc.com
|