Manchester Code Library

The mikroPascal PRO for ARM 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

Stellaris

The following variables must be defined in all projects using Manchester Code Library: Description: Example:
var MANRXPIN : sbit; sfr; external; Receive line. var MANRXPIN : sbit at GPIO_PORTE_DATA.B0;
var MANTXPIN : sbit; sfr; external; Transmit line. var MANTXPIN : sbit at GPIO_PORTE_DATA.B1;
var MANRXPIN_Direction : sbit; sfr; external; Direction of the Receive pin. var MANRXPIN_Direction : sbit at GPIO_PORTE_DIR.B0;
var MANTXPIN_Direction : sbit; sfr; external; Direction of the Transmit pin. var MANTXPIN_Direction : sbit at GPIO_PORTE_DIR.B1;

STM32

The following variables must be defined in all projects using Manchester Code Library: Description: Example:
var MANRXPIN : sbit; sfr; external; Receive line. var MANRXPIN : sbit at GPIOE_IDR.B8;
var MANTXPIN : sbit; sfr; external; Transmit line. var MANTXPIN : sbit at GPIOE_ODR.B9;

Library Routines

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

Man_Receive_Init

Prototype

function Man_Receive_Init() : word;

Description

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

Parameters

None.

Returns

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

Requires

External dependencies of the library from the top of the page must be defined before using this function.

Example

Stellaris

// Manchester module connections
var MANRXPIN : sbit at GPIO_PORTE_DATA.B0;
    MANRXPIN_Direction : sbit at GPIO_PORTE_DIR.B0;
    MANTXPIN : sbit at GPIO_PORTE_DATA.B1;
    MANTXPIN_Direction : sbit at GPIO_PORTE_DIR.B1;
// End Manchester module connections
...
Man_Receive_Init();

STM32

// Manchester module connections
var MANRXPIN: sbit at GPIOE_IDR.B8;
var MANTXPIN: sbit at GPIOE_ODR.B9;
// End Manchester module connections
...
Man_Receive_Init();
Notes

In case of multiple persistent errors on reception, the user should call this routine once again or Man_Synchro routine to enable synchronization.

Man_Receive

Prototype

function Man_Receive(var error : word) : byte;

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.
Returns

A byte read from the incoming signal.

Requires

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

Example
var data_, error : word;
...
error := 0;
data_ := 0;
data_ := Man_Receive(error);
if (error <> 0) then
begin 
	// error handling 
end;
Notes

None.

Man_Send_Init

Prototype

procedure Man_Send_Init();

Description

The function configures Transmitter pin.

Parameters

None.

Returns

Nothing.

Requires

External dependencies of the library from the top of the page must be defined before using this function.

Example

Stellaris

// Manchester module connections
var MANRXPIN : sbit at GPIO_PORTE_DATA.B0;
    MANRXPIN_Direction : sbit at GPIO_PORTE_DIR.B0;
    MANTXPIN : sbit at GPIO_PORTE_DATA.B1;
    MANTXPIN_Direction : sbit at GPIO_PORTE_DIR.B1;
// End Manchester module connections
...
Man_Receive_Init();

STM32

// Manchester module connections
var MANRXPIN: sbit at GPIOE_IDR.B8;
var MANTXPIN: sbit at GPIOE_ODR.B9;
// End Manchester module connections
...
Man_Send_Init();
Notes

None.

Man_Send

Prototype

procedure Man_Send(tr_data : byte);

Description

Sends one byte.

Parameters
  • tr_data: data to be sent
Returns

Nothing.

Requires

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

Example
var msg : byte;
...
Man_Send(msg);
Notes

Baud rate used is 500 bps.

Man_Synchro

Prototype

function Man_Synchro(): word;

Description

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

Parameters

None.

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

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

Example
var man__half_bit_len : word;
...
man__half_bit_len := Man_Synchro();
Notes

None.

Man_Break

Prototype

procedure Man_Break();

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.

Parameters

None.

Returns

Nothing.

Requires

Nothing.

Example

          
Notes

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

Library Example

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

Stellaris

program Manchester_Receiver;

// Lcd module connections
var LCD_RS : sbit at GPIO_PORTD_DATA.B2;
    LCD_EN : sbit at GPIO_PORTD_DATA.B3;
    LCD_D4 : sbit at GPIO_PORTD_DATA.B4;
    LCD_D5 : sbit at GPIO_PORTD_DATA.B5;
    LCD_D6 : sbit at GPIO_PORTD_DATA.B6;
    LCD_D7 : sbit at GPIO_PORTD_DATA.B7;

var LCD_RS_Direction : sbit at GPIO_PORTD_DIR.B2;
    LCD_EN_Direction : sbit at GPIO_PORTD_DIR.B3;
    LCD_D4_Direction : sbit at GPIO_PORTD_DIR.B4;
    LCD_D5_Direction : sbit at GPIO_PORTD_DIR.B5;
    LCD_D6_Direction : sbit at GPIO_PORTD_DIR.B6;
    LCD_D7_Direction : sbit at GPIO_PORTD_DIR.B7;
// End Lcd module connections

// Manchester module connections
var MANRXPIN : sbit at GPIO_PORTE_DATA.B0;
    MANRXPIN_Direction : sbit at GPIO_PORTE_DIR.B0;
    MANTXPIN : sbit at GPIO_PORTE_DATA.B1;
    MANTXPIN_Direction : sbit at GPIO_PORTE_DIR.B1;
// End Manchester module connections

var error : word;
    ErrorCount, counter, temp : byte;

  begin
    ErrorCount := 0;
    counter := 0;
    Lcd_Init();                              // Initialize LCD
    Lcd_Cmd(_LCD_CLEAR);                     // Clear LCD display

    Man_Receive_Init();                      // Initialize Receiver

    while TRUE do                            // Endless loop
      begin
        Lcd_Cmd(_LCD_FIRST_ROW);             // Move cursor to the 1st row

        while TRUE do                        // Wait for the "start" byte
          begin
            temp := Man_Receive(error);      // Attempt byte receive
           if (temp = 0x0B) then             // "Start" byte, see Transmitter example
              break;                         // We got the starting sequence
           if (error <> 0) then              // Exit so we do not loop forever
              break;
          end;

        repeat
          begin
            temp := Man_Receive(error);      // Attempt byte receive
            if (error <> 0) then             // If error occured
              begin
                Lcd_Chr_CP('?');             // Write question mark on LCD
                Inc(ErrorCount);             // Update error counter
                if (ErrorCount > 20) then    // In case of multiple errors
                  begin
                    temp := Man_Synchro();   // Try to synchronize again
                    //Man_Receive_Init();    // Alternative, try to Initialize Receiver again
                    ErrorCount := 0;         // Reset error counter
                  end;
              end
            else                             // No error occured
              begin
                if (temp <> 0x0E) then       // If "End" byte was received(see Transmitter example)
                  begin                        // do not write anymore received byte on LCD
                    Lcd_Chr_CP(temp);          // else write character on LCD
                    Inc(counter);              // Counts how many chars have been written on LCD
                    if counter = 25 then       // If there were more then 25 characters
                      begin                    // synchronization is off
                        Lcd_Cmd(_LCD_CLEAR);   // Clear the LCD of garbled communication
                        temp := Man_Synchro(); // Try to synchronize again
                      end;
                  end
                else
                  counter := 0;                // reset counter
              end;
            Delay_ms(25);
          end;
        until ( temp = 0x0E );
      end;                                     // If "End" byte was received exit do loop
  end.

STM32

program Manchester_Receiver;

// LCD module connections
var LCD_RS: sbit at GPIOD_ODR.B2;
var LCD_EN: sbit at GPIOD_ODR.B3;
var LCD_D4: sbit at GPIOD_ODR.B4;
var LCD_D5: sbit at GPIOD_ODR.B5;
var LCD_D6: sbit at GPIOD_ODR.B6;
var LCD_D7: sbit at GPIOD_ODR.B7;
// End LCD module connections


// Manchester module connections
var MANRXPIN: sbit at GPIOE_IDR.B8;
var MANTXPIN: sbit at GPIOE_ODR.B9;
// End Manchester module connections

var error : word;
    ErrorCount, counter, temp : byte;

  begin
    ErrorCount := 0;
    counter := 0;
    Lcd_Init();                              // Initialize LCD
    Lcd_Cmd(_LCD_CLEAR);                     // Clear LCD display

    Man_Receive_Init();                      // Initialize Receiver

    while TRUE do                            // Endless loop
      begin
        Lcd_Cmd(_LCD_FIRST_ROW);             // Move cursor to the 1st row

        while TRUE do                        // Wait for the "start" byte
          begin
            temp := Man_Receive(error);      // Attempt byte receive
           if (temp = 0x0B) then             // "Start" byte, see Transmitter example
              break;                         // We got the starting sequence
           if (error <> 0) then              // Exit so we do not loop forever
              break;
          end;

        repeat
          begin
            temp := Man_Receive(error);      // Attempt byte receive
            if (error <> 0) then             // If error occured
              begin
                Lcd_Chr_CP('?');             // Write question mark on LCD
                Inc(ErrorCount);             // Update error counter
                if (ErrorCount > 20) then    // In case of multiple errors
                  begin
                    temp := Man_Synchro();   // Try to synchronize again
                    //Man_Receive_Init();    // Alternative, try to Initialize Receiver again
                    ErrorCount := 0;         // Reset error counter
                  end;
              end
            else                             // No error occured
              begin
                if (temp <> 0x0E) then       // If "End" byte was received(see Transmitter example)
                  begin                        // do not write anymore received byte on LCD
                    Lcd_Chr_CP(temp);          // else write character on LCD
                    Inc(counter);              // Counts how many chars have been written on LCD
                    if counter = 25 then       // If there were more then 25 characters
                      begin                    // synchronization is off
                        Lcd_Cmd(_LCD_CLEAR);   // Clear the LCD of garbled communication
                        temp := Man_Synchro(); // Try to synchronize again
                      end;
                  end
                else
                  counter := 0;                // reset counter
              end;
            Delay_ms(25);
          end;
        until ( temp = 0x0E );
      end;                                     // If "End" byte was received exit do loop
  end.

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

Stellaris

program Manchester_Transmitter;

// Manchester module connections
var MANRXPIN : sbit at GPIO_PORTE_DATA.B0;
    MANRXPIN_Direction : sbit at GPIO_PORTE_DIR.B0;
    MANTXPIN : sbit at GPIO_PORTE_DATA.B1;
    MANTXPIN_Direction : sbit at GPIO_PORTE_DIR.B1;
// End Manchester module connections

var index, character : byte;
    s1 : array[17] of char;

  begin
    s1 := 'mikroElektronika';

    Man_Send_Init();                 // Initialize transmitter

    while TRUE do                    // Endless loop
      begin
        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 <> 0) do    // String ends with zero
          begin
            Man_Send(character);     // Send character
            Delay_ms(90);            // Wait for a while
            Inc(index);              // Increment index variable
            character := s1[index];  // Take next char from string
          end;
        Man_Send(0x0E);              // Send "end" byte
        Delay_ms(1000);
      end;
  end.

STM32

program Manchester_Transmitter;

// Manchester module connections
var MANRXPIN: sbit at GPIOE_IDR.B8;
var MANTXPIN: sbit at GPIOE_ODR.B9;
// End Manchester module connections


var index, character : byte;
    s1 : array[17] of char;

  begin
    s1 := 'mikroElektronika';

    Man_Send_Init();                 // Initialize transmitter

    while TRUE do                    // Endless loop
      begin
        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 <> 0) do    // String ends with zero
          begin
            Man_Send(character);     // Send character
            Delay_ms(90);            // Wait for a while
            Inc(index);              // Increment index variable
            character := s1[index];  // Take next char from string
          end;
        Man_Send(0x0E);              // Send "end" byte
        Delay_ms(1000);
      end;
  end.
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