Manchester Code Library

The mikroBasic PRO for AVR 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:
dim MANRXPIN as sbit sfr external Receive line. dim MANRXPIN as sbit at PINB0_bit
dim MANTXPIN as sbit sfr external Transmit line. dim MANTXPIN as sbit at PORTB1_bit
dim MANRXPIN_Direction as sbit sfr external Direction of the Receive pin. dim MANRXPIN_Direction as sbit at DDB0_bit
dim MANTXPIN_Direction as sbit sfr external Direction of the Transmit pin. dim MANTXPIN_Direction as sbit at DDB1_bit

Library Routines

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

Man_Receive_Init

Prototype

sub function Man_Receive_Init() as word

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
dim MANRXPIN as sbit at PINB0_bit
dim MANRXPIN_Direction as sbit at DDB0_bit
...
Man_Receive_Init()

Man_Receive

Prototype

sub function Man_Receive(dim byref error as byte) as byte

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
dim data, error as byte
...
data = 0
error = 0
data = Man_Receive(&error)

if (error <> 0) then
' error handling 
end if

Man_Send_Init

Prototype

sub procedure 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:
dim MANTXPIN as sbit at PINB1_bit
dim MANTXPIN_Direction as sbit at DDB1_bit
...
Man_Send_Init()

Man_Send

Prototype

sub procedure Man_Send(tr_data as byte)

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
dim msg as byte
...
Man_Send(msg)

Man_Synchro

Prototype

sub function Man_Synchro() as word

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
dim man__half_bit_len as word
...
man__half_bit_len = Man_Synchro()

Man_Break

Prototype

sub procedure 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
dim data1, error, counter as byte

sub procedure Timer0Overflow_ISR org 0x12
  counter = 0
  if (counter >= 20) then
    Man_Break()
    counter = 0                ' reset counter
  else
    Inc(counter)                  ' increment counter
  end if
end sub

main: 
  TOIE0_bit  = 1                   ' Timer0 overflow interrupt enable
  TCCR0_bit  = 5                   ' Start timer with 1024 prescaler

  SREG_I_bit = 0                   ' Interrupt disable

  ...

  Man_Receive_Init()

  ...
  
  ' try Man_Receive with blocking prevention mechanism

  SREG_I_bit = 1                   ' Interrupt enable
  data1 = Man_Receive(@error)
  SREG_I_bit = 0                   ' Interrupt disable

  ...

end.

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
program Manchester_Receiver

' Lcd module connections
dim LCD_RS as sbit at PORTD2_bit
    LCD_EN as sbit at PORTD3_bit
    LCD_D4 as sbit at PORTD4_bit
    LCD_D5 as sbit at PORTD5_bit
    LCD_D6 as sbit at PORTD6_bit
    LCD_D7 as sbit at PORTD7_bit

dim LCD_RS_Direction as sbit at DDD2_bit
    LCD_EN_Direction as sbit at DDD3_bit
    LCD_D4_Direction as sbit at DDD4_bit
    LCD_D5_Direction as sbit at DDD5_bit
    LCD_D6_Direction as sbit at DDD6_bit
    LCD_D7_Direction as sbit at DDD7_bit
' End Lcd module connections

' Manchester module connections
dim MANRXPIN as sbit at PINB0_bit
    MANRXPIN_Direction as sbit at DDB0_bit
    MANTXPIN as sbit at PORTB1_bit
    MANTXPIN_Direction as sbit at DDB1_bit
' End Manchester module connections

dim error_, ErrorCount, temp as byte

main:
  ErrorCount = 0
  Delay_10us()
  Lcd_Init()                          ' Initialize LCD
  Lcd_Cmd(_LCD_CLEAR)                 ' Clear LCD display

  Man_Receive_Init()                  ' Initialize Receiver

  while TRUE                          ' Endless loop
    Lcd_Cmd(_LCD_FIRST_ROW)           ' Move cursor to the 1st row
    while TRUE                        ' Wait for the "start" byte
      temp = Man_Receive(error_)      ' Attempt byte receive
      if (temp = 0x0B) then           ' "Start" byte, see Transmitter example
        break                         ' We got the starting sequence
      end if
      if (error_ <> 0) then           ' Exit so we do not loop forever
        break
      end if
    wend

    while (temp <> 0x0E)
      temp = Man_Receive(error_)      ' Attempt byte receive
      if (error_ <> 0) then           ' If error occured
        Lcd_Chr_CP("?")               ' Write question mark on LCD
        Inc(ErrorCount)               ' Update error counter
        if (ErrorCount > 20) then     ' 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
        end if
        else                          ' No error occured
          if (temp <> 0x0E) then      ' If "End" byte was received(see Transmitter example)
                                      ' do not write anymore received byte on Lcd
            Lcd_Chr_CP(temp)          ' else write character on Lcd
            Inc(ErrorCount)              ' Counts how many chars have been written on Lcd
            if ErrorCount = 25 then      ' If there were more then 25 characters
                                      ' synchronization is off
              Lcd_Cmd(_LCD_CLEAR)     ' Clear the Lcd of garbled communication
              temp = Man_Synchro()    ' Try to synchronize again
            end if

          else
            ErrorCount = 0               ' reset counter
          end if
            Delay_ms(25)
      end if

    wend                              ' If "End" byte was received exit do loop
  wend
end.

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
program Manchester_Transmitter

' Manchester module connections
dim MANRXPIN as sbit at PORTB0_bit
    MANRXPIN_Direction as sbit at DDB0_bit
    MANTXPIN as sbit at PORTB1_bit
    MANTXPIN_Direction as sbit at DDB1_bit
' End Manchester module connections

dim index, character as byte
    s1 as char[17]

main:
  s1 = "mikroElektronika"
  Man_Send_Init()                 ' Initialize transmitter

  while TRUE                      ' 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 <> 0)      ' String ends with zero
        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
      wend
      Man_Send(0x0E)              ' Send "end" byte
      Delay_ms(1000)
  wend
end.

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