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

📄 soft232.asm

📁 用C51和汇编混合实现4个软串口的程序
💻 ASM
字号:
$NOMOD51

        NAME	Soft232

        PUBLIC  bFinEmpty0			; FiFo 0空
        PUBLIC  bFinOver0       		; FiFo 0溢出
        PUBLIC  bFinEmpty1			; FiFo 1空
        PUBLIC  bFinOver1			; FiFo 1溢出
        PUBLIC  bFinEmpty2			; FiFo 2空
        PUBLIC  bFinOver2			; FiFo 2溢出
;        PUBLIC  bFinEmpty3			; FiFo 3空
;        PUBLIC  bFinOver3			; FiFo 3溢出

        PUBLIC  _GetFiFo                        ; unsigned char GetFiFo( unsigned char FiFoNum );
        PUBLIC  _SetSoftBaud                    ; void SetSoftBaud( unsigned char Channel, unsigned char Baud );
        PUBLIC  InitSoft232                    ; void InitSoft232( void );

        ProgSeg	SEGMENT	CODE
        DatSeg  SEGMENT DATA
        BitSeg  SEGMENT BIT

EA		BIT	0A8H.7
P1		EQU	090H
PSW             EQU     0D0H
ACC             EQU     0E0H
;***********************************************
        DSEG    AT      20H
MultDat:        DS      1			; 多路采样
	bRxBit0		EQU   (MultDat-20H)*8+0 ; 当前采样位
	bRxBit1		EQU   (MultDat-20H)*8+1
	bRxBit2		EQU   (MultDat-20H)*8+2
	bRxBit3		EQU   (MultDat-20H)*8+3
	bStartBit0	EQU   (MultDat-20H)*8+4 ; 起始位有效
	bStartBit1	EQU   (MultDat-20H)*8+5
	bStartBit2	EQU   (MultDat-20H)*8+6
	bStartBit3	EQU   (MultDat-20H)*8+7
                        
        RSEG    DatSeg
RxBaudRate0:    DS      1			; 接收波特率分频系数 = (9600 / 波特率) * 3
RxBaudRate1:    DS      1			; 接收波特率分频系数 = (9600 / 波特率) * 3
RxBaudRate2:    DS      1			; 接收波特率分频系数 = (9600 / 波特率) * 3
;RxBaudRate3:    DS      1			; 接收波特率分频系数 = (9600 / 波特率) * 3
	
RxBaudCount0:   DS      1			; 接收波特率分频计数器
RxBaudCount1:   DS      1			; 接收波特率分频计数器
RxBaudCount2:   DS      1			; 接收波特率分频计数器
;RxBaudCount3:   DS      1			; 接收波特率分频计数器
	
RxBitCount0:    DS      1			; 接收位计数器 = 数据位数 + 1
RxBitCount1:    DS      1			; 接收位计数器 = 数据位数 + 1
RxBitCount2:    DS      1			; 接收位计数器 = 数据位数 + 1
;RxBitCount3:    DS      1			; 接收位计数器 = 数据位数 + 1
	
RxShift0:       DS      1			; 接收到的数据
RxShift1:       DS      1			; 接收到的数据
RxShift2:       DS      1			; 接收到的数据
;RxShift3:       DS      1			; 接收到的数据

FinOpt0:	DS      1			; FIFO指针长度字节
Fin0:           DS	8			; FIFO缓冲区
FinOpt1:	DS      1			; FIFO指针长度字节
Fin1:           DS	8			; FIFO缓冲区
FinOpt2:	DS      1			; FIFO指针长度字节
Fin2:           DS	8			; FIFO缓冲区
;FinOpt3:	 DS      1			; FIFO指针长度字节
;Fin3:           DS	8			; FIFO缓冲区


        RSEG    BitSeg  
bRxOK0:		DBIT    1			; 刚收到一字节, 但未存入 FIFO
bRxOK1:		DBIT    1			; 刚收到一字节, 但未存入 FIFO
bRxOK2:		DBIT    1			; 刚收到一字节, 但未存入 FIFO
;bRxOK3:         DBIT    1			; 刚收到一字节, 但未存入 FIFO

bFinEmpty0:	DBIT    1			; FiFo 0空
bFinOver0:	DBIT	1			; FiFo 0溢出
bFinEmpty1:	DBIT    1			; FiFo 1空
bFinOver1:	DBIT	1			; FiFo 1溢出
bFinEmpty2:	DBIT    1			; FiFo 2空
bFinOver2:	DBIT	1			; FiFo 2溢出
;bFinEmpty3:	DBIT    1			; FiFo 3空
;bFinOver3:	DBIT	1			; FiFo 3溢出

        CSEG	AT	000BH
	        LJMP	ISR_T0

        RSEG    ProgSeg
        USING   0
;----------------------------------------------- 存输入优先型FIFO, 最大19个指令周期
; 入口:
; X = 缓冲区号
; Dat = 将要存入的RAM单元
; rX = 局部变量, 必须是 R0 or R1
mPutFin	MACRO	X, Dat, rX			; rX = R0 or R1
	LOCAL	mPutFin_2, mPutFin_9

		MOV	A, FinOpt&X
		JNB	ACC.3, mPutFin_2

		SETB	bFinOver&X		; Fin 溢出错误
		SJMP	mPutFin_9
mPutFin_2:
		ADD	A, #10H			; Eptr ++
		INC	A			; Len ++
		MOV	FinOpt&X, A
		SWAP	A
		ANL	A, #00000111B
		ADD	A, #Fin&X
		MOV	rX, A
		MOV	@rX, Dat
		CLR	bFinEmpty&X
mPutFin_9:
	ENDM
;----------------------------------------------- 取输入优先型FIFO
; 入口:
; X = 缓冲区号
; rX = 局部变量, 必须是 R0 or R1
; rY = 局部变量
; 出口:
; A
mGetFin	MACRO	X, rX, rY
	LOCAL	mGetFin_2, mGetFin_9

		JB	bFinEmpty&X, mGetFin_9
	CLR	EA
		DEC	FinOpt&X
		MOV	A, FinOpt&X
	SETB	EA
		MOV	rY, A
		ANL	A, #07H		
		JNZ	mGetFin_2

		SETB	bFinEmpty&X
mGetFin_2:
		CPL	A
		INC	A
		XCH	A, rY   		; rY = (长度-1)的补码
		SWAP	A
		ADD	A, rY
		ANL	A, #00000111B
		ADD	A, #Fin&X
		MOV	rX, A
		MOV	A, @rX
;		CLR	bFinOver&X
mGetFin_9:
	ENDM
;----------------------------------------------- 多路串行位接收
; 入口:
; X = 串口通道号
; Y = 局部变量, 必须是 R0 or R1
; 2-7-17-26个指令周期
mByteIn	MACRO	X, Y
	LOCAL	mByteIn_1, mByteIn_2, mByteIn_7, mByteIn_9

		JNB	bStartBit&X, mByteIn_7
								; if 起始位有效
		DEC	RxBaudCount&X
		MOV	A, RxBaudCount&X
		JNZ	mByteIn_7
mByteIn_1:					  		; if 波特率分频到
		MOV	A, RxBitCount&X
		JNZ	mByteIn_2
						    		; if 停止位
		MOV	A, RxBaudRate&X
		CLR	C
		RRC	A
		ADD	A, RxBaudRate&X
		INC	A
		MOV	RxBaudCount&X, A	      	; 初始波特率分频x1.5, 跳过起始位
		MOV	RxBitCount&X, #08H	        ; 暂时默认 8 位数据,无校验
		CLR	bStartBit&X
		SETB	bRxOK&X
		SJMP	mByteIn_9
mByteIn_2:					    		; else 正常位接收
		DEC	RxBitCount&X
		MOV	A, RxShift&X
		MOV	C, bRxBit&X
		RRC	A
		MOV	RxShift&X, A
		MOV	A, RxBaudRate&X
		MOV	RxBaudCount&X, A	      	; 波特率分频
		SJMP	mByteIn_9
mByteIn_7:
		JNB	bRxOK&X, mByteIn_9
		CLR	bRxOK&X
		mPutFin	X, RxShift&X, Y
mByteIn_9:
	ENDM
;*********************************************** 
;----------------------------------------------- T0中断程序, 9600*3 Hz的中断频率, 公共部分28个指令周期
ISR_T0:
		PUSH	PSW
                PUSH    ACC
                PUSH    AR0

		MOV	A, P1			; P1口, P1.0 - P1.3 是接收脚
		MOV	R0, #MultDat	       	; 以下这段用于判断是否有起始位,是4路同时处理的
		XCHD	A, @R0
		XRL	A, MultDat
		CPL	A
		ORL	A, MultDat
		CPL	A
		ANL	A, #0FH
		SWAP	A
		ORL	MultDat, A

		mByteIn	0, R0                   ; 驱动通道0
		mByteIn	1, R0                   ; 驱动通道1
		mByteIn	2, R0                   ; 驱动通道2
;		mByteIn	3, R0                   ; 驱动通道3

                POP     AR0
		POP	ACC
		POP	PSW
		RETI
;----------------------------------------------- 取FIFO中的数据
; unsigned char FetFiFo( unsigned char FiFoNum )
; 入口:
; 缓冲区编号
; 出口:
; 字节数据
_GetFiFo:
                CJNE    R7, #00H, _GetFiFo_1

                mGetFin	0, R0, R7
                LJMP    _GetFiFo_9
_GetFiFo_1:
                CJNE    R7, #01H, _GetFiFo_2

                mGetFin	1, R0, R7
                LJMP    _GetFiFo_9
_GetFiFo_2:
                CJNE    R7, #02H, _GetFiFo_3

                mGetFin	2, R0, R7
;                LJMP    _GetFiFo_9
_GetFiFo_3:
;                CJNE    R7, #03H, _GetFiFo_9
;
;                mGetFin	3, R0, R7
_GetFiFo_9:
                MOV     R7, A
                RET
;----------------------------------------------- 设置软串口波特率
; void SetSoftBaud( unsigned char Channel, unsigned char Baud )
; 入口参数:
; 通道号, 波特率代号
_SetSoftBaud:
                CJNE    R5, #07H, $+3
                JNC     _SetSoftBaud_9
                MOV     A, R5
                JZ      _SetSoftBaud_9          ; 波特率代号在1-6之间
                MOV     A, #07H                 ; 本来应该是06H,但此处C必然为1,所以置07H
                SUBB    A, R5
                MOV     R5, #03H
                JZ      _SetSoftBaud_B

                XCH     A, R5
_SetSoftBaud_A:
                RL      A
                DJNZ    R5, _SetSoftBaud_A
                XCH     A, R5                   ; 得到波特率的计数值
_SetSoftBaud_B:
                CJNE    R7, #00H, _SetSoftBaud_1

		MOV	RxBaudRate0, R5
                MOV     A, R5
                RR      A
                ADD     A, R5
                INC     A
		MOV	RxBaudCount0, A
                SJMP    _SetSoftBaud_9
_SetSoftBaud_1:                
                CJNE    R7, #01H, _SetSoftBaud_2

		MOV	RxBaudRate1, R5
                MOV     A, R5
                RR      A
                ADD     A, R5
                INC     A
		MOV	RxBaudCount1, A
                SJMP    _SetSoftBaud_9
_SetSoftBaud_2:                
                CJNE    R7, #02H, _SetSoftBaud_3

		MOV	RxBaudRate2, R5
                MOV     A, R5
                RR      A
                ADD     A, R5
                INC     A
		MOV	RxBaudCount2, A
;                SJMP    _SetSoftBaud_9
_SetSoftBaud_3:                
;                CJNE    R7, #03H, _SetSoftBaud_9
;
;                MOV     RxBaudRate3, R5
;                MOV     A, R5
;                RR      A
;                ADD     A, R5
;                INC     A
;       	 MOV     RxBaudCount3, A
_SetSoftBaud_9:                
                RET
;----------------------------------------------- 软串口初始化
InitSoft232:					
		MOV	FinOpt0, #00H
		SETB	bFinEmpty0
		CLR	bFinOver0

		MOV	FinOpt1, #00H
		SETB	bFinEmpty1
		CLR	bFinOver1

		MOV	FinOpt2, #00H
		SETB	bFinEmpty2
		CLR	bFinOver2

;		MOV	FinOpt3, #00H
;		SETB	bFinEmpty3
;		CLR	bFinOver3

		MOV	MultDat, #0FH

		CLR	bRxOK0
		CLR	bRxOK1
		CLR	bRxOK2
;		CLR	bRxOK3

		MOV	RxBitCount0, #08H
		MOV	RxBitCount1, #08H
		MOV	RxBitCount2, #08H
;		MOV	RxBitCount3, #08H
		RET
;***********************************************
END

⌨️ 快捷键说明

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