There are probably a few hundred ways to do this, but here's a few that I've used with decent results.
The 1st version uses PBP's bit twiddling ability. Version 2 is a modified version of one originally done
by Les Johnson.
The .asm routine is considerably faster & smaller (knocks off 300 words) compared to the BASIC
bit-twiddling approach.
Code:
DEFINE LOADER_USED 1
DEFINE OSC 20
; compiled for an 18F2525. 882 words with MPASMWIN 5.01
X VAR BYTE
Y VAR BYTE ' Array index pointer for primary functions
Index VAR BYTE ' Array index pointer for encode/decode routines
BitCount VAR BYTE ' Bit counter
ByteIn VAR BYTE ' Byte to encode
ByteOut VAR BYTE ' Decoded byte
Manch VAR WORD ' Encoded manchester word
Enc_Dat VAR WORD[6] ' Word array for 6 manchester encoded words
GOTO Main ' Jump over encode/decode routines
Encode:
For Index = 0 to 7 ' loop 8-bits
Manch.0[(Index*2)] = ~ByteIn.0[Index] ' Encode bits 0,2,4,6,8,10,12,14 in Manch
Manch.0[(Index*2)+1] = ByteIn.0[Index]' Encode bits 1,3,5,7,9,11,13,15 in Manch
Next Index
Return
Decode::
For Index = 0 to 7 ' loop for 8 bits
ByteOut.0[Index] = ~Manch.0[Index<<1] ' ByteOut bits 0-7 = Manch bits 0,2,4,6,8,10,12,14
Next Index
Return
Main:
CLEAR ' Used for demo to start with all RAM clear
' Encode ASCII characters "A" to "F"
Y = 0 ' Start array index pointer at 0
FOR X = "A" to "F"
ByteIn = X
GOSUB Encode
Enc_Dat[Y] = Manch
HSEROUT ["Encoded ",ByteIn," = ",IBIN16 Enc_Dat[Y],13,10]
Y = Y + 1 ' Increment array index pointer
NEXT X
' Decode & print results
FOR Y = 0 to 5
Manch = Enc_Dat[Y]
GOSUB Decode
HSEROUT ["Decoded ",IBIN16 Manch," = ",ByteOut,13,10]
NEXT Y
PAUSE 10000
GOTO Main
END
And here's a much smaller version. A nice choice; especially for smaller PIC's, but it's somewhat harder
to understand at first glance if you're not familiar with .asm
Code:
DEFINE LOADER_USED 1
DEFINE OSC 20
; compiled for an 18F2525. 582 words with MPASMWIN 5.01
X VAR BYTE
Y VAR BYTE
BitCount VAR BYTE bank0 system ' Bank0 system so we don't need an underscore
ByteIn VAR BYTE bank0 system ' to access BASIC variables from assembler
ByteOut VAR BYTE bank0 system
Manch VAR WORD bank0 system ' Holds manchester encoded word
Temp VAR WORD bank0 system ' Temp var
Enc_Dat VAR WORD[6] ' Holds 6 manchester encoded words
GOTO Main ' Jump over encode/decode routines
ASM ; Note: For 14-bit core just change Rlcf to Rlf
; Manchester encode routine
_Encode
Movlw 8
Movwf BitCount
E_Repeat
Rlcf ByteIn,F ; Rotate MSB on ByteIn into carry & test for 1
Btfss STATUS,C ; If bit = 1 then skip to BitSet
Goto BitClr ; If bit = 0 then goto to BitClr
BitSet ; Bit was set, so encode 1 as 10
Rlcf Manch,F
Rlcf Manch+1,F
bcf STATUS,C
Rlcf Manch,F
Rlcf Manch+1,F
Goto E_Loop
BitClr ; Bit was clear, so encode 0 as 01
Rlcf Manch,F
Rlcf Manch+1,F
bsf STATUS,C
Rlcf Manch,F
Rlcf Manch+1,F
E_Loop
Decfsz BitCount,F
Goto E_Repeat
Return
ENDASM
ASM
; Manchester decode routine.
_Decode
Movf Manch+1,W
Movwf Temp+1
Movf Manch,W
Movwf Temp
Movlw 8
Movwf BitCount
Repeat
Rlcf Temp,F
Rlcf Temp+1,F
Rlcf ByteOut,F
Rlcf Temp,F
Rlcf Temp+1,F
Decfsz BitCount,F
Goto Repeat
Return
ENDASM
Main:
CLEAR ' Used for demo to start with all RAM clear
' Manchester encode ASCII characters "A" to "F"
Y = 0 ' Start array index pointer at 0
FOR X = "A" to "F"
ByteIn = X
CALL Encode
Enc_Dat[Y] = Manch
HSEROUT ["Encoded ",X," = ",IBIN16 Enc_Dat[Y],13,10]
Y = Y + 1 ' Increment array index pointer
NEXT X
' Decode & print results
FOR Y = 0 to 5
Manch = Enc_Dat[Y]
CALL Decode
HSEROUT ["Decoded ",IBIN16 Manch," = ",ByteOut,13,10]
NEXT Y
PAUSE 10000
GOTO Main
END
Toss in a few bytes for preamble & synch consisting of an equal 1's & 0's before the encoded data packet,
and you're off to the races....;}
Bookmarks