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

📄 d.txt

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

offsetx				;pointer to current offset group

offset_0			;zero adjust and comparison register
offset_1			; for +/- comparisons.
offset_2

offset1_0			;zero adjust for lowest scale
offset1_1
offset1_2

offset2_0			;zero adjust for second scale
offset2_1
offset2_2

offset3_0			;zero adjust for third scale
offset3_1
offset3_2

offset4_0			;zero adjust for highest scale
offset4_1
offset4_2

over_0				;overflow binary counter
over_1				; tells us when sync wait is too long
over_2

		endc

;aliases: these allow alternate name for systems resources.
; it makes reading the program a bit easier while conserving resources

xlsb		=		x10
xmsb		=		xfe
shift		=		temp1
drop		=		wlcdtemp
mantissa	=		temp0
exponent	=		temp3

;shadowb: bit assignments

;LOW 4 BITS ARE SHADOW FOR PORTB   (Some have already been defined)

;periodin	=		h'00'		;inb selected period input
						; (not used, but still registered)
;pselect	=		h'01'		;outb period select 
						; 0=period  1=px100
;lcde		=		h'02'		;outb lcd enable line
;lcdrs		=		h'03'		;outb lcd rs line (data/!instruction)

;flags: bit assignments

intoverflow	=		h'0'		;1=overflow during interrupt routine
;		=		h'1'		;not used
;		=		h'2'		;not used
gotit		=		h'3'		;1=we have data
plusminus	=		h'4'		;1=plus [bin24 > offset]
flipflop	=		h'5'		;flipflop indicator
;		=		h'6'		;not used
;		=		h'7'		;not used

;autoflags: bit assignments

manual		=		h'0'		;1=manual 0=auto
stop		=		h'1'		;1=stop 0=continue operation
rangechange	=		h'2'		;1=range change
toolong		=		h'3'		;1=too long

;conversions used by decimal nibble output routines

n0		=		h'0'
n1		=		h'1'
n2		=		h'2'
n3		=		h'3'
n4		=		h'4'
n5		=		h'5'
n6		=		h'6'
n7		=		h'7'
n8		=		h'8'
n9		=		h'9'
nspace		=		h'a'		;after number is produced
nplus		=		h'b'		; we add in special characters
nminus		=		h'c'
ncomma		=		h'd'
nperiod		=		h'e'
nx		=		h'f'


;
;program  1kx14 eeprom. (h'400') can only be changed via programmer, not on-the-fly.
;                

		
		org     	h'0000'		;set code origin

start		goto		setup		;we have to get past interrupt vector at 0004
		

		
;
;interrupts
;               there is a single interrupt location at 004
;               we must use flags to determine which interrupt...
;               this info is in intcon
;
;intcon register: byte assignments
;
;enables... 1=enable 0=disable
;<7>=gie=global_int_enable
;<6>=eeie=eeprom_int_enable
;<5>=t0ie=t0_int_enable (enables <2> t0if)
;<4>=inte=int_enable (rb0/int) (enables <1> intf)
;<3>=rbie=rb_int_enable (enables <0> rbif)
;
;flags. software reset. 0=reset 1=flagged
;<2>=t0if=t0_int_flag
;<1>=intf=int_flag (rb0/int)
;<0>=rbif=rb_int_flag (rb7-rb4)
;
;upon power up and !mclr!, intcon will contain 0000 000x
;this means that initially all interrupts are disabled.
;
;note: option_reg register is used to program use of tmr0 and wdt
;

		org     h'0004'		;interrupt vector location

inthandler
		;global interrupts automatically disabled on entry!
		;we must save context using a somewhat convoluted scheme
		movwf	savew		;save w register!
		swapf	status,w	;save status! (twisted)
		movwf	savestatus	;(we use swapf so as not to disturb Z!)
		movf	fsr,w		;save fsr! 
		movwf	savefsr
		
;actual interrupt code
		movf	tmr0,w		;save tmr0 in case we need it
		movwf	bin24_0		;save it as low byte
		btfss	intcon,t0if	;if not t0if it should be intf
		goto	intperiod	
inttmr0
		bcf	intcon,t0if	;reset t0if
		incf	bin24_1,f	;update 24 bit binary count
		btfss	status,z	;need carry?
		goto	intreturn	;all done.
		incf	bin24_2,f	;handled carry.
		btfss	status,z	;overflow?
		goto	intreturn	;if not, almost done
		call	set4		;otherwise range to top
		bsf	flags,intoverflow	;set overflow indicator
					;now flow into intperiod to terminate
					; and turn off interrupts

	
;intperiod occurs when rbo/int triggers on edge (intf)
; (it is also entered when there is an overflow!)
intperiod
		bsf	flags,gotit	;tell regular program we have data!
		clrf	intcon		;turn off all interrupts 
					;& clear all interrupt flags

intreturn
		comf	porta,w		;copy inverted porta to w
		andlw	b'00011100'	;check three bits at once
		btfsc	status,z
		goto	intfinish	;if all are low, then none pushed
		movf	porta,w
		movwf	acopy		;save copy of porta for later use
					;sort out the details later...
		
		
intfinish
		movf	savefsr,w	;restore fsr!
		movwf	fsr
		swapf	savestatus,w	;untwist twisted saved status
		movwf	status		;restore normalized status!
		swapf	savew,f		;restore w! first twist nibbles
		swapf	savew,w		;then twist again and place result in w.
					;(how convoluted!)


		retfie                  ;return from interrupt!
					;gie is auto-re-enabled.


;note that jump tables and decoder tables are limited to 256 bytes of program space,
;and care must be taken that tables not cross over page boundaries.
;the limitation is based on the 8 bit addressing scheme employed in tables due to
;the size of w.

;decoder tables take the form:
;label	
;		addwf	pcl,f	;this executes an effective jump forward
;		retlw	'a'	;0 decodes as 'a'
;		retlw	'b'	;1 decodes as 'b'
;		retlw	'c'	;2 decodes as 'c' ... and so on
;
;


;convert special packed bcd+ nibbles into one of 16 8 bit code things

convert
		andlw	b'00001111'	;just the right nibble, please
		addwf	pcl,f		;this executes an effective jump forward 0-15
		retlw	'0'
		retlw	'1'
		retlw	'2'
		retlw	'3'
		retlw	'4'
		retlw	'5'
		retlw	'6'
		retlw	'7'
		retlw	'8'
		retlw	'9'
		retlw	' '		;decode the special stuff, too
		retlw	'+'
		retlw	'-'
		retlw	','
		retlw	'.'
		retlw	'_'		;underscore _ used for non-existent digits

;text for lcd messages
	
sometext			;routine to extract string pieces
		addwf	pcl,f	;this executes an effective jump forward
starttext
begin1text	dt	"PIC CAP METER",0	;put *your* name or message here 16 max
begin2text	dt	"Fr Tom McGahee",0	;put *your* name or message here 16 max
autotext	dt	"AUTORANGING     ",0
overtext	dt	"OVER-RANGE!",0
manual2text	dt	"MANUAL MODE",0
fourspaces	dt	"    "
ufnfpftext	dt	" ",mu,"f  nf  pf",0	;that mu is code for greek letter
zerotext	dt	"ZERO ALL RANGES",0


commontext	=	overtext	;share text to conserve memory
					;(every little "bit" counts!)
					;if you need extra bytes you can
					;reduce the size of the messages,
					;or even eliminate some entirely.
					;but leave fourspaces and ufnfpftext alone,
					;or at least modify them with care!



;               pic16c84 pinouts
;
;       ra2     <1>     <18>    ra1
;       ra3     <2>     <17>    ra0
;  (oc) ra4/tmr0<3>     <16>    osc1/clkin
;       !mclr!  <4>     <15>    osc2/clkout
;       gnd     <5>     <14>    +2 to +6 volts
;       rb0/int <6>     <13>    rb7
;       rb1     <7>     <12>    rb6
;       rb2     <8>     <11>    rb5
;       rb3     <9>     <10>    rb4
;
;osc1 & osc2 allow many types of timing choices. use device command to select.
;
;!mclr! tied high via resistor. use a switch to force it low for a reset.
;
;ra4 becomes the tmr0 external input if option_reg<5>=1. then option_reg<4> selects edge.
;ra4 is not ttl. it is oc out and schmitt in. use pullup resistor if needed.
;
;ra3-ra0 are ttl level. 
;
;rb7-rb0 are ttl. weak pullups can be programmed for inputs if option_reg<7>=0
;rb0/int acts as int pin if intcon<4> inte=1. intcon<1> intf is flag. software reset. 
;rb7-rb4 will generate an interrupt if intcon<3> rbie=1. intcon<0> rbif is flag. software reset.
;


setup		;initialize ports and registers

					;ra4/tmr0<3>, ra3<2>, ra2<1>, ra1<18>, ra0<17>
					;rb7<13>, rb6<12>, rb5<11>, rb4<10>
					;rb3<9>, rb2<8>, rb1<7>, rb0/int<6>

;page 1 stuff includes option_reg, trisa, trisb, eecon1, eecon2

	
		bsf     status,rp0	;allow access to page 1 stuff!
;*************** ignore mplab message[302] 
		movlw	b'00011100'	;set porta direction for i/o pins
		movwf	trisa		;0=output  1=input

		movlw	b'00000001'	;set portb direction for i/o pins
					;using rb0 as interrupt pin.
		movwf	trisb		;0=output  1=input

		bcf     option_reg,not_rbpu	;!rbpu! rb_pullup 0=enabled 1=disabled
						; enabling is based on individual port-latch values
						; we have disabled rb_pullup
						
		bcf     option_reg,intedg	;intedg 0=inc on falling 1=inc on rising
						; <<note: intedg and t0se use opposite definition!>>
						;we are incrementing on falling edge
						; because initial sync is on falling edge
						; and we want full period
						;
						;the edge used is later changed to speed
						;up sync process.

		bcf     option_reg,t0cs		;t0cs timer0clocksource 0=internal clkout 1=ra4/int 
						; (rts in some data sheets)
						; we clear so we can use internal clkout

		bcf     option_reg,t0se		;t0se timer0signaledge 0=inc on rising 1=inc on falling
						; (rte in some data sheets)
						; <<note: intedg and t0se use opposite definition!>>
						; in our application edge makes no difference,
						; so we arbitrarily choose rising edge.

		bsf     option_reg,psa	;psa prescalerassignment 0=tmr0 1=wdt
					;we do not use wdt, but we set prescaler
					;to wdt to allow div by 1 for tmr0!
					
					;ps2-ps0 determine prescalerrate, which is
					;dependent also on whether tmr0 or wdt is selected:
					;wdt from 0-7 is div by 1 2 4 8 16 32 64 128
					;tmr0 from 0-7 is div by 2 4 8 16 32 64 128 256
					;if wdt is assigned prescaler, then tmr0 is div by 1
					; here we will set prescaler to divide by 1 for tmr0
					; by assigning the prescaler to the wdt
					
		bcf     option_reg,ps2	;ps2 set for division by 1
		bcf     option_reg,ps1	;ps1
		bcf     option_reg,ps0	;ps0
;***************
		bcf     status,rp0	;allow access to page 0 stuff again. (back to normal)

;now use movlw/movwf and/or clrf statements to initialize any desired variables

		clrf	flags		;reset all flag bits
		clrf	autoflags
		movlw	b'11111111'	;ensure initial 1's to allow auto-zero!
		movwf	acopy

;ready now to begin  main user program.

mainprog  
		call	lcdreset	;reset lcd, set for 4 bit ops, clear, no cursor
		
;output opening two-line message and wait 2 seconds to allow circuitry to stabilize.

		movlw	begin1text-starttext
		call	textout
		call	lcdhome2
		movlw	begin2text-starttext
		call	textout
		call	delay1000
		call	delay1000
		
		call	lcdclear		;clear lcd and display "ZERO ALL" message
		movlw	zerotext-starttext
		call	textout

;set each range and perform initial Auto-Zero for each scale (click click click)

		call	set1
		call	setstuff
		
		call	set2
		call	setstuff
		
		call	set3
		call	setstuff
		
		call	set4
		call	setstuff

;finished with all the initialization stuff. so here we go loop de loop!

mainloop
		call	periodinit		;sync and acquire a count
		call	checkhit		;check for buttons and process

processdata
		clrf	intcon			;disable interrupts (we have other work to do)
		btfss	flags,intoverflow	;check state of interrupt overflow flag
		goto	convertit		;if no overflow, convert binary, etc.
overflowed
		call	lcdclear		;if interrupt overflow
		movlw	overtext-starttext	; clear display and show message
		call	textout
		goto	mainloop		;try again!

;subroutine to check for buttons being hit while interrupts are off

gethit
		comf	porta,w			;copy inverted porta to w
		andlw	b'00011100'		;check three bits at once
		btfsc	status,z
		return				;if all are low, then none pushed
		movf	porta,w
		movwf	acopy			;save copy of original porta for later use
						;sort out the details later...
		goto	oldhit

;subroutine to handle buttons being hit both in and out of interrupt.
;includes immediate check and check for "old" hits registered in acopy.

checkhit
						;first check for new hit key
		comf	porta,w			;copy inverted porta to w
		andlw	b'00011100'		;check three bits at once
		btfsc	status,z
		goto	oldhit			;if all are low, then none pushed
		movf	porta,w			;otherwise we have a new hit!
		movwf	acopy			;save copy of porta for later use by oldhit
						;liesurely flow into oldhit routine...
oldhit		
		comf	acopy,w			;check if a key was hit (old or new)
		andlw	b'00011100'		;check three bits at once
		btfsc	status,z
		return				;if all are low, then none pushed
		bcf	autoflags,manual	;clear manual so we can use setx routines!
		btfsc	acopy,upkey		;non-inverted original in acopy. is it UP key?
		goto	isitdown		;1 means it was NOT UP key, so check next key
itwasup						;0 means it WAS UP key
		movf	offsetx,w		;ummmm, where ARE we? (what range is current?)
		sublw	offset1_0		;compare by subtracting one from the other
		btfss	status,z		;are we at range 1?
		goto	upto3			;if not, check for others...
upto2
		call	set2 			;if it was 1, change to range 2

⌨️ 快捷键说明

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