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

📄 serial.asm

📁 web51的开发库
💻 ASM
字号:
; Serial Communication Library (c)Copyright 2000, Radek Benedikt;	benedikt@lphard.cz, http://benedikt.lphard.cz; ver. 1.20 -- Radek Benedikt 22-Feb-2002 - RD2/XRAM buffers; ver. 1.21 -- Radek Benedikt 12-Mar-2002 - timer 2 Baud Rate Generator;;*************************************************************;***		PROJECT WEB51  http://web51.hw.cz	    **;*************************************************************;   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, version 2.;;   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., 675 Mass Ave, Cambridge, MA 02139, USA.;   Tento program je volne programove vybaveni; muzete jej sirit a;   modifikovat podle ustanoveni Obecne verejne licence GNU, vydavane Free;   Software Foundation, verze 2;;   Tento program je rozsirovan v nadeji, ze bude uzitecny, avsak BEZ;   JAKEKOLI ZARUKY; neposkytuji se ani odvozene zaruky PRODEJNOSTI anebo;   VHODNOSTI PRO URCITY UCEL.;   Dalsi podrobnosti hledejte v Obecne verejne licenci GNU.;;   Kopii Obecne verejne licence GNU jste mel obdrzet spolu s timto;   programem; pokud se tak nestalo, napiste o ni Free Software Foundation,;   Inc., 675 Mass Ave, Cambridge, MA 02139, USA.;	.global	getchar	.global	xputchar	.global	pchar	.global	putchar	.global	sstat	.global	intRITI	.global	rxint	.global	txint	.global	srun	.global	rtscts	.global	xonxoff	.global	flagxoff	.global	xonrq	.global	xoffrq	.global	flagtxoff	.global	r1point	.global	s1point	.global	sser	.global	rser;extrn	BIT(cflag);.nolist.include "param.inc".list;	.equ	XON, 0x11	.equ	XOFF,0x13	.bitcomm rxint, 1	.bitcomm txint, 1	.bitcomm srun, 1	.bitcomm rtscts, 1	.bitcomm xonxoff, 1	.bitcomm flagxoff, 1	.bitcomm xonrq, 1	.bitcomm xoffrq, 1	.bitcomm flagtxoff, 1.if	RD2SER	.comm	r1point, 2	;receive serial buffer - pointer 1 (Rd, buff->app)	.comm	r2point, 2	;receive serial buffer - pointer 2 (Wr, SBUF->buff)	.comm	s1point, 2	;send serial buffer - pointer 1 (Wr, app->buff)	.comm	s2point, 2	;send serial buffer - pointer 2 (Rd, buff->SBUF); send buffer	.xcomm	sser, lngsser	;send serial buffer; receive buffer	.xcomm	rser, lngrser	;receive serial buffer.else	.comm	r1point, 1	;receive serial buffer - pointer 1	.comm	s1point, 1	;send serial buffer - pointer 1; send buffer	.icomm	sser, lngsser	;send serial buffer; receive buffer	.icomm	rser, lngrser	;receive serial buffer.endif	.text;;#########################################################;  Procedura cteni znaku za serioveho kanalu;#########################################################;getchar:jnb	rxint,retchar	;idioten sichr.if	RD2SER	push	dph	push	dpl	mov	dph, r1point	; MSB	mov	dpl, r1point+1	; LSB	ENABLE_XRAM	movx	a,@dptr		; precti znak	DISABLE_XRAM	mov	r1,a	inc	dptr	mov	a,dph		; make circle buffer from linear buffer	cjne	a,#HIGH(rser+lngrser),nocircle1	mov	a,dpl	cjne	a,#LOW(rser+lngrser),nocircle1	mov	dptr,#rsernocircle1:	clr	C	mov	a,dpl	subb	a, r2point+1	; LSB	mov	r0,a	mov	a,dph	subb	a, r2point	; MSB	jnb	Acc.7,noadj1	add	a,#HIGH(lngrser)noadj1:	clr	C	jnz	adj1		; unused buffer space > 0xFF	mov	a,r0	jz	adj1		; buffer empty	cjne	a,#20,.+3	; if unused buffer space < 20 then reset RTS/adj1:	jnb	rtscts,getchar1	mov	RTS,Cgetchar1:	jnb	xonxoff,getchar2	jc	getchar2	; XOFF	jnb	flagxoff,getchar2 ;O.K.	jb	srun,getchr2	; nezahajuj vysilani, vysila se	clr	flagxoff	mov	SBUF,#XON	; vysli XON	setb	srun	sjmp	getchar2getchr2:setb	xonrq		; XON requestgetchar2:	mov	a,dpl		; LSB	CLR	ES		; disable serial interrupt	cjne	a,r2point+1,notempty	mov	a,dph		; MSB	cjne	a,r2point,notempty	clr	rxint		; buffer empty clear "NoEmpty flag"notempty:	mov	r1point,dph	; MSB	mov	r1point+1,dpl	; LSB	SETB	ES		; enable serial interrupt	mov	a,r1	pop	dpl	pop	dph.else	mov	r0,#rser	MOV	A,@r0		;precti znak	mov	r1,a	mov	r0,#LOW(rser+lngrser)	CLR	ES		;disable serial interruptfllp:	dec	r0	xch	a,@r0	cjne	r0,#rser,fllp	dec	r1point	mov	a,r1point	cjne	a,#(rser+MAXCHAR),.+3	cpl	C		;if v bufferu je > MAXCHAR znaku then reset RTS/	jnb	rtscts,getchar1	mov	RTS,Cgetchar1:	jnb	xonxoff,getchar2	jc	getchar2		;XOFF	jnb	flagxoff,getchar2	;O.K.	jb	srun,getchr2		;nezahajuj vysilani, vysila se	clr	flagxoff	mov	SBUF,#XON		;vysli XON	setb	srun	sjmp	getchar2getchr2:setb	xonrq			;XON requestgetchar2:	cjne	a,#rser,notempty	clr	rxint			;buffer empty clear "NoEmpty flag"notempty:SETB	ES			;enable serial interrupt	mov	a,r1.endifretchar:ret;;#########################################################;;testbuffer:;	mov	C,rxint;	mov	cflag,C;	ret;;#########################################################;  Procedura zapis znaku do serioveho kanalu;#########################################################;	.using	0.if	RD2SERxputchar:	push	dph	push	dpl	mov	dph, s1point	; MSB	mov	dpl, s1point+1	; LSB	ENABLE_XRAM	movx	@dptr,a		; uloz znak do bufferu	DISABLE_XRAM	inc	dptr	mov	a,dph		; make circle buffer from linear buffer	cjne	a,#HIGH(sser+lngsser),nocircle2	mov	a,dpl	cjne	a,#LOW(sser+lngsser),nocircle2	mov	dptr,#ssernocircle2:	mov	a,dpl	CLR	ES		; disable serial interrupt	cjne	a,s2point+1,xptchr ; neni plno, vysli znak	mov	a,dph	cjne	a,s2point,xptchr   ; neni plno, vysli znak	SETB	ES		;enable serial interrupt	pop	dpl	pop	dph	clr	A		;0 char send	retpchar:	mov	a,R7putchar:	push	dph	push	dpl	mov	dph, s1point	; MSB	mov	dpl, s1point+1	; LSB	ENABLE_XRAM	movx	@dptr,a		; uloz znak do bufferu	DISABLE_XRAM	inc	dptr	mov	a,dph		; make circle buffer from linear buffer	cjne	a,#HIGH(sser+lngsser),nocircle3	mov	a,dpl	cjne	a,#LOW(sser+lngsser),nocircle3	mov	dptr,#ssernocircle3:	mov	a,dpl	CLR	ES		;disable serial interrupt	cjne	a,s2point+1,xptchr ; neni plno, vysli znak	mov	a,dph	cjne	a,s2point,xptchr   ; neni plno, vysli znak	SETB	ES		;enable serial interrupt	sjmp	nocircle3	; je plno cekej na uvolnenixptchr:	mov	s1point, dph	; MSB	mov	s1point+1, dpl	; LSB	SETB	ES		;enable serial interrupt	pop	dpl	pop	dph.elsexputchar:	push	Acc	MOV	a,s1point	xrl	a,#sser+lngsser	jnz	xptchr		;neni plno, vysli znak	djnz	acc,.	MOV	a,s1point	;1th retry	xrl	a,#sser+lngsser	jnz	xptchr		;neni plno, vysli znak	djnz	acc,.	MOV	a,s1point	;2nd retry	xrl	a,#sser+lngsser	jnz	xptchr		;neni plno, vysli znak.ifdef RETRY4 	djnz	acc,.	djnz	acc,.	MOV	a,s1point	;3nd retry	xrl	a,#sser+lngsser	jnz	xptchr		;neni plno, vysli znak	djnz	acc,.	djnz	acc,.	MOV	a,s1point	;4nd retry	xrl	a,#sser+lngsser	jnz	xptchr		;neni plno, vysli znak.endif	pop	Acc	clr	A		;0 char send	retpchar:	mov	a,R7putchar:	push	Accptchr:	MOV	a,s1point	xrl	a,#sser+lngsser	jz	ptchr		;je plno cekej na uvolnenixptchr:	pop	Acc	push	ar0	CLR	ES		;disable serial interrupt	mov	r0,s1point	MOV	@r0,A		;uloz znak do bufferu	inc	s1point	SETB	ES		;enable serial interrupt	pop	ar0.endif	jnb	rtscts, ptchr1	jb	CTS,ptchrr	;nezahajuj pripadne vysilaniptchr1:	jnb	xonxoff,ptchr2	jb	flagtxoff, ptchrr ;nezahajuj pripadne vysilaniptchr2:	jb	srun,ptchrr	setb	srun	setb	TIptchrr:	mov	a,#1		;1 char send	ret;;#########################################################;  Procedura zahajeni vysilani znaku do serioveho kanalu;            a vypoctu delky vysilaci fronty;#########################################################;sstat:.ifdef LEDSERIAL	mov	C,srun	cpl	C	mov	LED0,C.endif	CLR	ES		;disable serial interrupt	jb	xonrq,sstat2	jb	xoffrq,sstat2.if	RD2SER	mov	a,s1point+1	; otestuj pocet znaku v bufferu	xrl	a,s2point+1	; LSB	jnz	sstat0	mov	a,s1point	; MSB	xrl	a,s2point	jz	sstatexit 	; neni co vysilatsstat0:.else	MOV	a,s1point	;spocitej pocet znaku v bufferu	xrl	A,#sser	jz	sstatexit 	;neni co vysilat.endif	jnb	rtscts,sstat1	jb	CTS,sstatexit	;nezahajuj vysilani, obsazenosstat1:	jnb	xonxoff,sstat2	jb	flagtxoff,sstatexit	;nezahajuj vysilani, obsazenosstat2:	jb	srun,sstatexit	;nezahajuj vysilani, vysila se	setb	srun	setb	TIsstatexit:	SETB	ES		;enable serial interrupt	ret;;#########################################################;  Procedura Preruseni od prijateho znaku;#########################################################;	.using	0intRITI:JBC	RI,INT_READ	;je preruseni od prijimace	JBC	TI,INT_WRITE	;je preruseni od vysilace	RETIINT_WRITE:	PUSH	PSW	PUSH	ACC.if	RD2SER	push	dph	push	dpl	push	AUXR	push	EECON.else	PUSH	AR0.endif	setb	txint		;nastav priznak preruseni od vyslaneho znaku	jnb	xoffrq, int_w1	clr	xoffrq	setb	flagxoff	MOV	SBUF,#XOFF	;vysli XOFF	sjmp	INT_WRITE_ENDint_w1:	jnb	xonrq, int_w2	clr	xonrq	clr	flagxoff	MOV	SBUF,#XON	;vysli XON	sjmp	INT_WRITE_ENDint_w2:	clr	srun.if	RD2SER	mov	a,s2point+1	; otestuj pocet znaku v bufferu	mov	dpl, a	xrl	a,s1point+1	; LSB	jnz	int_w0	mov	a,s2point	; MSB	xrl	a,s1point	jz	INT_WRITE_END	; neni co vysilatint_w0:.else	mov	a,s1point	; send serial buffer - pointer 1	xrl	a,#sser	jz	INT_WRITE_END	; neni co vysilat.endif	jnb	rtscts, int_w3	jb	CTS,INT_WRITE_END ;nezahajuj pripadne vysilaniint_w3:	jnb	xonxoff,int_w4	jb	flagtxoff,INT_WRITE_END ;nezahajuj pripadne vysilaniint_w4:.if	RD2SER	mov	dph, s2point	; MSB	;mov	dpl, s2point+1	; LSB	DISABLE_EE	ENABLE_XRAM	movx	a,@dptr		; vyjmi znak z bufferu	;.._EE, .._XRAM	disabled/enabled on exit	mov	SBUF,a		;vysli znak	setb	srun	inc	dptr	mov	a,dph		; make circle buffer from linear buffer	cjne	a,#HIGH(sser+lngsser),nocircle4	mov	a,dpl	cjne	a,#LOW(sser+lngsser),nocircle4	mov	dptr,#ssernocircle4:	mov	s2point, dph	; MSB	mov	s2point+1, dpl	; LSB.else	mov	r0,#sser	MOV	A,@r0		;vyjmi data z bufferu	MOV	SBUF,A		;vysli znak	setb	srun	mov	r0,#LOW(sser+lngsser)flls:	dec	r0	xch	a,@r0	cjne	r0,#sser,flls	dec	s1point		;dec send serial buffer pointer.endifINT_WRITE_END:.if	RD2SER	pop	EECON	pop	AUXR	pop	dpl	pop	dph.else	POP	AR0.endif	POP	ACC	POP	PSW	RETI;INT_READ:	.using	0	PUSH	PSW	PUSH	ACC.if	RD2SER	push	dph	push	dpl	push	AUXR	push	EECON.else	PUSH	AR0.endif	setb	rxint		;nastav priznak preruseni od prijateho znaku	MOV	A,SBUF		;precti znak	jnb	xonxoff,int_r0	cjne	A,#XON,noXON	clr	flagtxoff	sjmp	int_r2noXON:	cjne	A,#XOFF,int_r0	setb	flagtxoff	sjmp	int_r2.if	RD2SERint_r0:	mov	dph, r2point	; MSB	mov	dpl, r2point+1	; LSB	DISABLE_EE	ENABLE_XRAM	movx	@dptr,a		; save received char to buffer	;.._EE, .._XRAM	disabled/enabled on exit	inc	dptr		; inc temp pointer to buffer	mov	a,dph		; make circle buffer from linear buffer	cjne	a,#HIGH(rser+lngsser),nocircle5	mov	a,dpl	cjne	a,#LOW(rser+lngsser),nocircle5	mov	dptr,#rsernocircle5:	mov	a,dpl	cjne	a,r1point+1,xgtchr ; not full, update pointer	mov	a,dph	cjne	a,r1point,xgtchr   ; not full, update pointer	sjmp	int_r9xgtchr:	mov	r2point, dph	; MSB	mov	r2point+1, dpl	; LSBint_r9:	clr	C	mov	a, r1point+1	subb	a, dpl		; LSB	mov	dpl,a	mov	a, r1point	subb	a, dph		; MSB	jnb	Acc.7,noadj2	add	a,#HIGH(lngsser)noadj2:	clr	C	jnz	adj2		; unused buffer space > 0xFF	mov	a,dpl	cjne	a,#20,.+3	; if unused buffer space < 20 then reset RTS/adj2:.elseint_r0:	mov	r0,r1point	; receive serial buffer	cjne	r0,#LOW(rser+lngrser),xgtchr	sjmp	int_r9xgtchr:	mov	@r0,a		;uloz data do bufferu	inc	r1pointint_r9:	mov	a,r1point	cjne	a,#(rser+MAXCHAR),.+3	cpl	C		;if v bufferu je > MAXCHAR znaku then reset RTS/.endif	jnb	rtscts,int_r1	mov	RTS,Cint_r1: jnb	xonxoff,int_r2	jnc	int_r2		;XON request	jb	flagxoff,int_r2	;O.K.	jb	srun,intr2	;nezahajuj vysilani, vysila se	setb	flagxoff	mov	SBUF,#XOFF	;vysli XOFF	setb	srun	sjmp	int_r2intr2:	setb	xoffrq		;XOFF requestint_r2:.if	RD2SER	pop	EECON	pop	AUXR	pop	dpl	pop	dph.else	POP	AR0.endif	POP	ACC	POP	PSW	RETI;;#########################################################;  INIT;#########################################################;	.section reset_device, #allocinit_serial:	orl	PCON,#0x80	mov	SCON,#0x52.ifdef BDT2.else	orl     TMOD,#0b00100000 ;timer 1, autoreload 8 bit.endif	ENABLE_EE	mov	dptr,#flash_flow	movx	a,@dptr	mov	C,B2B(ACC,optrtscts)	mov	rtscts,C	mov	C,B2B(ACC,optxonxoff)	mov	xonxoff,C	mov	dptr,#flash_baud	movx	a,@dptr	DISABLE_EE.ifdef BDT2	anl	a,#0x07		; may be, safety mask	rl	a	mov	r1,a	mov	dptr,#baudtable	movc	a,@a+dptr	mov	RCAP2H, A	mov	a,r1	inc	a	movc	a,@a+dptr	mov	RCAP2L, A	mov	T2CON, #0x30.else	mov	R1,a		;1..7	clr	A	setb	Cbdlp:	rlc	A	djnz	R1,bdlp	mov	b,#LOW(CPUCLOCK/384)	mul	ab	cpl	a	inc	a	MOV	TH1,a	MOV	TL1,a	orl	TCON,#0xC0      ;start timer1.endif.if	RD2SER	mov	r1point,#HIGH(rser)	;receive serial buffer - MSB pointer 1	mov	r1point+1,#LOW(rser)	;receive serial buffer - LSB pointer 1	mov	r2point,#HIGH(rser)	;receive serial buffer - MSB pointer 2	mov	r2point+1,#LOW(rser)	;receive serial buffer - LSB pointer 2	mov	s1point,#HIGH(sser)	;send serial buffer - MSB pointer 1	mov	s1point+1,#LOW(sser)	;send serial buffer - LSB pointer 1	mov	s2point,#HIGH(sser)	;send serial buffer - MSB pointer 2	mov	s2point+1,#LOW(sser)	;send serial buffer - LSB pointer 2.else	mov	r1point,#rser	;receive serial buffer - pointer 1	mov	s1point,#sser	;send serial buffer - pointer 1.endif	jnb	rtscts, init_ser1	clr	RTS		;povol prijem	mov	SBUF,#0init_ser1:	jnb	xonxoff, init_ser2	clr	flagtxoff	clr	xoffrq	clr	xonrq	mov	SBUF,#XON	;direct send XON	setb	sruninit_ser2:.ifdef BDT2	setb	TR2	orl	IE,#0b00010000	; enable serial port interrupt.else	setb	TR1	orl	IE,#0b00010000	; enable serial port interrupt.endif;.ifdef BDT2	.text.global	baudtablebaudtable:	.word	0x10000 - ((CPUFRQ+(16*384))/(32*384))	; not used	.word	0x10000 - ((CPUFRQ+(16*384))/(32*384))	; 38400	.word	0x10000 - ((CPUFRQ+(16*192))/(32*192))	; 19200	.word	0x10000 - ((CPUFRQ+(16* 96))/(32* 96))	;  9600	.word	0x10000 - ((CPUFRQ+(16* 48))/(32* 48))	;  4800	.word	0x10000 - ((CPUFRQ+(16* 24))/(32* 24))	;  2400	.word	0x10000 - ((CPUFRQ+(16* 12))/(32* 12))	;  1200	.word	0x10000 - ((CPUFRQ+(16*  6))/(32*  6))	;   600.endif;	;; END

⌨️ 快捷键说明

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