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

📄 ds1820.asm

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	bsf     status,c		; shift a 1 into quotient	;; ( rl rh ^ ql qh nl nh dl dh sign count )	sb_divide_skip_2	;; shift the quotient left	decf	fsr,f			; ->ql	rlf	indf,f			; ql	decf	fsr,f			; ->qh	rlf	indf,f			; qh		;; loop until all bits checked	movlw	d'6'	subwf	fsr,f			; ->count	decfsz  indf,f			; count	goto    sb_divide_loop	popl				; drop count	;; ( rl rh ql qh nl nh dl dh sign )	;; adjust stack	popf	r_ephemeral	movlw	d'4'	addwf	fsr,f			; drop nl nh dl dh	;; ( rl rh ql qh )		;; check effective sign difference and adjust quotient	btfss   r_ephemeral,7	retlw	0			; signs were same		;; signs different, negate quotient	goto	sb_negate;;; bank 1 follows		ifdef	__12c509	org	0x200		; push main to high bank	endif;;;;;; main program;;; main	;; clear stack	movlw	stack	movwf	fsr		;; clear output port	clrf	port		;; clear tris mirror	clrf	r_trism	bsf	r_trism,b_ow0	bsf	r_trism,b_ow1	bsf	r_trism,b_in	bsf	r_trism,b_ow2	bsf	r_trism,b_ow3	movf	r_trism,w		movwt	;; set option register to enable pull-ups and enable GP2	ifdef	__12c509	movlw	b'10011111'	; NOT_GPPU, T0CS	option	endif	;; set option register	ifdef	__16f84	;; enable port b weak pullups (NOT_RBPU=0)	;; free RA4/TOCKI pin (T0CS=0)	;; prescaler to WDT (PSA=1)	;; prescaler at 1:64, 18ms x 64 = 1.152sec	movlw	b'01011110'	movwf	OPTION_REG	endif	;; pause for 0.5s to let supply stabilise before chatting	pushl	d'195'pause_loop	pushl	d'0'			; 2.65ms	bank0	call	us10	bank1	decfsz	indf,f	goto	pause_loop	popl	;; test for fahrenheit mode, gp3 low	;; (if left open, it is pulled up to high)	btfss	port,b_in	bsf	r_trism,b_fahre		ifdef	notdefnoisy	;; need to account for gp0 being input now	;; test for noisy mode; gp0 connected to gp3	bank1	bsf	port,gp0	; turn on gp0	btfss	port,gp3	; see if gp3 	goto	noisy_skip	bcf	port,gp0	btfsc	port,gp3	goto	noisy_skip	bsf	b_noisy,r_trism	goto	noisy_donenoisy_skip	noisy_done	endif			;; say g'daygday	pushl	'R'			; reset	bank0	call	tx_header	pushl	0			; start at beginning of tablegday_loop	movf	indf,w			; pull down index	bank0	call	t_gday			; get the byte from the string	iorlw	0			; is zero?	bank1	bz	gday_exit		; if so, exit loop	pushw	bank0	call	tx_byte			; transmit the character	incf	indf,f			; increment index	bank1	goto	gday_loopgday_exit	;; print C or F according to b_fahre	movlw	'C'			; assume low	btfsc	r_trism,b_fahre	movlw	'F'			; set high if non zero	pushw	bank0	call	tx_space	call	tx_byte			; display the F or C	call	tx_crlf			; followed by a new line pair		;; select starting sensor	movlw	1<<b_ow0	movwf	r_which	;; main loop begins hereloop		;; determine displayable sensor number	movlw	0		; initialise sensor counter	movwf	r_ephemeral	movf	r_which,w	; copy selection mask to temporary	movwf	r_temporary	bank1	which_loop	btfsc	r_temporary,0	; have we shifted the bit down yet?	goto	which_exit	; yes, exit the loop	rrf	r_temporary,f	; shift the bit down	incf	r_ephemeral,f	; increment the sensor number	goto	which_loop	which_exit	movf	r_ephemeral,w	bank0	call	t_which		; translate to printable	pushw			; save on stack		;; reset bus to determine if sensor is present	;; bank0	call	ow_reset		; ( -- flag )	popw	iorlw	0x0			; set zero flag if sensor absent	bank1	bnz	present	;; if non-verbose, don't report pins without sensors	;; bank1	;; btfss	port,b_in		; verbose mode on?	goto	hello_skip		; no, skip it	;; report a sensorless pin	bank0	call	tx_header		; transmit the sensor number	movf	r_which,w		; fetch the selection mask	andwf	port,w			; keep the port bit we want	movlw	'L'			; assume low	skpz	movlw	'H'			; set high if non zero	pushw	;; bank0	call	tx_byte			; display the L or H	call	tx_crlf	bank1	goto	absent	hello_skip	popl				; drop the sensor number	goto	absentpresent	bank0	call	tx_header		; transmit the sensor number		;; skip rom check sequence	pushl	ow_command_skip	bank0	call	ow_tx	;; commence conversion	pushl	ow_command_convert	call	ow_tx	;; wait until sensor not busy		;; ??? we wait until we get eight bits of 1's, which could take	;; longer than just waiting for one bit of 1.  try waiting for 1?	;; ds1820 specification says 200ms typical, 500ms maximumbusy	bank0	call	ow_rx			; fetch a byte	popw				; pop the byte from stack	xorlw	0xff			; test for 0xff	bank1	bnz	busy			; loop if not equal	;; ask sensor for data	;; reset bus	bank0	call	ow_reset		; ( -- flag )	popw	iorlw	0x0			; set zero flag if sensor absent	bank1	bz	absent	;; skip rom check sequence	pushl	ow_command_skip	bank0	call	ow_tx	;; request data	pushl	ow_command_read	call	ow_tx		;; read data from sensorow_get	macro	m_byte		; get byte to address	;; bank0	call	ow_rx	popf	m_byte	endm		ow_get	r_ds_lsb	ow_get	r_ds_msb	ow_get	r_ds_rem	; ignore low alarm byte	ow_get	r_ds_rem	; ignore high alarm byte	ow_get	r_ds_rem	; ignore reserved byte	ow_get	r_ds_rem	; ignore reserved byte	ow_get	r_ds_rem	ow_get	r_ds_count	ow_get	r_ds_crc	;; ??? check the crc some day!	;; in verbose mode, dump the data in hexdata	bank1	;; btfss	port,b_in		; verbose mode on?	goto	data_skip		; no, skip it		tx_put	r_ds_lsb	tx_put	r_ds_msb	tx_put	r_ds_rem	tx_put	r_ds_count	tx_put	r_ds_crc	call	tx_spacedata_skip;;;;;; dump stack pointer at top value;;; 	if	debug == 1dump	macro	m_label	pushl	m_label			; print the label byte	bank0	call	tx_byte	tx_put	fsr			; ??? stack check	call	tx_space	endm	elsedump	macro	m_label			; null macro	endm	endif;;;;;; Calculation of high resolution temperature from the count per degrees;;; c and remaining count values fetched from the DS1820 scratchpad.;;;;;; high-res-temp = ( temperature >> 1 ) - 0.25;;;                 + (count-per-c - count-remain) / (count-per-c);;; ;;; Problem:	Result is truncated to two decimal places rather than being;;;		rounded.  Solution not yet planned.;;; 	;; move temperature as read to accumulator	pushf16	r_ds_lsb	;; shift right to truncate 0.5C LSB	bcf	status,c	; start with a clear carry flag	rrf	indf,f	incf	fsr,f	rrf	indf,f	decf	fsr,f	;; multiply by 100 to scale to hundredths of degrees	pushl16	d'100'	bank0	call	sb_multiply	dump	'A'	;; subtract 25 from accumulator	pushl16	d'25'	;; bank0	call	sb_subtract	dump	'B'	;; keep on stack for later use	;; take eight bit count per degrees c	;; subtract count remaining	movf	r_ds_rem,w	; get count remaining	subwf	r_ds_count,w	; subtract it from count per degrees c	pushw			; place on stack	pushl	d'0'		; extend to sixteen bits	;; multiply by 100 to scale	pushl16	d'100'	;; bank0	call	sb_multiply	dump	'C'	;; divide by count per degrees c	pushf	r_ds_count	pushl	d'0'			; extend to sixteen bits	;; bank0	call	sb_divide	call	sb_nip			; drop remainder	dump	'D'	;; we now have offset from temperature in hundredths of degrees	;; add to previouosly saved value	;; bank0	call	sb_add	dump	'E'	;; we now have the measurement in degrees centigrade, scaled by	;; 100, such that 23.54 degrees is binary value for decimal 2354		;; convert to fahrenheit	bank1	btfss	r_trism,b_fahre		; if bit zero, degrees C	goto	fahrenheit_skip		; yes, skip it		bank0	pushl16	d'9'		; multiply by nine	call	sb_multiply	pushl16	d'5'		; divide by five (therefore multiply by 1.8)	call	sb_divide	call	sb_nip		; drop remainder	pushl	d'128'		; add thirty two (3200)	pushl	d'12'	call	sb_add	fahrenheit_skip	;; check sign of result	bank1	btfss	indf,7		; sign bit of signed integer result	goto	skip		; bit cleared, it is positive	;; issue negative sign to output	pushl	'-'	bank0	call	tx_byte	;; subtract from zero	call	sb_negateskip		;; convert value to bcd	bank0	call	sb_bcd	dump	'F'	;; transmit the bcd output buffer	call	tx_byte_hex		; d2 (msd)	call	tx_byte_hex		; d1	pushl	'.'			; interject the decimal place '0655.35'	call	tx_byte	call	tx_byte_hex		; d0 (lsd)	;; finish the output off with a newline	call	tx_crlf		;; delay for a while between outputs, try to get 500ms	bank1	;; btfsc	port,b_in		; verbose mode on?	;; goto	snooze_skip		; yes, skip it		;; (above takes 279ms, so we need 221ms)	pushl	d'85'			; ( outer ) [experimental figure]snooze_loop	pushl	d'250'			; ( outer inner )	bank0	call	us10	bank1	decfsz	indf,f			; ( outer )	goto	snooze_loop	popl				; ( )snooze_skip	absent	;; switch to next sensor by spinning the mask around to next combo		btfss	r_which,7		; propogate bit 7 to carry flag	bcf	status,c	btfsc	r_which,7	bsf	status,c	rlf	r_which,f		; logical left rotate (spin bits)	movlw	m_ow			; is it a bit we can use?	andwf	r_which,w	bz	absent			; no, so spin it again		;; clear watchdog timer!	clrwdt		;; and do it all again	goto	looplast2	retlw	0		; define the last byte used in page 2/3	;; ease determination of last used data address	cblock		r_zzz	endc	;; calibration for 12C509-JW part	ifdef	__12c509	ifdef	jw	org	0x3ff	movlw	0x50			; 12c509 #1	; movlw	0x30			; 12c509 #2	endif	endif	;; cross-checks	ifdef	__12c509	if	r_zzz > 0x1f	messg	"error:	last allocated file register is not in bank 0"	endif	if	last0 > 0xff	messg	"error: last function in page 0 is beyond call limit"	endif	if	last2 > 0x3ff	messg	"error:	code in page 3 runs over to page 4 (>0x3ff)"	endif	endif	end

⌨️ 快捷键说明

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