fundstück aus dem web, hoffe es hilft dir.
lG
XCyber
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,
http://www.linxtechnologies.com> and <http://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 */
}