Assembler subroutine for PIC microcontroller




 
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
usaex	bsf	STATUS,RP0  ;switch to bank 1
	movlw	0x00	; PORTA set to output
	movwf	TRISA
	bcf	STATUS,RP0  ;switch back to bank 0
	return
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
usain	bsf	STATUS,RP0  ;switch to bank 1
	movlw	0x1F	; PORTA set to input
	movwf	TRISA
	bcf	STATUS,RP0  ;switch back to bank 0
	return
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
usbex	bsf	STATUS,RP0  ;switch to bank 1
	movlw	0x00	; PORTB set to output
	movwf	TRISB
	bcf	STATUS,RP0  ;switch back to bank 0
	return
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
usbin	bsf	STATUS,RP0  ;switch to bank 1
	movlw	0xFF	; PORTB set to input
	movwf	TRISB
	bcf	STATUS,RP0  ;switch back to bank 0
	return
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ser_tx
	movwf	transo	; transfer data, use accu W	
	movlw	0x08	; W=input variable	
	movwf	count4
	call	ein	; Start bit
wdh1	btfsc	transo,0
	call	null
	btfss	transo,0
	call	ein
	rrf	transo,F
	decfsz	count4,F	
	goto 	wdh1
	call	null	; Stop bit
	retlw	00
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ser_rx
	btfsc	rsrx	; wait a change in logic level
	goto	ser_rx
	call	haltb
	movlw	0x08
	movwf	count5
wdh2	call	halta
	bcf	STATUS,C
	btfsc	rsrx	; rx test
	bsf	STATUS,C	
	rrf	ratb,F	; ratb=output variable
	decfsz	count5,F
	goto	wdh2
	return
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ein	bcf	rstx	; tx=0
	call	halta
 	return
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
null	bsf	rstx	; tx=1
	call	halta
 	return
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

;________________________________________________________________________
halta	movlw	0x88	; 136*3 step or 104us Q=16MHz
	movwf	count1
q0	decfsz	count1,F	
	goto 	q0		
 	retlw	00
;________________________________________________________________________
haltb	movlw	0x16	; 22*3 step or 17.75us Q=16MHz
	movwf	count1
q1	decfsz	count1,F	
	goto 	q1		
 	retlw	00
;________________________________________________________________________

;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
paar	movwf	paru	; W=input data (stored in paru)
	movlw	0x07	
	movwf	count3	; just a counter
	movlw	0x01
	andwf	paru,0
	movwf	bug	; bug=output data (parity bit)
roata	rrf	paru,1
	movlw	0x01
	andwf	paru,0
	xorwf	bug,1
	decfsz	count3,F
	goto	roata
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

conversie
	movf	LO,W		; LO -> LO_TEMP
	movwf	LO_TEMP		
	movf	HI,W		; HI -> HI_TEMP
	movwf	HI_TEMP
	bcf	blank,0		; invalidate flag	
	
	movlw	0x27		; verify div. to 10000
	movwf	TEMP3		
	movlw	0x10		 
	movwf	TEMP2		
	call	convb	
	
	movlw	0x03		; verify div. to 1000
	movwf	TEMP3		
	movlw	0xE8		
	movwf	TEMP2		
	call	convb	

	clrf	TEMP3		; verify div. to 100
	movlw	0x64		
	movwf	TEMP2		
	call	convb

	clrf	TEMP3		; verify div. to 10
	movlw	0x0A		
	movwf	TEMP2		
	call	convb

	clrf	TEMP3		; verify div. to 1
	movlw	0x01		
	movwf	TEMP2
	bsf	blank,0
	call	convb

homa	goto	homa        ; stay here
;*****************************************	
convb
	clrf	TEMP1		; clear counter
conv_high
	movf	TEMP3,W
	subwf	HI_TEMP,W	; TEST: HI_TEMP-TEMP3 >0 ?
	btfss	STATUS,C			
	goto	conv_end	; rezultat negativ, exit
	btfss	STATUS,Z	; TEST: HI_TEMP-TEMP3 = 0 ?
	goto	conv_low	; test zero, goto if result > 0
	movf	TEMP2,W		; Precondition: HI-TEST is zero
	subwf	LO_TEMP,W	; TEST: LO_TEMP-TEMP2 > 0 ?
	btfss	STATUS,C	; 
	goto	conv_end	; rezultat negativ, exit
conv_low	
	movf	TEMP3,W
	subwf	HI_TEMP,F	; STORE: HI_TEMP = HI_TEMP - TEMP3
	movf	TEMP2,W
	subwf	LO_TEMP,F	; STORE: LO_TEMP = LO_TEMP - TEMP2
	btfss	STATUS,C	; daca imprumut
	decf	HI_TEMP,F	; decrement HI
	incf	TEMP1,F		; increment counter
	bsf	blank,0		; invalidate flag
	goto	conv_high
conv_end
	movlw	0xB0
	addwf	TEMP1,W		; B0 is ascii offset, add counter
	btfss	blank,0		; check flag
	movlw	0xB0		; display zeros
	movwf	buff
	call	push_lcd
	return



;*****************************************************************

conv_5d
	movf	c0,W		; LO -> LO_TEMP
	movwf	f0		
	movf	c1,W		; HI -> HI_TEMP
	movwf	f1
	movf	c2,W
	movwf	f2		;	
;******************************************
conversie_3
	bsf	punct,0
	bcf	count5,0		; invalidate flag	
	movlw	0x98		; verify div. to 10000000
	movwf	temp2		
	movlw	0x96		 
	movwf	temp1	
	movlw	0x80		
	movwf	temp0	
	bsf		count4,0	
	call	convb
	
	movlw	0x0F		; verify div. to 1000000
	movwf	temp2		
	movlw	0x42		 
	movwf	temp1	
	movlw	0x40		
	movwf	temp0	
	bcf		count4,0	
	call	convb

	movlw	0x01		; verify div. to 100000
	movwf	temp2		
	movlw	0x86		 
	movwf	temp1	
	movlw	0xA0		
	movwf	temp0		
	call	convb
	
conversie_2
	bcf		count4,0
	clrf	temp2		; verify div. to 10000
	movlw	0x27		 
	movwf	temp1	
	movlw	0x10		
	movwf	temp0		
	call	convb

	clrf	temp2		; verify div. to 1000
	movlw	0x03		 
	movwf	temp1	
	movlw	0xE8		
	movwf	temp0		
	call	convb

	clrf	temp2		; verify div. to 100
	clrf	temp1	
	movlw	0x64		
	movwf	temp0		
	call	convb

	btfsc	punct,0	; check flag
	call	virgula

	clrf	temp2		; verify div. to 10
	clrf	temp1	
	movlw	0x0A		
	movwf	temp0		
	call	convb


	movf	f0,W		; copy units (c0/1=c0)
	movwf	count1
	bsf		count5,0		; remove blank checker in case of zero
	call	conv_end
	bcf		punct,0
	return
;*****************************************	
convb
	clrf	count1		; clear counter
conv_high
	movf	temp2,W
	subwf	f2,W	
	btfss	STATUS,C			
	goto	conv_end	; resultat negativ, exit
	btfss	STATUS,Z; skpz	
	goto	conv_low	; test zero, goto if result > 0
	movf	temp1,W	
	subwf	f1,W	
	btfss	STATUS,C;skpc	; skip, if true
	goto	conv_end	; result negativ, exit
	btfss	STATUS,Z;skpz
	goto	conv_low	; test zero, goto if result > 0
	movf	temp0,W	
	subwf	f0,W
	btfss	STATUS,C;skpc	; skip, if true
	goto	conv_end	; result negativ, exit
conv_low	
	movf	temp0,W
	subwf	f0,F	;
	btfss	STATUS,C;skpc	; skip, if true
	decf	f1,F	; decrement 
	movf	temp1,W
	subwf	f1,F	; 
	btfss	STATUS,C;skpc	; skip, if true
	decf	f2,F	; decrement
	movf	temp2,W
	subwf	f2,F	; 
	incf	count1,F		; increment counter
	bsf		count5,0		; invalidate flag
	goto	conv_high
conv_end
	movlw	0x30
	addwf	count1,W		; 30 is ascii offset, add counter
	btfss	count5,0		; check flag
	movlw	0x20		; clear preceeding zeros
	btfss	count4,0		; check flag
	call	lcdta
	return
;**********************************************************************	



Back to my home page

Last updated January, 2010