⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d.txt

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 TXT
📖 第 1 页 / 共 5 页
字号:

addtens10
		movlw	1
addtensx0
		movwf	mantissa
		movlw	0
addtensxx
		movwf	exponent	;exponent
					;flows into addtens

;addtens: enter with mantissa and exponent registers loaded.
;value specified gets added into decimal registers.
;w/flags/mantissa/exponent affected. Returns xlsb->xmsb updated.

addtens
		movf	mantissa,w	;check mantissa value
		btfsc	status,z
		return			;return if nothing to do!
		bcf	status,c	;clear carry
		rrf	exponent,w	;divide exponent by two (nibble oriented)
		addlw	xlsb		;point to proper nibble set
		movwf	fsr		;use it for indirect addressing of nibble sets
		addlw	-(xmsb+1)	;don't go too far!
		btfsc	status,z
		return			;return if all available digits done
		btfsc	exponent,0	;lsb tells us even or odd exponent
		goto	oddstuff
evenstuff
		call	even		;handle rightmost nibble
		incf	exponent,f	;prepare for next higher digit
		goto	addtens		;see if more to do...

oddstuff	
		call	odd		;handle leftmost nibble
		incf	exponent,f	;prepare for next higher digit
		goto	addtens		;see if more to do...
even		
		movlw	b'00001111'	;just look at right nibble
		andwf	indf,w		; of value pointed to
		addwf	mantissa,f	;add mantissa+current value 
					; and save in mantissa
		movf	mantissa,w	;copy into w, too
		addlw	-d'10'		;same as x-10
		btfsc	status,z
		goto	setevenzero	;10-10=0
		btfsc	status,c	
		goto	setevenpositive	;cy=1 if x-10 is positive
setevennegative
		movlw	b'11110000'
		andwf	indf,f		;clear out right nibble
		movf	mantissa,w	;copy mantissa+current value into w
					; (value is less than 10)
		iorwf	indf,f		;now byte contains new right nibble
		clrf	mantissa	;clear carryout pointer
		return			;all done! no carryout.
setevenzero
		movlw	b'11110000'
		andwf	indf,f		;clear out right nibble
		clrf	mantissa	;set mantissa to 1 for carryout.
		incf	mantissa,f	; 0+1=1
		return			;now update next because of carryout
setevenpositive	
		movwf	mantissa	;save positive value
		movlw	b'11110000'
		andwf	indf,f		;clear out right nibble
		movf	mantissa,w	;copy mantissa+current value into w
					; (value is less than 10)
		iorwf	indf,f		;now byte contains new right nibble
		clrf	mantissa	;set mantissa to 1 for carryout.
		incf	mantissa,f	; 0+1=1
		return			;now update next because of carryout
		
odd
		swapf	indf,f		;swap nibbles
		call	even		; and use even routines! how sneaky.
		swapf	indf,f		;swap nibbles back to normal
		return			;return with possible carry in mantissa
		




;sample calling routine
;		call	lcdclear1
;		movlw	onetext-starttext	;note how we subtract starttext address
;		call	textout			; to make an 8 bit address PIC can handle.
;		call	lcdclear2		; sometext routine and attendant data
;		movlw	twotext-starttext	; should be within 1st 256 bytes of program
;		call	textout			; to ensure addressability.


textout		
		movwf	temp1			;save that address!
textloop
		call	sometext		;retlw a byte
		addlw	0			;set z flag if we recovered terminating 0
		btfsc	status,z
		return				;once we got 0 we are done
		call	lcdout			;everything else we send to lcd
		incf	temp1,f			;NEXT!
		movf	temp1,w			;need new address in both temp1 and w
		goto	textloop		;do a whole string of 'em

;routine to output packed bcd+ nibbles

dataout
		call	lcdhome1		;data goes on 1st line of lcd
		movlw	8			;8 bytes = 16 packed bcd+ nibbles
		movwf	temp2			;temp2 holds byte count
		movlw	xmsb
		movwf	fsr			;indirect addressing set to xmsb
dataloop
		swapf	indf,w			;get left nibble, since we are outputting
						; digits etc from left to right (msb->lsb)
		call	convert			;convert 4 bits into full regular ascii
		call	lcdout			;and display it on lcd (including commas, etc.)
		movf	indf,w			;then right nibble
		call	convert
		call	lcdout
		decf	fsr,f			;point to next
		decf	temp2,f
		btfsc	status,z
		return				;done when all 8 bytes done
		goto	dataloop		;otherwise keep going.
		


;these routines are used to "shift and drop" coded items such as commas and decimal
;points into the packed bcd+ decimal set.

;first we have some space-saving attempts that code some of the more popular sd constructs
sd4c
		movlw	d'4'
sdxc
		movwf	shift
		movlw	ncomma
		goto	sd	

sd12s
		movlw	d'12'
		movwf	shift
		movlw	nspace
		goto	sd
sd12p
		movlw	d'12'
sdxp
		movwf	shift
		movlw	nperiod
		goto	sd		
sd15x
		movlw	d'15'
		movwf	shift
		movlw	nx
					;flows into shiftanddrop

;enter with shift position in (shift)temp1 and replacement data in w.
;use fsr method. shift left

;the method used for shifting is to shift a nibble at a time

shiftanddrop
sd					;(I use the shorter label when I have to type.)
		movwf	wlcdtemp	;steal the lcd's temp register to conserve resources.
		movlw	xmsb
		movwf	fsr		;fsr now points to msb
		movf	temp1,w		;check for 'more to do'
		btfsc	status,z	;if position is 0 no shift to do
		goto	stuffleft	; so just stuff data
nextleft
		swapf	indf,f		;otherwise 'shift' nibble left
		movf	indf,w
		andlw	b'11110000'	;clear right nibble
		movwf	indf		;of current byte
		decf	temp1,f		;update shift counter
		btfsc	status,z
		goto	stuffright	;if done, stuff new data
					;otherwise do nextright...
nextright		
		decf	fsr,f		;if not done, shift across bytes
		swapf	indf,w		; copy high nibble into low nibble and to w
		andlw	b'00001111'	;get nibble to be shifted...
		incf	fsr,f		;access 'current' location again
		iorwf	indf,f		;replace with shifted data.
		decf	fsr,f		;point to next byte!
		decf	temp1,f		;update shift counter
		btfsc	status,z
		goto	stuffleft	;if done, stuff new data
		goto	nextleft
		
stuffleft
		movf	indf,w		;recover current byte
		andlw	b'00001111'	;clear left nibble
		movwf	indf		;replace byte
		swapf	wlcdtemp,w	;move replacement nibble into position
		andlw	b'11110000'	;just replace left nibble
		iorwf	indf,f		;done!
		return
		
stuffright
		movf	indf,w		;recover current byte
		andlw	b'11110000'	;clear right nibble
		movwf	indf		;replace byte
		movf	wlcdtemp,w
		andlw	b'00001111'	;just replace right nibble
		iorwf	indf,f		;done!
		return

;a whole bunch of lcd routines to make life easier

initwlcd
		call	wmillisecs	;wait w ms (may be power up condition)
		movlw	b'00110000'
		andlw	b'11110000'	;just high bits first
		movwf	nibbles		;save high nibbles
		movf	shadowb,w	;get control bits from flags
		andlw	b'00001111'	; they are in lower 4 bits
		iorwf	nibbles,w	;save result in w
		movwf	portb		;output high bits and controls...
		bsf	portb,lcde	;begin enable strobe...
		nop			;add extra 1 us delay
		bcf	portb,lcde	;end enable strobe
		return

lcdreset
		movlw	d'16'
		call	initwlcd	;wait 16 ms (may be power up condition)
					;do lcd song and dance init thing
		
		movlw	d'1'
		call	initwlcd	;wait 1 ms (may be power up condition)
					;do lcd song and dance init thing
					
					;most data sheets show 3 initializations,
					;but I have always found 2 to be enough.

		movlw	d'1'
		call	wmillisecs	;wait 1 ms (we don't read busy flag)
		movlw	b'00100000'
		andlw	b'11110000'	;just high bits first
		movwf	nibbles		;save high nibbles
		movf	shadowb,w	;get control bits from flags
		andlw	b'00001111'	; they are in lower 4 bits
		iorwf	nibbles,w	;save result in w
		movwf	portb		;set for 4 bit mode
		bsf	portb,lcde	;begin enable strobe...
		nop			;add extra 1 us delay for good luck
		bcf	portb,lcde	;end enable strobe
		
		movlw	d'1'
		call	wmillisecs	;wait 1 ms to allow it to take
		
					;from here on out we use 4 bit interface!
					;proper delays are built-in.
					
		movlw	b'00101000'	;set 4 bit, 2 lines, 5x7 font
		call	lcdcommand
		
		movlw	b'00001100'	;display on, cursor off,blink off
		call	lcdcommand
		
		call	lcdclear	;clear lcd
		
		movlw	b'00000110'	;increment cursor and no display shift
		call	lcdcommand
		return	
		
;lcd commands: called subroutines. each clobbers w.

lcdclear
		movlw	b'00000001'
		goto	lcdcommand
		
lcdclear1	call	lcdhome1
		call	lcdlineclear
		goto	lcdhome1

lcdclear2	call	lcdhome2
		call	lcdlineclear
		goto	lcdhome2
		
lcdhome1
		movlw	b'00000010'	;home to line 1 and set display to normal
		goto	lcdcommand
		
lcdaddress	
		iorlw	b'10000000'	;append command to address in w.
		goto	lcdcommand	; sets ddram address.

lcdhome2	movlw	b'11000000'	;set ddram address to h'40'
		goto	lcdcommand	; which is line 2
		
lcdlineclear	movlw	d'16'		;lines are 16 characters long
		movwf	temp1
llcloop		movlw	' '		;clear by writing 16 spaces
		call	lcdout
		decf	temp1,f		;update loop count and w
		movf	temp1,f
		btfss	status,z
		goto	llcloop
		return	

;lcdout: called subroutine. w contains data to be sent in two 4 bit nibbles.
;includes delay since we do not read the busy flag. w unaffected.

lcdout
		bsf	shadowb,lcdrs	;set data mode in flags register
		call	lcdnibbles	;do common lcd routine
		return
		



;lcdcommand: called subroutine. w contains data to be sent in two 4 bit nibbles.
;includes delay since we do not read the busy flag. w not affected.

lcdcommand
		bcf	shadowb,lcdrs	;set instruction mode in flags register
		call	lcdnibbles	;do common lcd routine
		movlw	d'4'
		call	wmillisecs	;wait another 4 ms (we don't read busy flag)
		movf	wlcdtemp,w	;we have w back!
		return

;NOTE! lcdnibbles is the low-level interface between data to be displayed and
; the actual hardware implementation of the 4 data bits and control stuff.
; if you implement a different port useage, then this routine would have to
; be modified. pay special attention to the necessary bit masks and port used!
		
lcdnibbles
		movwf	wlcdtemp	;save w!
		movlw	d'1'
		call	_200usecs	;wait min. .2 ms (we don't read busy flag)
		bcf	shadowb,lcde	;set e strobe low (default)
		movf	wlcdtemp,w	;recover original
		andlw	b'11110000'	;just high bits first
		movwf	nibbles		;save high nibbles
		movf	shadowb,w	;get control bits from flags
		andlw	b'00001111'	; they are in lower 4 bits
		iorwf	nibbles,w	;save result in w
		movwf	portb		;output high bits and controls...
		bsf	portb,lcde	;begin enable strobe...
		nop			;add extra 1 us delay
		bcf	portb,lcde	;end enable strobe
		
		swapf	wlcdtemp,f	;swap hi and lo nibbles of original
					;(leave lcdrs bit set as-is)
					
		movf	wlcdtemp,w	;recover swapped nibble
		andlw	b'11110000'	;now low bits are in high bits
		
		movwf	nibbles		;save this nibble (which was low bits)
		movf	shadowb,w	;get control bits from flags
		andlw	b'00001111'	; they are in lower 4 bits
		iorwf	nibbles,w	;save result in w
		movwf	portb		;output low bits...
		bsf	portb,lcde	;begin enable strobe...
		nop			;slight delay
		bcf	portb,lcde	;strobe e goes low now
		
		bsf	shadowb,lcdrs	;default in flags is data mode
		bcf	shadowb,lcde	;default in flags is strobe enable low
		swapf	wlcdtemp,f	;back to normal...
		movf	wlcdtemp,w	;we have w back!
		return
		

;==============================================================================
; _200usecs: (subroutine) : 200 usec delay.
;==============================================================================

	
_200usecs
		movlw	(d'200'-3)/3	;number of loops
		movwf	xmillisec	;(shared register)
_200loop
		decf	xmillisec,f	;count down
		btfss	status,z
		goto	_200loop
		return

delay1000
	call	xmillisecs
delay800
	call	xmillisecs
delay600
	call	xmillisecs
delay400
	call	xmillisecs
				;flow into xmillisecs for last 200 ms delay
;==============================================================================
; xmillisecs: (subroutine) : 200 msec delay. flows into wmillisec.
;==============================================================================

xmillisecs
	movlw	d'200'		;delay...

;==============================================================================
; wmillisecs: (subroutine) : delay for w millisecs. tuned for 4.00 mhz xtal.
;==============================================================================

;called subroutine set to generate delays.
;enter with # of milliseconds to delay in W

wmillisecs

	movwf	xmillisec	;save # of millisecs in w to delay.

	incf	xmillisec,f	;adjust to account for initial decrement.
				;first (outer) loop.
	
wmloop1
	decfsz	xmillisec,f	;update first (outer) loop
	goto	wmloopa		;if more to do, do it.
	
	return			;done when xmillisec=0.
	
wmloopa	
	clrf	ymillisec	;second (inner) loop
				;256 loops (256+1 becomes 0)
	
wmloopb	
	decfsz	ymillisec,f	;update 256 part of inner loop.
	goto	wmloopb		;3 usec per loop
	
	movlw	d'75'+1
	movwf	ymillisec	;75 loops for third loop
	
wmloopc	
	decfsz	ym

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -