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

📄 ds1820.asm

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;; ;;    $Id: ds1820.asm,v 1.1 2001/12/27 22:46:51 james Exp james $;; ;;    ds1820.asm, a PIC 12C509 or 16F84 based DS1820 translator;;    Copyright (C) 2002  James Cameron (quozl@us.netrek.org);;;;    This program is free software; you can redistribute it and/or modify;;    it under the terms of the GNU General Public License as published by;;    the Free Software Foundation; either version 2 of the License, or;;    (at your option) any later version.;;;;    This program is distributed in the hope that it will be useful,;;    but WITHOUT ANY WARRANTY; without even the implied warranty of;;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the;;    GNU General Public License for more details.;;;;    You should have received a copy of the GNU General Public License;;    along with this program; if not, write to the Free Software;;    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA;;;;;;    Refer to http://quozl.netrek.org/ts/ or http://quozl.linux.org.au/ts/;;    for further documentation.;; ;;    Variable prefix conventions;;       b_	bit number;;       m_	bit mask;;       r_	static file register;; ;;    Function prefix conventions;;       t_	entry point for a lookup table;;       ow_	one wire bus communication functions;;       tx_	serial data transmission functions;;       sb_	sixteen bit math functions;;;;    Source code reading hints;;       - INDF is a data stack pointer, FSR is top of stack,;;       - stack macros are used, check their definitions carefully,;;       - explicit bank switching is done in the code, using macros.;; 	ifdef		__16f84	processor	16f84	list		f=inhx8m	include		"p16f84.inc"	__config	_cp_off & _wdt_on & _hs_osc	endif	ifdef		__12c509	processor	12c509	list		f=inhx8m	include		"p12c509a.inc"	ifdef		jw	__config	_mclre_off & _cp_off & _wdt_on & _iNTrc_osc	endif	ifdef		cp	__config	_mclre_off & _cp_on & _wdt_on & _iNTrc_osc	endif        endif		ifdef	__16f84base	equ	0x0c		; first free file register addressstack	equ	0x4f+1		; end address of stackport	equ     portb		; port on which bits are usedmovwt	macro			; move w to tris        tris	trisb	endmbank0	macro	endmbank1	macro	endm	endif	ifdef	__16f84		endif	ifdef	__12c509base	equ	0x07		; first free file register addressstack	equ	0x1f+1		; end address of stackport	equ	gpio		; port on which bits are usedmovwt	macro			; move w to tris	tris	gpio	endmbank0	macro			; select low bank for goto/call	bcf	status,pa0	endmbank1	macro			; select high bank for goto/call	bsf	status,pa0	endm	endifdebug	equ	0		; set to one to enable calculation stack trace		;; port bit allocationsb_ow0	equ	0		; one wire bus to first DS1820b_ow1	equ	1		; one wire bus to second DS1820b_tx	equ	2		; serial output 2400 baud to hostb_in	equ	3		; mode flag inputb_ow2	equ	4		; one wire bus to third DS1820b_ow3	equ	5		; one wire bus to fourth DS1820	;; r_trism extra allocationsb_noisy	equ	6		; display more datab_fahre	equ	7		; display in fahrenheit	;; mask of one wire bus valid bits	m_ow	equ	1<<b_ow0|1<<b_ow1|1<<b_ow2|1<<b_ow3		;; data stack macros, to reduce memory use	;; fsr points to top element of stack	;; stack grows downward in memory addresses (upward on paper)	;; initial fsr high in register space	popw	macro				; pop to w from stack	movf	indf,w		incf	fsr,f		endmpushw	macro				; push from w to stack	decf	fsr,f		movwf	indf	endmpopl	macro				; pop literal (aka drop) from stack	incf	fsr,f		endmpushl	macro	m_literal		; push literal to stack	movlw	m_literal	pushw	endmpopf	macro	m_to			; pop to file addresss (uses w)	popw	movwf	m_to	endmpushf	macro	m_from			; push from file address (uses w)	movf	m_from,w		pushw	endmpopf16	macro	m_to			; pop 16-bit value	popf	m_to+1	popf	m_to	endmpushf16	macro	m_from			; push 16-bit value	pushf	m_from	pushf	m_from+1	endmpushl16	macro	m_literal		; push literal to stack	pushl	m_literal	pushl	0	endmpopl16	macro				; pop literal (aka 2drop)	popl	popl	endmmov16	macro	m_from,m_to		; move 16 bit value	movf	m_from+0,w		movwf	m_to+0	movf	m_from+1,w		movwf	m_to+1	endm	clr16	macro	m_from	clrf	m_from+0	clrf	m_from+1	endm	;; static register allocation	;; (12c509 has 9 registers addressible regardless of bank select)			cblock	base		r_ephemeral	; lowest stack level temporary storage		r_temporary	; middle stack level temporary storage			r_trism		; mirror of tristate output latch				; used by ow_high, ow_low, main			r_which		; bit mask of which DS1820 to talk to					; data read from device scratchpad		r_ds_lsb	; temperature lsb		r_ds_msb	; temperature msb		r_ds_rem	; remaining count after conversion		r_ds_count	; counts per degrees c		r_ds_crc	; cyclic redundancy check byte	endc	;; FSR based data stack is from 0x1f to 0x10, 16 bytes.		;; register addresses 0x30 to 0x3f are unallocated due to the	;; requirement to set bit five of FSR prior to access.	;; start of executable code		org	0x0	ifdef	__12c509	movwf	OSCCAL		; calibrate internal oscillator	endif	bank1	goto	main		; go to main program;;;;;; t_gday, table lookup of serial number;;;;;; input:	w contains offset in string;;; output:	w contains table value;;; t_gday	addwf	pcl,f			; vector to byte in serial #	;; include "version.inc"	; fetch version from file	dt	"V1.0"                  ; or use this line	dt	" "	;; include "serial.inc"		; fetch serial number from file	dt	"quozl.netrek.org/ts"   ; or use this line	retlw	0			; terminating zero for caller	;;;;;; t_which, table lookup of sensor number;;;;;; input:	w contains port bit number;;; output:	w contains ASCII sensor number;;; t_which	addwf	pcl,f		dt	"12  34"	;;;;;; us, delay a number of 10 microsecond cycles;;;;;; call stack:	none;;; data stack: ( cycles -- ) [total 1];;; us10	nop	nop	nop	nop	nop	nop	nop	decfsz	indf,f			; loop until done	goto	us10	popl				; drop argument	retlw	0;;;;;; ow_, routines for one wire bus communication;;;;;;;;; ow_command_*, one wire bus command bytes, from ds-1820 data sheet;;; ow_command_skip		equ	0xcc	; skip rom match sequenceow_command_convert	equ	0x44	; commence temperature conversionow_command_read		equ	0xbe	; read the data scratchpad;;;;;; ow_high, one wire high, allow output line to float to pull-up;;;;;; call stack:	none;;; data stack:	none;;; ow_high	movf	r_which,w	; fetch the selection mask	iorwf	port,f		; set that bit in port latch				; (a momentary 2uS fast pull-up)	iorwf	r_trism,w	; set that bit in tris mask	movwf	r_trism		; save tris mask	movwt			; set tris        retlw	0;;;;;; ow_low, one wire low, drive output line to ground;;;;;; call stack:	none;;; data stack:	none;;; ow_low	comf	r_which,w	; fetch inverted selection bits	andwf	port,f		; reset selected bits of port	andwf	r_trism,f	; reset selected bits of tris mirror	movf	r_trism,w	; fetch tris mirror	movwt			; set tris        retlw	0;;;;;; ow_reset, one wire reset, signal the slave that we want a bus reset;;;;;; call stack:	calls others that do not call;;; data stack:	( -- slave-present-flag ) [total 1];;; ow_reset	;; allow the bus to go high	call	ow_high	pushl	d'9'		; 60us delay	call	us10		;; now check to see if the bus is sick (no pull-up)	movf	port,w		; read port bits once only	andwf	r_which,w	; keep bits we want	bz	ow_reset_fail	; bus is being held down, fail	;; bus is healthy, now issue a reset	call	ow_low	pushl	d'50'		; 500us delay (480 to 960us)	call	us10	call	ow_high	pushl	d'9'		; 60us delay	call	us10	movf	port,w		; read port bits once only	andwf	r_which,w	; keep bits we want	bz	ow_reset_ok	pushl	d'39'		; total 480us delay	call	us10	ow_reset_fail	pushl	0		; return failure status	retlw	0ow_reset_ok	pushl	d'39'		; total 480us delay	call	us10	pushl	1		; return success status	retlw	0;;;;;; ow_rx, one wire receive, receive a byte from the bus;;;;;; call stack:	calls others that do not call;;; data stack:	( -- received-byte ) [total 1];;; ow_rx	pushl	d'0'		; received data	pushl	d'8'		; count of bits to read inow_rx_loop	call	ow_low		; generate short low for slave	nop	call	ow_high	nop			; delay for 6 microseconds	nop	nop	nop	nop        nop	movf	port,w		; read port bits once only	andwf	r_which,w	; keep bits we want	btfsc	status,z	; test if it is zero	bcf	status,c	; it is, so clear carry	btfss	status,z	; test if it is one	bsf	status,c	; it is, so set carry	incf	fsr,f		; rotate the bit into our copy	rrf	indf,f		decf	fsr,f			pushl	d'6'		; and wait for sixty microseconds	call	us10	decfsz	indf,f		; decrement count of bits to read	goto	ow_rx_loop	; loop until end of byte	incf	fsr,f		; drop count of bits	retlw	0	;;;;;; ow_tx, one wire transmit, output a byte on the bus;;;;;; call stack:	calls others that do not call;;; data stack:	( transmit-byte -- ) [total 3];;; ow_tx	pushl	d'8'		; initialise bits in byte counterow_tx_loop	incf	fsr,f		; rotate next bit to carry flag	rrf	indf,f		decf	fsr,f	        btfsc	status,c	; test the bit	goto	ow_tx_one	ow_tx_zero			; transmit a zero	call	ow_low		; by generating a long low	pushl	d'6'		; for sixty microseconds	call	us10	call	ow_high		; then return to high	goto	ow_tx_skip	; and continue to next bit	ow_tx_one			; transmit a one	call	ow_low		; by generating a short low	call	ow_high		; followed by a long high	pushl	d'6'		; for sixty microseconds	call	us10ow_tx_skip	decfsz	indf,f		; decrement bits in byte counter        goto	ow_tx_loop	; loop until counter zero	incf	fsr,f		; drop bits in byte counter	incf	fsr,f		; drop transmit byte	retlw	0		; return to caller;;;;;; tx_, routines for serial transmission, asynchronous;;; ;;;;;; tx_byte_hex, transmit a byte in hexadecimal;;;;;; call stack:	calls others that do not call;;; data stack:	( byte-to-send -- ) [total 3];;; tx_byte_hex	swapf	indf,w			; send high nibble first	call	tx_byte_hex_digit	popw	tx_byte_hex_digit	andlw	0x0f			; keep low nibble only	pushw				; save to data stack	movlw	0x0a			; test for greater than nine	subwf	indf,w			; by subtraction	movlw	0x30			; assume numeric	btfsc	status,c		; test result of subtraction	movlw	0x37			; alphabetic	addwf	indf,f			; offset to ASCII character;	goto	tx_byte			; fall-through optimisation;;;;;; tx_byte, transmit byte, serially send at 2400 ;;;;;; call stack:	none;;; data stack:	( transmit-byte -- ) [total 2];;; tx_byte	pushl	9			; bit count	bcf	status,c		; start bit	tx_byte_loop_1	btfsc	status,c		; echo bit to output        bcf     port,b_tx	btfss	status,c        bsf     port,b_tx        pushl   d'134'			; set timer for 416us, 2400 baud	;; [cycles=7]tx_byte_loop_2	decfsz	indf,f		goto	tx_byte_loop_2	popl				; drop timer	        incf	fsr,f			; rotate byte to send        rrf     indf,f		decf	fsr,f		;; [cycles=11+134*3]		decfsz	indf,f			; decrement bit count and loop	goto	tx_byte_loop_1	;; [cycles=14+134*3], therefore 2403.8 baud        bcf     port,b_tx		; send stop bit	        movlw   d'134'			; set timer	pushw

⌨️ 快捷键说明

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