Thanks for letting me know. Code has been up for eons and nobody spotted the typo before now!
Thanks for letting me know. Code has been up for eons and nobody spotted the typo before now!
Hi Mel,
Yep I thought it had a bug, actually there is another ...(I swear I am not picking on you.... ) the NEXT counterA is missing in the EncodeManchester routine.
For a while I had a problem understanding how the shift right >> instruction ran. (Not using this before)
Also I assumed that the MyData BITS are stored in the registers as [0,1,2,3,4,5,6,7], but actually they are the other way around (same goes for the ManchesterWord bits).
Watching the code run through ICD makes a lot of sense. I have attached the code for anyone interested. It is fully working on a 16F628 chip and great to pause the code and swap a few bits in the manchesterword to trigger the ErrorFlag Bit.
Thanks again Melanie
Now then, where did I put those RF modules?.....
' ==========================
' DEVICE PROGRAMMING OPTIONS
' ==========================
' PRESET FUSES
@ DEVICE PIC16F628, WDT_ON
@ DEVICE PIC16F628, INTRC_OSC_NOCLKOUT
@ DEVICE PIC16F628, BOD_ON
@ DEVICE PIC16F628, PROTECT_OFF
@ DEVICE PIC16F628, MCLR_ON
' =============
' USER DEFINES
' =============
DEFINE OSC 4
' =================
' SET USART PARAMS
' =================
DEFINE HSER_RCSTA 90h ' Set receive register to receiver enabled
DEFINE HSER_TXSTA 24h
DEFINE HSER_BAUD 4800 ' Set baud rate
DEFINE HSER_SPBRG 51 ' Set SPBRG directly (normally set by HSER_BAUD)
' ===========================
' CONFIGURE COMPARATOR MODULE
' ===========================
CMCON = 7 ' TURN ANALOG COMPARATOR MODE OFF
' ==============
' PROGRAM VARS
' ==============
COUNTERA var Byte
ERRORFLAG var Bit
MYDATA var Byte
MANCHESTERWORD var Word
' ===================
' START
' ===================
START:
HSERIN [MYDATA]
HSEROUT ["ENTERED VALUE: ",MYDATA,13,10]
HSEROUT ["ENCODING TO MANCHESTER NOW",13,10]
GOSUB EncodeManchester
HSEROUT ["ENCODING COMPLETED",13,10]
PAUSE 1000
HSEROUT ["DECODING MANCHESTER NOW",13,10]
GOSUB DECODEMANCHESTER
HSEROUT ["DECODING COMPLETED",13,10]
IF ERRORFLAG THEN
HSEROUT ["VALUE CORRUPTED!: ",MYDATA,13,10,13,10]
ELSE
HSEROUT ["FINAL VALUE: ",MYDATA,13,10,13,10]
ENDIF
GOTO START:
' Subroutine Encodes Manchester Word
' Enter subroutine with data in MyData
' Exit Subroutine with encoded ManchesterWord
' MyData contents are destroyed on exit
ENCODEMANCHESTER:
ManchesterWord=0
For CounterA=0 to 7
If MyData.0=0 then
ManchesterWord.14=1
else
ManchesterWord.15=1
endif
If CounterA<7 then ManchesterWord=ManchesterWord>>2
MyData=MyData>>1
Next CounterA
Return
' Subroutine Decodes Manchester Word
' Enter subroutine with encoded data in ManchesterWord
' Exit subroutine with decoded data in MyData
' ManchesterWord contents are destroyed on exit
' Also on exit, ErrorFlag=0 then Data is good
' ErrorFlag=1 then Data is suspect/corrupt
DECODEMANCHESTER:
ErrorFlag=0
For CounterA=0 to 7
If ManchesterWord.1=0 then
MyData.7=0
If ManchesterWord.0=0 then ErrorFlag=1
else
MyData.7=1
If ManchesterWord.0=1 then ErrorFlag=1
endif
ManchesterWord=ManchesterWord>>2
If CounterA<7 then MyData=MyData>>1
NEXT COUNTERA
Return
Thank you for your contribution ,Squibcakes.
Your code can be an excellent example for someone wanting RC5 over RF.
regards
hi all, i don't believe the decoding part of that code works! if you received an encoded stream of 0110100110011010 for example, this would raise the erro flag?
If ManchesterWord.1=0 then
MyData.7=0
If ManchesterWord.0=0 then ErrorFlag=1
else
MyData.7=1
If ManchesterWord.0=1 then ErrorFlag=1
endif
any help?
thanks.
Have you run the program and seen it work?
I just did and it works fine! Lets see, was the letter you typed in the letter "k"?
It decoded no problems for me.
The best way to inderstand this program is to step through it using ICD mode... its hard to explain without viewing the registers at work.
Good luck, and may the force be with you.
Cheers
J
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.
And here's a much smaller version. A nice choice; especially for smaller PIC's, but it's somewhat harderCode: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
to understand at first glance if you're not familiar with .asm
Toss in a few bytes for preamble & synch consisting of an equal 1's & 0's before the encoded data packet,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
and you're off to the races....;}
Thanks for that bruce, would you be able to explain the line:
Manch.0[(Index*2)] = ~ByteIn.0[Index]
for me please? what are the parts in [] doing?
thanks
Bookmarks