Regarding the listed subject, the following is a way that seems like a good way to do it using a standard UART and a minimum of software overhead. Comments appreciated, Randy Perrin Message-Id: <199905031614.MAA22075@p1.acadia.net> Date: Mon, 03 May 1999 12:14:07 -0400 To: forum@ibsystems.com From: Steve Bohrer Subject: Re: Manchester encoding/decoding in software for standard UART In-Reply-To: <199904291039.DAA19824@larry.ibsystems.com> As noted by Paul Yamkovoy, Fred Skalka, and others, Manchester encoding in general is a scheme where each transmitted data bit is followed by its complement, so that there is no net DC level. The effect is that the longest "run-of-identical-bits" is two: there are never more than two ones or two zeros transmitted in a row, no matter what data is sent. "Real" Manchester encoding uses hardware to split each bit transmission time into two phases, and complements the second phase. But, you can certainly send "almost Manchester" encoded data by encoding each byte as two bytes, with each data bit followed by its complement. (Clearly, this cuts the effective data rate in half!) The UART will add the standard start and stop bits to each byte, but the resulting bit stream still has only two-bit long runs, since there is a one bit run at each end of the encoded data. (However, you can not delay between bytes in a packet, as the idle time between bytes is not balanced) This scheme is useful with some low cost digital radios which use "on-off" keying rather than FSK or another more complex scheme (see, for example, www.linxtechnologies.com and www.rfm.com). The receivers in such systems use the average received signal level to set the threshold between a one and a zero. Thus, Manchester encoded data will bias the system to the optimum threshold. Essentially, if you consider every other bit to be the "data", only the nybbles 0x5, 0x6, 0x9, and 0xA have the pattern of "data bit followed by its complement", so all your data gets encoded into combinations of these nybbles. Each two bits becomes four: orig data (bit cpl bit cpl) hex nybble 00 ==> 0 1 0 1 = 5 01 ==> 0 1 1 0 = 6 10 ==> 1 0 0 1 = 9 11 ==> 1 0 1 0 = A So, you need software routine which takes a byte, and returns two bytes encoded such that each bit from the original byte is followed by its complement. Then, send these two bytes out with the standard UART. If you encode all the bits in order, as follows (~x represents complement of bit x) orig. data ms encoded ls encoded 7 6 5 4 3 2 1 0 ==> 7 ~7 6 ~6 5 ~5 4 ~4 3 ~3 2 ~2 1 ~1 0 ~0 then you are in for a bunch of shifting and bit diddling for each data byte. Better is to encode alternate bits in each byte, so you can process four bits at a time, and just shift, mask, complement, and then or the bits together to get each encoded byte. For example, encode the odd bits in the ms byte, and the even bits in the ls: orig. data ms encoded ls encoded 7 6 5 4 3 2 1 0 ==> 7 ~7 5 ~5 3 ~3 1 ~1 ~6 6 ~4 4 ~2 2 ~0 0 For example, to encode the odd bits, take the original data, copy and complement it, and then AND each with 0xAA to clear the even bits. Shift the complement right 1 spot, and OR with the original. This lets you encode (at the transmitter) and decode (at the receiver) each data byte relatively quickly. ("Quickly enough" depends on your baud rate, crystal, other cpu tasks, etc. We use a fairly pokey 4800 baud, and thus have no trouble keeping up with the data with a 3.6864 MHz 8031.) It is possible to use tables to encode/decode, with the usual size/speed trade-off. But, for my compiler, the "C" table lookup is not any faster than the assembly shift and mask, so I use math rather than the table. Here is sample C code: typedef unsigned char uchar; /* to avoid typing "unsigned" all the time */ typedef unsigned short ushort; enum {false, true}; /* for bit flags */ extern bit manErrFlg; /* set this flag if an invalid byte is received */ /* NOTE: For example only. You decide how to signal a receive error */ /* Manchester encode byte c as two bytes: Odd bits in MS byte, Even in LS */ ushort manEncode(uchar c) { uchar ms, ls; ms = (c & 0xAA) | ((~c & 0xAA)>>1); /* encode odd bits w/ their cpls */ ls = (c & 0x55) | ((~c & 0x55)<<1); /* now even bits */ return ((ushort)ms << 8) | ls; /* build two bytes into a short */ } /* decode odd bits from MS byte, even bits from LS byte. If mc is not */ /* valid (bits don't match complements) then set manErrFlg and return 0 */ uchar manDecode(ushort mc) { uchar ms, ls; ms = (uchar)(mc >> 8); /* get ms byte from short */ if ( (ms & 0xAA) ^ ((~ms & 0x55) << 1) ) { manErrFlg = true; /* odd bits != complement of their complements */ return 0; /* so flag the error and punt */ } else ms &= 0xAA; /* otherwise, valid data, so just clear cpls */ ls = (uchar)mc; /* now test even bits... */ if ( (ls & 0x55) ^ ((~ls & 0xAA)>>1) ) { manErrFlg = true; return 0; } else ls &= 0x55; /* valid, so clear complements */ manErrFlg = false; return ms | ls; /* OR original odd and even bits back together */ }