Well, heres the code:
/* ---- Manchester Encode ----*/
unsigned int
manEncode(const unsigned char data) {
return ((unsigned int)((data[i] & 0xAA) | (~data[i] & 0xAA) >> 1)<<8) | ((data[i] & 0x55) | (~data[i] & 0x55) << 1);
}
/* ---- Manchester Decode ---- */
unsigned char
manDecode(const unsigned int data, unsigned char *error) {
unsigned char odd, even;
odd = data >> 8; // We want the upper 8 bits
if( (odd & 0xAA) ^ ((~odd & 0x55) << 1) ) {
*error = 1;
return 0;
} else
odd &= 0xAA;
even = data; // Will automatically cast, keeping only the lower 8 bits
if( (even & 0x55) ^ ((~even & 0xAA) >> 1) ) {
*error = 1;
return 0;
} else
even &= 0x55;
*error = 0;
return odd | even;
}
Please note, I cannot take credit for this code (maybe for porting it to Microchip C18 and getting rid of the global constant that was used in the original).
The original can be found here:
http://www.ottawarobotics.org/articles/rf/rf.html
which was found in this thread:
http://www.sparkfun.com/cgi-bin/phpbb/v … php?t=5369
The two functions I actually use just wrap these functions and include the transmission of the preamble, frame alignment, and identification codes, and look like the following:
/* * *
* Transmitter Code
*/
#define TX_PWR PORTBbits.RB0
void
main(void) {
unsigned char dat[2] = {0b00001111, 0b11110000};
... // Setup transmitter
sendData(dat, 2);
... // Do other stuff
}
/* ---- Send Data ---- */
void
sendData(const unsigned char *data, const unsigned char size) {
unsigned char i;
/* Power on the transmitter */
TX_PWR = 1;
Delay1KTCYx(1);
/* Send preamble */
for( i = 0; i < 5; i++ ) {
putcUSART(0x55);
while( BusyUSART() );
}
/* Send framing fix */
putcUSART(0b01000100);
while( BusyUSART() );
putcUSART(0b00010001);
while( BusyUSART() );
putcUSART(0b01000101);
while( BusyUSART() );
putcUSART(0b00010101);
while( BusyUSART() );
/* Send identification code */
putcUSART(0b01011001);
while( BusyUSART() );
putcUSART(0b01001010);
while( BusyUSART() );
putcUSART(0b10110010);
while( BusyUSART() );
/* Send data */
for( i = 0; i < size; i++ ) {
putcUSART((data[i] & 0xAA) | (~data[i] & 0xAA) >> 1);
while( BusyUSART() );
putcUSART((data[i] & 0x55) | (~data[i] & 0x55) << 1);
while( BusyUSART() );
}
/* Power off the transmitter */
Delay1KTCYx(1);
TX_PWR = 0;
}
/* * *
* Receiver Code
*/
void
main(void) {
unsigned char byte;
unsigned char test[3] = {0b01011001, 0b01001010, 0b10110010};
unsigned char i;
... // Setup receiver
while( 1 ) { // Loop, forever receiving data
PORTBbits.RB0 = 1; // Turn on receive LED
i = 0;
while( i < 3) {
if( PIR1bits.RCIF ) {
byte = getcUSART();
if( RCSTAbits.OERR ) {
RCSTAbits.CREN = 0;
RCSTAbits.CREN = 1;
break;
}
if( byte != test[i] )
break;
i++;
}
}
if( i == 3 ) {
PORTBbits.RB1 = 1; // Turn on valid receive LED
byte = getData(i); // Should check for error (check i)
byte = getData(i); // Should check for error (check i)
PORTBbits.RB1 = 0; // Turn off valid receive LED
}
PORTBbits.RB0 = 0; // Turn off receive LED
}
}
/* ---- Get Data ---- */
unsigned char
getData(unsigned char *error) {
unsigned char odd, even;
odd = getcUSART();
even = getcUSART();
if( (odd & 0xAA) ^ ((~odd & 0x55) << 1) ) {
*error = 1;
return 0;
} else
odd &= 0xAA;
if( (even & 0x55) ^ ((~even & 0xAA) >> 1) ) {
*error = 1;
return 0;
} else
even &= 0x55;
*error = 0;
return odd | even;
}
If you have any questions, just let me know, I didn’t bother to comment the stuff very well.
Also note, the Manchester encoding isn’t exactly what you might be taught, as the bits are no longer in order( ie, its not b7, b7’, b6, b6’, … b0, b0’, where bn is the nth bit, and bn’ is the nth bits compliment, its jumbled up, which saves on computation, but still ensures the same amount of DC balancing).
-Nate