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

📄 paulmon.txt

📁 国外一个可根据需要剪裁的51系列单片机的监控程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:
;---------------------------------------------------------;

nloc:
	mov	dptr, #prompt6
	acall	pcstr_h
	acall	ghex16
	jc	abort2
	jb	psw.5, abort2
	acall	dptrtor6r7
	ajmp	newline2

;---------------------------------------------------------;

erfr:
	acall	newline2
	mov	dptr, #erfr_cmd
	acall	pcstr_h
	mov	a, #','
	acall	cout_sp
	mov	dptr, #sure
	acall	pcstr_h
	acall	cin_filter_h
	acall	upper
	cjne	a, #'Y', abort_it
	acall	newline2
	lcall	erall
	mov	dptr, #erfr_ok
	jnc	erfr_end
	mov	dptr, #erfr_err
erfr_end:
	ajmp	pcstr_h



;---------------------------------------------------------;

intm:	acall	newline
	mov	r0, #0
intm2:	acall	newline
	cjne	r0, #0x80, intm3 
	ajmp	newline
intm3:	mov	a, r0
	acall	phex
	mov	a, #':'
	acall	cout
intm4:	acall	space
	mov	a, @r0
	acall	phex
	inc	r0
	mov	a, r0
	anl	a, #00001111b
	jnz	intm4
	sjmp	intm2





;**************************************************************
;**************************************************************
;*****							  *****
;*****	     2k page boundry is somewhere near here	  *****
;*****	       (no ajmp or acall past this point)	  *****
;*****							  *****
;**************************************************************
;**************************************************************



;---------------------------------------------------------;
;							  ;
;   Subroutines for memory managment and non-serial I/O	  ;
;							  ;
;---------------------------------------------------------;




	; poll the flash rom using it's toggle bit feature
	; on D6... and wait until the flash rom is not busy
	; dptr must be initialized with the address to read
flash_wait:
	push	b
	clr	a
	movc	a, @a+dptr
flwt2:	mov	b, a
	inc	r5
	clr	a
	movc	a, @a+dptr
	cjne	a, b, flwt2
	pop	b
	ret

	;send the flash enable codes
flash_en:
	mov	dptr, #flash_en1_addr
	mov	a, #flash_en1_data
	movx	@dptr, a
	mov	dptr, #flash_en2_addr
	mov	a, #flash_en2_data
	movx	@dptr, a
	ret


;a routine that writes ACC to into flash memory at DPTR
; C is set if error occurs, C is clear if it worked

prgm:	xch	a, r0
	push	acc
	push	dpl
	push	dph
	acall	flash_en		;do first step, enable writing
	mov	dptr, #flash_wr_addr
	mov	a, #flash_wr_data
	movx	@dptr, a		;send flash write command
	pop	dph
	pop	dpl
	mov	a, r0
	movx	@dptr, a		;write the data
	acall	flash_wait		;wait until it's done
	clr	a
	movc	a, @a+dptr		;read it back
	clr	c
	xrl	a, r0
	jz	prgmend			;check if data written ok
	setb	c
prgmend:pop	acc
	xch	a, r0
	ret

; erase the entire flash rom
; C=1 if failure, C=0 if ok

erall:
	mov	dptr, #flash_er2_addr
	mov	a, #flash_er2_data
	acall	erblock			;use erblock to send erase all
	mov	dptr, #bflash
erall2:	clr	a
	movc	a, @a+dptr		;read back flash memory
	cpl	a
	jnz	erall_err		;check if it's really erased
	inc	dptr
	mov	a, #((eflash+1) & 255)
	cjne	a, dpl, erall2
	mov	a, #(((eflash+1) >> 8) & 255)
	cjne	a, dph, erall2
	clr	c
	ret
erall_err:
	setb	c
	ret


	;send a custom erase command.  This is used by erall,
	;and it's intended to be callable from the flash memory
	;so that custom block erase code can be implemented
erblock:
	push	acc
	push	dpl
	push	dph
	acall	flash_en		;send flash enable stuff
	mov	dptr, #flash_er1_addr
	mov	a, #flash_er1_data
	movx	@dptr, a		;send erase enable
	acall	flash_en		;send flash enable stuff
	pop	dph
	pop	dpl
	pop	acc
	movx	@dptr, a		;send erase command
	ajmp	flash_wait




;finds the next header in the external memory.
;  Input DPTR=point to start search (only MSB used)
;  Output DPTR=location of next module
;    C=set if a header found, C=clear if no more headers
find:	mov	dpl, #0
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xA5, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xE5, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xE0, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xA5, find3
	mov	dpl, #0			;found one here!
	setb	c
	ret
find3:	mov	a, #(emem >> 8)
	cjne	a, dph, find4		;did we just check the end
	clr	c
	ret
find4:	inc	dph			;keep on searching
	sjmp	find




;************************************
;To make PAULMON2 able to write to other
;types of memory than RAM and flash rom,
;modify this "smart_wr" routine.  This
;code doesn't accept any inputs other
;that the address (dptr) and value (acc),
;so this routine must know which types
;of memory are in what address ranges
;************************************


;Write to Flash ROM or ordinary RAM.  Carry bit will indicate
;if the value was successfully written, C=1 if not written.


smart_wr:
	push	acc
	push	b
	mov	b, a
	;do we even have a flash rom?
	mov	a, #has_flash
	jz	wr_ram
	;there is a flash rom, but is this address in it?
	mov	a, dph
	cjne	a, #(eflash >> 8), isfl3
	sjmp	wr_flash
isfl3:	jnc	wr_ram
	cjne	a, #(bflash >> 8), isfl4
	sjmp	wr_flash
isfl4:	jnc	wr_flash
	;sjmp	wr_ram

wr_ram: mov	a, b
	movx	@dptr, a	;write the value to memory
	clr	a
	movc	a, @a+dptr	;read it back from code memory
	clr	c
	subb	a, b
	jz	smwrok
	movx	a, @dptr	;read it back from data memory
	clr	c
	subb	a, b
	jz	smwrok
smwrbad:setb	c
	sjmp	smwrxit
smwrok: clr	c
smwrxit:pop	b
	pop	acc
	ret

wr_flash:
	mov	a, b
	lcall	prgm
	pop	b
	pop	acc
	ret




;---------------------------------------------------------;
;							  ;
;	Power-On initialization code and such...	  ;
;							  ;
;---------------------------------------------------------;

;first the hardware has to get initialized.

intr_return:
	reti

poweron:
	clr	a
	mov	ie, a		;all interrupts off
	mov	ip, a
	mov	psw, #psw_init
	;clear any interrupt status, just in case the user put
	;"ljmp 0" inside their interrupt service code.
	acall	intr_return
	acall	intr_return
	cpl	a
	mov	p0, a
	mov	p1, a
	mov	p2, a
	mov	p3, a
	mov	sp, #stack

;Before we start doing any I/O, a short delay is required so
;that any external hardware which may be in "reset mode" can
;initialize.  This is typically a problem when a 82C55 chip
;is used and its reset line is driven from the R-C reset
;circuit used for the 8051.  Because the 82C55 reset pin
;switches from zero to one at a higher voltage than the 8051,
;any 82C55 chips would still be in reset mode right now...

rst_dly:
	mov	r1, #200	;approx 100000 cycles
rdly2:	mov	r2, #249	;500 cycles
	djnz	r2, *
	djnz	r1, rdly2

;Check for the Erase-on-startup signal and erase Flash ROM 
;if it's there.

	mov	a, #has_flash
	jz	skip_erase
	mov	a, #erase_pin
	jz	skip_erase
	mov	r0, #250	;check it 250 times, just to be sure
chk_erase:
	mov	c, erase_pin
	mov	r1, #200
	djnz	r1, *		;short delay
	jc	skip_erase	;skip erase if this bit is not low
	djnz	r0, chk_erase
	lcall	erall		;and this'll delete the flash rom
skip_erase:

;run any user initialization programs in external memory
	mov	b, #249
	acall	stcode

;initialize the serial port, auto baud detect if necessary
	acall	autobaud	;set up the serial port
	;mov	a, th1
	;lcall	phex

;run the start-up programs in external memory.
	mov	b, #253
	acall	stcode

;now print out the nice welcome message

welcome:
	mov	r0, #24
welcm2: lcall	newline
	djnz	r0, welcm2
	mov	r0, #15
	mov	a, #' '
welcm4: lcall	cout
	djnz	r0, welcm4
	mov	dptr, #logon1
	lcall	pcstr
	mov	dptr, #logon2
	lcall	pcstr
	lcall	dir
	mov	r6, #(pgm & 255)
	mov	r7, #(pgm >> 8)
	ljmp	menu


stcode: mov	dptr, #bmem	 ;search for startup routines
stcode2:lcall	find
	jnc	stcode5
	mov	dpl, #4
	clr	a
	movc	a, @a+dptr
	cjne	a, b, stcode4	;only startup code if matches B
	push	b
	push	dph
	mov	a, #(stcode3 & 255)
	push	acc
	mov	a, #(stcode3 >> 8)
	push	acc
	mov	dpl, #64
	clr	a
	jmp	@a+dptr		;jump to the startup code
stcode3:pop	dph		;hopefully it'll return to here
	pop	b
stcode4:inc	dph
	mov	a, dph
	cjne	a, #((emem+1) >> 8) & 255, stcode2
stcode5:ret			;now we've executed all of 'em


;to do automatic baud rate detection, we assume the user will
;press the carriage return, which will cause this bit pattern
;to appear on port 3 pin 0 (CR = ascii code 13, assume 8N1 format)
;
;	       0 1 0 1 1 0 0 0 0 1
;	       | |	       | |
; start bit----+ +--lsb	  msb--+ +----stop bit
;
;we'll start timer #1 in 16 bit mode at the transition between the
;start bit and the LSB and stop it between the MBS and stop bit.
;That will give approx the number of cpu cycles for 8 bits.  Divide
;by 8 for one bit and by 16 since the built-in UART takes 16 timer
;overflows for each bit.  We need to be careful about roundoff during
;division and the result has to be inverted since timer #1 counts up.  Of
;course, timer #1 gets used in 8-bit auto reload mode for generating the
;built-in UART's baud rate once we know what the reload value should be.


autobaud:
	mov	a, #baud_const	;skip if user supplied baud rate constant
	jnz	autoend_jmp
	mov	a, baud_save+3	;is there a value from a previous boot?
	xrl	baud_save+2, #01010101b
	xrl	baud_save+1, #11001100b
	xrl	baud_save+0, #00011101b
	cjne	a, baud_save+2, autob1
	cjne	a, baud_save+1, autob1
	cjne	a, baud_save+0, autob1
autoend_jmp:
	ajmp	autoend

autob1: ;wait for inactivity

	mov	pcon, #0x80	;configure uart, fast baud
	mov	scon, #0x42	;configure uart, but receive disabled
	mov	tmod, #0x11	;get timers ready for action (16 bit mode)
	clr	a
	mov	tcon, a
	mov	tl0, a
	mov	th0, a
	mov	tl1, a
	mov	th1, a

	;make sure there is no activity on the line
	;before we actually begin looking for the carriage return
	mov	r0, #200
autob1b:mov	r1, #30
autob1c:jnb	p3.0, autob1
	djnz	r1, autob1c
	djnz	r0, autob1b

autob2: ;look for the bits of the carriage return
	jb	p3.0, autob2	;wait for start bit
	jb	p3.0, autob2
	jb	p3.0, autob2	;  check it a few more times to make
	jb	p3.0, autob2	;  sure we don't trigger on some noise
	jb	p3.0, autob2
autob2b:jnb	p3.0, autob2b	;wait for bit #0 to begin
	setb	tr1		;and now we're timing it
autob2c:jb	tf1, autob1	;check for timeout while waiting
	jb	p3.0, autob2c	;wait for bit #1 to begin
autob2d:jb	tf1, autob1	;check for timeout while waiting
	jnb	p3.0, autob2d	;wait for bit #2 to begin
autob2e:jb	tf1, autob1	;check for timeout while waiting
	jb	p3.0, autob2e	;wait for bit #4 to begin
	setb	tr0		;start timing last 4 bits
autob2f:jb	tf1, autob1	;check for timeout while waiting
	jnb	p3.0, autob2f	;wait for stop bit to begin
	clr	tr1		;stop timing (both timers)
	clr	tr0

	jb	tf1, autob1	;check for timeout one last time

	;compute the baud rate based on timer1
	mov	a, tl1
	rlc	a
	mov	b, a
	mov	a, th1
	rlc	a
	jc	autob1		;error if timer0 > 32767
	mov	c, b.7
	addc	a, #0
	cpl	a
	inc	a		;now a has the value to load into th1
	jz	autob1		;error if baud rate too fast

	;after we get the carriage return, we need to make sure there
	;isn't any "crap" on the serial line, as there is in the case
	;were we get the letter E (and conclude the wrong baud rate).
	;unfortunately the simple approach of just looking at the line
	;for silence doesn't work, because we have to accept the case
	;where the user's terminal emulation is configured to send a
	;line feed after the carriage return.  The best thing to do is
	;use the uart and look see if it receives anything

autob3: mov	th1, a		;config timer1
	mov	tl1, #255	;start asap!
	mov	tmod, #0x21	;autoreload mode
	setb	ren		;turn on the uart
	setb	tr1		;turn on timer1 for its clock

	mov	a, th1
	cpl	a
	inc	a
	mov	r1, a
autob3b:mov	r0, #255
autob3c:djnz	r0, autob3c
	djnz	r1, autob3b

	jnb	ri, autob4
	;if we got here, there was some stuff after the carriage
	;return, so we'll read it and see if it was the line feed
	clr	ri
	mov	a, sbuf
	anl	a, #01111111b
	add	a, #246
	jz	autob4		;ok if 0A, the line feed character
	add	a, #5
	jz	autob4		;of if 05, since we may have missed start bit
autob1_jmp:
	ljmp	autob1
autob4:
	;compute the baud rate based on timer0, check against timer1 value
	mov	a, tl0
	rlc	a
	mov	r0, a
	mov	a, th0
	rlc	a
	mov	r1, a

⌨️ 快捷键说明

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