Manchester Code Library

The mikroC PRO for PIC provides a library for handling Manchester coded signals. The Manchester code is a code in which data and clock signals are combined to form a single self-synchronizing data stream; each encoded bit contains a transition at the midpoint of a bit period, the direction of transition determines whether the bit is 0 or 1; the second half is the true bit value and the first half is the complement of the true bit value (as shown in the figure below).

Manchester signal format

  Important :

External dependencies of Manchester Code Library

The following variables must be defined in all projects using Manchester Code Library: Description: Example:
extern sfr sbit MANRXPIN; Receive line. sbit MANRXPIN at RC0_bit;
extern sfr sbit MANTXPIN; Transmit line. sbit MANTXPIN at RC1_bit;
extern sfr sbit MANRXPIN_Direction; Direction of the Receive pin. sbit MANRXPIN_Direction at TRISC0_bit;
extern sfr sbit MANTXPIN_Direction; Direction of the Transmit pin. sbit MANTXPIN_Direction at TRISC1_bit;

Library Routines

The following routines are for the internal use by compiler only:

Man_Receive_Init

Prototype

unsigned int Man_Receive_Init();

Returns

  • 0 - if initialization and synchronization were successful.
  • 1 - upon unsuccessful synchronization.
  • 255 - upon user abort.

Description

The function configures Receiver pin and performs synchronization procedure in order to retrieve baud rate out of the incoming signal.

  Note : In case of multiple persistent errors on reception, the user should call this routine once again or Man_Synchro routine to enable synchronization.
Requires Global variables :
  • MANRXPIN : Receive line
  • MANRXPIN_Direction : Direction of the receive pin
must be defined before using this function.
Example
// Initialize Receiver
sbit MANRXPIN at RC0_bit;
sbit MANRXPIN_Direction at TRISC0_bit;
...
Man_Receive_Init();

Man_Receive

Prototype

unsigned char Man_Receive(unsigned char *error);

Returns

A byte read from the incoming signal.

Description

The function extracts one byte from incoming signal.

Parameters :

  • error: error flag. If signal format does not match the expected, the error flag will be set to non-zero.

Requires

To use this function, the user must prepare the MCU for receiving. See Man_Receive_Init.

Example
unsigned char data = 0, error = 0;
...
data = Man_Receive(&error);
if (error)
  { /* error handling */ }

Man_Send_Init

Prototype

void Man_Send_Init();

Returns

Nothing.

Description

The function configures Transmitter pin.

Requires Global variables :
  • MANTXPIN : Transmit line
  • MANTXPIN_Direction : Direction of the transmit pin
must be defined before using this function.
Example
// Initialize Transmitter:
sbit MANTXPIN at RC1_bit;
sbit MANTXPIN_Direction at TRISC1_bit;
...
Man_Send_Init();

Man_Send

Prototype

void Man_Send(unsigned char tr_data);

Returns

Nothing.

Description

Sends one byte.

Parameters :

  • tr_data: data to be sent

  Note : Baud rate used is 500 bps.
Requires

To use this function, the user must prepare the MCU for sending. See Man_Send_Init.

Example
unsigned char msg;
...
Man_Send(msg);

Man_Synchro

Prototype

unsigned char Man_Synchro();

Returns
  • 255 - if synchronization was not successful.
  • Half of the manchester bit length, given in multiples of 10us - upon successful synchronization.
Description

Measures half of the manchester bit length with 10us resolution.

Requires

To use this function, you must first prepare the MCU for receiving. See Man_Receive_Init.

Example
unsigned int man__half_bit_len;
...
man__half_bit_len = Man_Synchro();

Man_Break

Prototype

void Man_Break();

Returns

Nothing.

Description

Man_Receive is blocking routine and it can block the program flow. Call this routine from interrupt to unblock the program execution. This mechanism is similar to WDT.

  Note : Interrupts should be disabled before using Manchester routines again (see note at the top of this page).
Requires

Nothing.

Example
char data1, error, counter = 0;

void interrupt {

  if (INTCON.T0IF) {
    if (counter >= 20) {
      Man_Break();
      counter = 0;              // reset counter
    }
    else
      counter++;                // increment counter

    INTCON.T0IF = 0;            // Clear Timer0 overflow interrupt flag

    }
}

void main() {

  OPTION_REG = 0x04;            // TMR0 prescaler set to 1:32

  ...

  Man_Receive_Init();

  ...
  
  // try Man_Receive with blocking prevention mechanism
  INTCON.GIE = 1;               // Global interrupt enable
  INTCON.T0IE = 1;              // Enable Timer0 overflow interrupt
  data1 = Man_Receive(&error);
  INTCON.GIE = 0;               // Global interrupt disable

  ...

}

Library Example

The following code is code for the Manchester receiver, it shows how to use the Manchester Library for receiving data:

Copy Code To ClipboardCopy Code To Clipboard
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections


// Manchester module connections
sbit MANRXPIN at RC0_bit;
sbit MANRXPIN_Direction at TRISC0_bit;
sbit MANTXPIN at RC1_bit;
sbit MANTXPIN_Direction at TRISC1_bit;
// End Manchester module connections

char error, ErrorCount, temp;

void main() {
  ErrorCount = 0;
  ANSEL  = 0;                                     // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                                   // Disable comparators
  C2ON_bit = 0;
  TRISC.F5 = 0;
  Lcd_Init();                                     // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                            // Clear LCD display

  Man_Receive_Init();                             // Initialize Receiver
  
  while (1) {                                     // Endless loop

      Lcd_Cmd(_LCD_FIRST_ROW);                    // Move cursor to the 1st row
       
      while (1) {                                 // Wait for the "start" byte
        temp = Man_Receive(&error);               // Attempt byte receive 
        if (temp == 0x0B)                         // "Start" byte, see Transmitter example
          break;                                  // We got the starting sequence
        if (error)                                // Exit so we do not loop forever
          break;
        }
        
      do
        {
          temp = Man_Receive(&error);             // Attempt byte receive
          if (error) {                            // If error occured
            Lcd_Chr_CP('?');                      // Write question mark on LCD
            ErrorCount++;                         // Update error counter
            if (ErrorCount > 20) {                // In case of multiple errors
              temp = Man_Synchro();               // Try to synchronize again
              //Man_Receive_Init();               // Alternative, try to Initialize Receiver again
              ErrorCount = 0;                     // Reset error counter
              }
            }
          else {                                  // No error occured
            if (temp != 0x0E)                     // If "End" byte was received(see Transmitter example)
              Lcd_Chr_CP(temp);                   //   do not write received byte on LCD
              }
          Delay_ms(25);
        }
      while (temp != 0x0E) ;                      // If "End" byte was received exit do loop
   }
}

The following code is code for the Manchester transmitter, it shows how to use the Manchester Library for transmitting data:

Copy Code To ClipboardCopy Code To Clipboard
// Manchester module connections
sbit MANRXPIN at RC0_bit;
sbit MANRXPIN_Direction at TRISC0_bit;
sbit MANTXPIN at RC1_bit;
sbit MANTXPIN_Direction at TRISC1_bit;
// End Manchester module connections

char index, character;
char s1[] = "mikroElektronika";

void main() {

  ANSEL  = 0;                      // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                    // Disable comparators
  C2ON_bit = 0;

  Man_Send_Init();                 // Initialize transmitter

  while (1) {                      // Endless loop
    Man_Send(0x0B);                // Send "start" byte
    Delay_ms(100);                 // Wait for a while

    character = s1[0];             // Take first char from string
    index = 0;                     // Initialize index variable  
    while (character) {            // String ends with zero
      Man_Send(character);         // Send character
      Delay_ms(90);                // Wait for a while 
      index++;                     // Increment index variable
      character = s1[index];       // Take next char from string 
      }
    Man_Send(0x0E);                // Send "end" byte
    Delay_ms(1000);
  }
}

Connection Example

Simple Transmitter connection

Simple Transmitter connection


Simple Receiver connection

Simple Receiver connection

Copyright (c) 2002-2012 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code