
La codifica Manchester permette la trasmissione dei dati e del clock in un unico pattern seriale, per questo viene utilizzata frequentemente nelle trasmissioni digitali in Radio Frequenza a basso costo. E' una particolare tecnica di modulazione bifase (BPSK, Binary Phase Shift Key) che consente di compattare al massimo il volume di dati trasmessi e di inglobare il segnale di sincronismo nello stesso stream dati. La codifica manchester è definita, inoltre, autosincronizzante ed è stata sviluppata come riporta anche il nome, dai ricercatori dell'Università di Manchester. Ecco come funziona e come implementarla su un PIC.
LA CODIFICA MANCHESTER
Il formato Manchester codifica un dato digitale non come livello di tensione statico, bensì come transazione da livello alto a livello basso per un ”1” logico e da livello basso a livello alto per uno “0” logico. In figura 1 è riportato un tipico stream dati codificato Manchester.
Il valore della componente continua di uno stream in codifica Manchester è sempre nullo e questo consente di decodificare facilmente i dati oltre che ad implementare un controllo di errore senza troppe difficoltà. Prima della decodifica vera e propria, il segnale viene trattato da un circuito detto data slice che provvede a generare dei livelli di tensione compresi tra 0 ed il positivo di alimentazione. Un data slice è sostanzialmente un comparatore rigenerativo a valle di un filtro passa basso come mostrato in figura 2.
La costante di tempo del filtro passa basso dovrà essere dimensionata in modo da essere maggiore del periodo del segnale di ingresso. Il vero processo di decodifica viene fatto con un microcontrollore mediante un algoritmo che associa “0” o “1” alle varie transazioni del segnale di ingresso.
Gli “Illegal codes”
Per quanto visto, nella codifica Manchester ciascun bit è espresso come una transazione 1-0 o 0-1 quindi a ciascun bit dato corrisponde una coppia di livelli. Ad esempio la stringa dati 0-1-1-1-1-0-0-1 viene codificata come 01-10-10-10-10-01-01-10. Questo porta a due conseguenze fondamentali: la prima è che per la trasmissione di un bit fisicamente ne devono essere trasmessi due e questo comporta una occupazione di banda maggiore; la seconda è che solo le coppie 01 e 10 codificano rispettivamente i bit 0 e 1 quindi le coppie 00 e 11 (cosiddette “illegal codes”) possono essere utilizzate per il controllo di errore nella trasmissione. Nella presente trattazione verrà illustrato come trasmettere una stringa di dati su una linea RS232 ad 8 bit dati, utilizzando la codifica Manchester pertanto potrà essere utilizzata la stringa “00-00-11-11” come controllo start/stop. Si noti che questa stringa ha la particolarità di avere una componente continua nulla ed una sola transazione da 0 a 1.
Come includere i Manchester bit nella comunicazione RS232
Per sfruttare la comunicazione RS232 al fine di trasmettere/ricevere dati in codifica Manchester, verrà utilizzata la configurazione 8-N-2 ovvero 8 bit di dati, nessuna parità e 2 stop bit. Il bus seriale sarà quindi caratterizzato da sequenze del tipo:
…MMSDDDDDDDDPPSDDDDDDDDPPMMMM….
dove M indica che il bus non è utilizzato (livello logico “1”), S è lo start bit (livello logico “0”), D è il bit dati, P è lo stop bit (livello logico “1”). Per quanto esposto finora in un byte RS232 verranno quindi codificati 4 bit Manchester.
IMPLEMENTAZIONE SU PIC
Verrà adesso illustrato come inviare e ricevere dati codificati Manchester sfruttando la RS232 su un microcontrollore PIC. Le routine sono espresse in linguaggio C per il compilatore PICC di CCS. Si supponga di dover trasmettere il dato esadecimale 0x41. In binario tale dato corrisponde alla stringa 0100 0001 e poiché i bit vengono trasmessi a partire da quello meno significativo, lo stream dati sarà 1000 0010. I 4 bit meno significativi del dato saranno quindi trasmessi come 1000 e tale stringa codificata Manchester diviene: 10-01-01-01 (ovvero 0xA9). I 4 bit più significativi vengono trasmessi come 0100 che, codificati, divengono 01-01-10-01 (ovvero 0x9A). Per la trasmissione di 0x41 saranno dunque sufficienti due chiamate della putc():
putc(0xA9); //lower nibble
putc(0x9A); //upper nibble
La codifica vera e propria può essere fatta dalla routine SEND_DATA il cui codice è riportato nel listato 1.
void SEND_DATA(BYTE txbyte) { int i,j,b,me; b = txbyte; for (i=0; i<2; i++) { me = 0; for (j=0 ; j<4; j++) { me >>=2; if (bit_test(b,0) ) me |= 0b01000000; // 1->0 else me |= 0b10000000; // 0->1 b >>=1; } putc(me); } }
Listato 1 |
La fine di una trasmissione viene segnalata inviando il byte 0xF0 ovvero la stringa di controllo 00-00-11-11 vista precedentemente. La trasmissione di tale stringa viene fatta semplicemente con la chiamata putc(0xF0). Per quanto riguarda la decodifica, il data slice viene fatto via software quindi vengono decodificati i bit. La routine che provvede a questo è la DECODE_DATA il cui codice è riportato nel listato 2.
BYTE DECODE_DATA(BYTE encoded) { BYTE i,dec,enc,pattern; enc = encoded; if (enc == 0xf0) return 0xf0; dec = 0; for (i=0; i<4; i++) { dec >>=1; pattern = enc & 0b11; if (pattern == 0b01) // 1 bit_set(dec,3); else if (pattern == 0b10) bit_clear(dec,3); // 0 else return 0xff; // illegal code enc >>=2; } return dec; }
Listato 2 |
GESTIONE DELLA CODIFICA MANCHESTER IN MIKROBASIC
Anche il popolarissimo mikroBASIC prevede la gestione della comunicazione dati con codifica Manchester su RS232. Le routine disponibili sono sette:
Man_Receive_Config
Prepara il PIC alla ricezione di un segnale. I parametri da specificare sono la porta e il pin sul quale arriverà il segnale seriale. Nel caso si verifichino errori in ricezione è necessario richiamare la funzione Man_Receive_Init al fine di ristabilire la sincronizzazione.
Man_Receive_Init
È analoga alla precedente, ma necessita solo della porta di comunicazione come parametro. Il pin di ricezione è sempre il pin 6.
Man_Receive
Ritorna il byte opportunamente decodificato. Come parametro richiede un byte che viene utilizzato come flag di errore (vale 255 in caso di errori in ricezione).
Man_Send_Config
Prepara il PIC per una trasmissione dati. Richiede come parametri la porta e il pin usato come output. Il baud rate è fissato a 500bps.
Man_Send_Init
È analoga alla precedente, ma necessita solo della porta di comunicazione come parametro. Il pin di uscita è per default il pin 0 della porta specificata. Il baud rate è fissato a 500bps.
Man_Send
Invia il byte specificato come parametro
Man_Synchro
Ritorna la metà della lunghezza di un bit Manchester. La lunghezza è data in multipli di 10 microsecondi. Come esempio di applicazione delle routine mikroBASIC, il listato 3 riporta un semplice programma per la trasmissione di un messaggio in codifica Manchester.
program RF_TX dim i as byte dim msg as string[20] main: msg = “Hello World!” PORTB = 0 ‘ Initialize port TRISB = %00001110 ClearBit(INTCON, GIE) ‘ Disable interrupts Man_Send_Init(PORTB) ‘ Initialize Manchester sender while TRUE Man_Send($0B) ‘ Send start marker Delay_ms(100) ‘ Wait for a while for i = 1 to Strlen(msg) Man_Send(msg[i]) ‘ Send char Delay_ms(90) next i Man_Send($0E) ‘ Send end marker Delay_ms(1000) wend end.
Listato 3 |
Il messaggio deve essere delimitato dai codici 0x0B e 0x0E. Il listato 4 riporta invece la routine di ricezione del messaggio. L’hardware a cui fare riferimento è illu- strato in figura 3.
Il micro utilizzato sia dal trasmettitore che dal ricevitore è un PIC16F877A ed il dato viene inviato in RF a 433MHz utilizzando un trasmettitore RT4 e ricevuto da un modulo RR3. Il dato ricevuto viene visualizzato sul un diplay LCD alfanumerico.
program RRX dim error, ErrorCount, temp as byte main: ErrorCount = 0 TRISB = 0 CMCON = 7 Lcd_Init(PORTB) ‘ Initialize LCD on PORTB Lcd_Cmd(LCD_CLEAR) Man_Receive_Config(PORTA,3) ‘ Configure and synchronize receiver while true do Lcd_Cmd(Lcd_FIRST_ROW) while true do ‘ Wait for the start marker temp = Man_Receive(error) if temp = $0B then break end if ‘ We got the starting sequence if error then ‘ Exit so we do not loop forever break end if wend do temp = Man_Receive(error) ‘ Attempt byte receive if error = true then Lcd_Chr_Cp(63) ‘ ASCII for ‘?’ Inc(ErrorCount) if ErrorCount > 20 then Man_Receive_Init(PORTA) ‘ alternative: ‘ temp = Man_Synchro ErrorCount = 0 end if else if temp <> $0E then ‘ Don’t print the end marker on LCD Lcd_Chr_Cp(temp) end if Delay_ms(20) end if loop until temp = $0E wend end.
Listato 4 |

Nell’ambito della codifica manchester c’e anche quella differenziale che ha una maggiore immunita’ al rumore, con algoritmi di controllo un po’ piu’ complessi.