• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Implementation of manchester coding

Status
Not open for further replies.

MessUpMymind

New Member
ive gone through Tutorial 12.3 of the wireless transmission and receiving of Nigel Goodwin's PIC Tutorial and the implementation has been successful.

Now I would like to wirelessly transmit out asynchronous data coming out from the serial port (using vb's mscomm) to my microcontroller. For that , I would need 2 PIC's (one at the TX end and the other at the RX end) for the implementation of Manchester Coding. Each data frame coming out of the computer is 10 bits consisting of 1 START bit, 8 DATA bits and 1 stop bit..(my vb settings are "9600,N,8,1")

From the serial port, a continuous string of ASCII characters will be transmitted out..

I understand that I have to configure the TXSTA and RXSTA registers as well as the SPBRG registers as stated in the datasheet but I would like to know how I can implement as well the Manchester Coding routine for this..

On the transmit side, I will be connecting the Tx pin from the serial port to Rx (pin26) of the 16f877A and then connect pin 25(Tx) to the data pin of the wireless transmitter.

On the receive side, I will be connecting the Data pin of the wireless receiver to pin26(Rx) of the PIC....


here's the Manchester coding routine that i extracted from nigel's tutorial:

Code:
packet_len	EQU 	2		;packet length 1 + 1 address byte


	cblock 	0x20 			;start of general purpose registers

		ncnt
		bt
		sum
		mtx_buffer
		mtx_buffer1
		mtx_delay		; half_frame delay

		count1			;used in delay routine
		count2
		counta			;used in delay routine
		countb			;used in delay routine
	endc


		call 	mtx_init
		movlw	0xAA			;set address byte to 0xAA
		movwf	mtx_buffer
;Manchester subroutines

;    Author:        [email protected]
;                   http://jap.hu/electronic/

mtx_init	
		movlw 	.115 		; 350 usec
		movwf 	mtx_delay
		return
		;

mtx_send
					; send out buffer
outbuf		movlw 	0x14 		; 20xbit1, 1xbit0

header		movwf 	count2
head0		call 	bit1
		decfsz 	count2,F
		goto 	head0
		call 	bit0

		movlw 	mtx_buffer
		movwf 	FSR
		movlw 	packet_len
		movwf 	count1
		movlw 	0xff
		movwf 	sum
		;
outbu0		movf 	INDF,W
		call 	update_sum
		movf 	INDF,W
		call 	outbyte
		incf 	FSR,F
		decfsz 	count1,F
		goto 	outbu0
		movf 	sum,W
		call 	outbyte
					; buffer is sent
		return

update_sum	; fast CRC-8 algorithm with poly x^8+x^5+x^4+1
		; executes in 23 cycles per update

		xorwf	sum,f
		clrw
		btfsc	sum,7
		xorlw	0x7a
		btfsc	sum,6
		xorlw	0x3d
		btfsc	sum,5
		xorlw	0x86
		btfsc	sum,4
		xorlw	0x43
		btfsc	sum,3
		xorlw	0xb9
		btfsc	sum,2
		xorlw	0xc4
		btfsc	sum,1
		xorlw	0x62
		btfsc	sum,0
		xorlw	0x31
		movwf	sum
		return

outbyte		movwf 	bt
		movlw 	8
		movwf 	count2
outby0		rlf 	bt,F
		btfsc 	STATUS,C
		goto 	outby1
		call 	bit0
		goto 	outby2
outby1		call 	bit1
outby2		decfsz 	count2,F
		goto 	outby0
		;
		call 	bit1
		; and 	bit0 - falls through to bit0 subroutine

;send a bit0

bit0		TXHIGH 			; HIGH


		call	mtx_bitdel	; bit time delay

		TXLOW 			; to LOW transition

		call	mtx_bitdel	; bit time delay
		return

;send a bit1

bit1		TXLOW 			; LOW

		call	mtx_bitdel	; bit time delay

		TXHIGH 			; to HIGH transition

		call	mtx_bitdel	; bit time delay
		return

; bit delay modified by NG

mtx_bitdel	movf 	mtx_delay, W
		movwf 	ncnt
ndelaya1	decfsz 	ncnt, F
		goto 	ndelaya1
		return

; end of Manchester routines

and now what i need to do is , implement this Manchester coding into this transmitter side coding ,

Code:
w_temp           EQU     0x7D       ; variable used for context saving
status_temp      EQU     0x7E       ; variable used for context saving
pclath_temp      EQU     0x7F       ; variable used for context saving
ByteCounter      EQU     0xBD       ;address used for byte counter


;**********************************************************************
       ORG       0x000             ; processor reset vector
       goto      Main               ; go to beginning of program
;**********************************************************************
; isr code can go here or be located as a call subroutine elsewhere

       ORG       0x004             ; interrupt vector location
       movwf     w_temp             ; save off current W register contents
       movf      STATUS,w           ; move status register into W register
       movwf     status_temp        ; save off contents of STATUS register
       movf      PCLATH,w           ; move pclath register into w register
       movwf     pclath_temp        ; save off contents of PCLATH register

       movf      pclath_temp,w      ; retrieve copy of PCLATH register
       movwf     PCLATH             ; restore pre-isr PCLATH register contents
       movf      status_temp,w      ; retrieve copy of STATUS register
       movwf     STATUS             ; restore pre-isr STATUS register contents
       swapf     w_temp,f
       swapf     w_temp,w           ; restore pre-isr W register contents
       retfie                       ; return from interrupt

Main:
       banksel   TRISC
       bcf       TRISC,6            ;c6=0 as output
       bsf       TRISC,0            ;c0=1 as input
       bsf       TRISC,1            ;c1=1 as input
; UART module setup
       banksel   SPBRG
       movlw     15                 ; rs232 baud as 57.6k as 15
       movwf     SPBRG              ; Enable SPBRG register Baud Rate

       banksel   TXSTA               ; Select memory bank for TXSTA SFR
             
       bcf       TXSTA,TX9             ; 8-bit transmission
       bsf       TXSTA,TXEN             ; Enable Transmission 
       bcf       TXSTA,SYNC             ; Asynchronous mode
       bsf       TXSTA,BRGH             ; High Baud Rate

       banksel   RCSTA
       bcf       RCSTA,SPEN         ; Disable Serial port. I use usart tx function
       bsf       RCSTA,CREN         ; Enable Receiver

       BANKSEL   PIE1
       BCF       PIE1,TXIE
; *******************save data in pic*******************************
SaveData
       bsf      STATUS,RP0             ;bank 1
       movlw    0x42
       movwf    0xBF
       movlw    0x24
       movwf    0xC0
       ;movlw    0x00
       ;movwf    0xC1
       ;movlw    0x00
       ;movwf    0xC2
       ;movlw    0x00
       ;movwf    0xC3
       ;movlw    0x00
       ;movwf    0xC4
;*********************transmit data new ******************************
       MOVLW     0x02
       MOVWF     ByteCounter
TestTxreg
       banksel   PIR1
       btfss     PIR1,TXIF          ;TXIF=1, is empty,skip
       goto      TestTxreg
TransData: 
       MOVLW     0xBF
       MOVWF     FSR                ; TO RAM
       ;CLRF      TXREG
GoOnTransData: 
       banksel   TXREG
       MOVF      INDF,0
       MOVWF     TXREG             ; Move the data to the transmit register
       INCF      FSR,1             ; INDF  address number moves next
Wait0:       
       banksel   PIR1
       btfss     PIR1,TXIF       
       goto      Wait0
       clrf      TXREG
       BSF       STATUS,RP0
       DECFSZ    ByteCounter,1  ; ChannelCounter-1
       goto      GoOnTransData     ; go on       
Wait1:   
       banksel   TXSTA
       MOVLW     0x02
       MOVWF     ByteCounter
Delay:
       BANKSEL   RCSTA
       MOVLW     0x02   ;20MHz=50ns=0.05us
       MOVWF     0x20   ;0.05*4=0.2us
LOOP2:
       MOVLW     0x03   ;E5=120us;c5=80us;85=75u;35=45=55=0
       MOVWF     0x21   ;03H=16us
LOOP1:
       DECFSZ    0x21,F
       GOTO      LOOP1
       DECFSZ    0x20,F
       GOTO      LOOP2
       GOTO      TransData
       ;goto      FinishData

FinishData:
       movlw     0x00
       movwf     TXREG
       goto      FinishData
       END
;*********************transmit data finish*****************
Would be great if anyone could guide me on how I can implement the Manchester Code routine for what i want to achieve..
 

Nigel Goodwin

Super Moderator
Most Helpful Member
You first need to decide on your packet size - the serial routine in the transmit side reads the bytes from the PC, and stuffs them in the packet buffer - then sends the packet. It would be a good idea to implement handshaking, to prevent the PC sending more data until the buffer has been transmitted.

On the receive side, the incoming data is received and placed in the buffer, once it's full, just send the data out of the serial port.

It would probably be simpler to add serial routines to the Manchester tutorial, rather than the other way round.
 

MessUpMymind

New Member
hi nigel,

sir , i have gone through some of the data that i have .. RS232 hand shaking is available in hardware and software (Xon and Xoff) , that part is still in progress ..sir what u mean by packet size ?? is it the amount of data that i wan to send ?? or how many bits that i wan to send for 1 word??
thanks for replying =)
 

Nigel Goodwin

Super Moderator
Most Helpful Member
Read the Manchester tutorial, Manchester is a packet system - data is sent in a certain number of bytes, known as a packet. As Manchester has a considerable amount of overhead, it's really impractical to send a single byte, so it's sent as multiple byte packets.
 

edeca

Active Member
You might also like to read Microchip's datasheet TB045, which explains Manchester coding very well.

I would not spend too long looking at anything else except Nigel's tutorial, as the internet is full of bad advice regarding Manchester.
 

MessUpMymind

New Member
Hi nigel,

very well explained sir , i will get my data compiled before i come back again to report the progress..thanks for your concern and replies.
 

MessUpMymind

New Member
HI nigel ,

sir i got a question , in ur tutorial ..the maximum packet that you have tried is 4 +1 packets which sum up to 5 , what's the limit of those packet that i can send?? because i am sending quite a number of characters in ASCII form , so if the packet cant goes up to the length of the number of characters i going to send , then i should consider sending it 1 by 1 is it correct??

thanks..
 

MessUpMymind

New Member
hi edeca ,

i have gone through that Apps Notes of TB045 , but it seem to be more complicated than nigel manchester coding , am i correct?? because inside there consist of several extra stuff, as i am a beginner i should take my step slow by going through nigel tutorial =), thanks for your advice , that's great!!

another question edeca , you did go other forum as well to answer people who need help right?? i see you posting this somewhere too =) ,i am pretty sure you are such a helpful person as nigel is..
 

edeca

Active Member
The only real limitation is the amount of memory your microcontroller has to store data in. However, longer packets are more likely to be corrupted by other wireless devices (e.g. my doorbell uses the same frequency as my receiver module).

You need 1 byte per character and probably some room for a header at the start & CRC at the end. How many characters do you want to send? I'd suggest you're going to run out of memory in the uC before you have problems with anything else.
 

edeca

Active Member
i have gone through that Apps Notes of TB045 , but it seem to be more complicated than nigel manchester coding , am i correct?? because inside there consist of several extra stuff, as i am a beginner i should take my step slow by going through nigel tutorial =)
Nigel's tutorial is an excellent way to learn correct Manchester coding. TB045 is an excellent way to learn how to implement it yourself, from scratch (as I am currently doing in C).

another question edeca , you did go other forum as well to answer people who need help right?? i see you posting this somewhere too =)
I use the same name elsewhere, so it depends what else you look at on the internet!
 

MessUpMymind

New Member
hi edeca,

oh , there's a problem exist on the package actually ..i must set it when the data receive from the RS232 from PC, basically user need to type in the length and send it to my transmitter microcontroller only i can decide how many package i need ..

hmm i searching around for any engineering base forum in the net as many as i can , maybe sparkfun if not mistaken =)...I see , for the apps note TB045 is it
only for asyn only?? , no wonder it sound so much complicated with other things else compare to nigel's tutorial..

thanks for your quick reply
 

MessUpMymind

New Member
Hi there,

back to the very first problem before all this packet transmitting occur, i would like to know , since my project all about is
Transmitting side
Visual Basic ---->Rs232 ----> uC (16F877A) ----> transmitter module 434 Mhz

Receiving side
Receiver module 434 Mhz ---->uC ---> Application

1.As for the transmitting side ,is it correct that i only need to configure my Rx pin ONLY and i left Tx pin Unconnected ?? with the condition that i don't use hand-shaking to send X-on and X-off..Is only half duplex transmission between PIC and CPU.

is my assumption correct ??

2.Another issue is that , i not necessary need to use the Rx and Tx pin at the receiver side right?? normal uC pin should be able to receive the data from the receiver module right??

****In the PIC16F877A data sheet , asyn is configured as full-duplex ..because i am using UART for transmission so is that ok for the above condition setting to run at Asyn mode? without the Tx pin at the receiver side connected to RS 232..****

Any reply is much appreciated !!
thanks!!
:eek: have a nice day.
 

MessUpMymind

New Member
Hi there,

here's the setting for my code , i didnt set those following item
1.Interrupt
2.framing error
3.overrun error
4.TRMT
5.Interrupt enabale (RCIE)

Code:
SerInit banksel SPBRG
        movlw  .25		   ;baud rate for 9600 Fosc = 4Mhz
        movwf  SPBRG       ; baud rate
        bsf    TXSTA, BRGH ; high speed
        bcf    TXSTA, SYNC ; async mode
        banksel RCSTA
        bsf    RCSTA, SPEN ; enable serial port
        bsf    RCSTA, CREN ; enable continous receive 
   
; Receive a single character in W from the USART   
; Routine returns in BANK 0

SerRX   banksel PIR1
SerRX1  btfss PIR1,RCIF    ; Wait until character is received complete 1 byte
        goto  SerRX1	    
        movf  RCREG,W		;store it

        RETURN
the above code will automatically store the data of 1 byte when RCIF complete filled with 8 bits , so the only thing i need to loop until RCIF is set right?? then only i store my data from RCREG to other place.

bear in mind that i only use it for receiving from PC to microcontroller , therefore i didnt configure my transmit pin.



Thanks for replying!!
 
Last edited:

MessUpMymind

New Member
hi nigel ,

okay , i will try it out...btw can i send those data from RCREG into single pin in microcontroller for eg PORTC.1??? i know i can use RLF,RRF or shift register from parallel to serial but is there anyway else??

Thanks for your reply =)..
 

Nigel Goodwin

Super Moderator
Most Helpful Member
hi nigel ,

okay , i will try it out...btw can i send those data from RCREG into single pin in microcontroller for eg PORTC.1??? i know i can use RLF,RRF or shift register from parallel to serial but is there anyway else??
I'm not really sure what you mean?, if you want to send it out again as RS232 you could always use the hardware UART.
 

MessUpMymind

New Member
hi nigel ,

sorry for those mess in previous , now i can send data to PIC from PC using UART... after i read 1 byte of data from RCREG and i wan to test it so i send those data that i read from RCREG to GPIO lets say PORTC and i will test it by using 8 LEDs on PORTC to see whether it receive the correct data. and it works out fine till this point

what i need to do now is:
now i wan to make my data sending to 1 of the GIPO PIN in SERIAL so that i can send it to my RF transmitter data pin in serial , make it short i need to put all 8 bits sending in 1 PIN serially instead of the whole PORT in parallel.

as i know those method that can achieve this will be the following methods:
1)using RLF/RRF and loop it 8 times to read every single bits
2)using shift register to make those parallel data to Serial

is there any other method that actually i can use to send out those data in serial from a pin to my RF transmitter data pin??

Thanks for helping out =).
 

Nigel Goodwin

Super Moderator
Most Helpful Member
Like I said above, you could use the hardware UART transmitter, as you're not already using it.

However, as you're sending it to a radio transmitter you should use my Manchester routines instead.
 
Status
Not open for further replies.

EE World Online Articles

Loading
Top