📄 soft232.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 + -