模拟串口:串口模拟程序(加了3次校验)

给模拟串口程序加上了3次校验,虽然采样的时间不是取平均值,但是还是应该比较准确了。然后把定时重新进行了一下精确的计算,把指令的误差都加进去了。为了让程序的可扩展性更高些。用的是发送和接收加相应的延时来同步,免去了换波特率的时候计算的麻烦。新的修改的程序如下:

[ft=,4,] 发送程序
;TXD P1.2
;指示灯 P3.7
;----------------------------------------------------
ORG 000H
RESET: AJMP MAIN
ORG 00BH
AJMP IT0P
ORG 050H
;----------------------------------------------------
;主程序
MAIN: MOV SP,#60H
ACALL PT0M2 ;调初始化子程序
LOOP1: CLR P3.7 ;发送指示灯亮
MOV R0,#0AH ;发送几个字节数据
MOV DPTR,#TAB
LOOP2: CLR A
MOVC A,@A+DPTR
ACALL TANSFER ;调传送子程序
INC DPTR
DJNZ R0,LOOP2 ;数据是否发送完
SETB P3.7 ;发送指示灯灭
ACALL DELAY2 ;调用延时子程序
AJMP LOOP1
;-----------------------------------------------------
;初始化子程序
PT0M2: MOV TMOD,#02H ;定时器0,方式2
MOV TL0,#0DH ;T0初值,计数250次,抛去了误差后的值
MOV TH0,#0DH
CLR TF0 ;初始化T0溢出中断标志位
SETB ET0 ;允许T0溢出中断
SETB EA ;允许中断
CLR F0 ;标志位清零
RET
;----------------------------------------------------
;中断子程序
IT0P: ACALL DELAY3 ;为了和接收程序同步,加相同的延时
DJNZ R6,GO
SETB F0
GO: RRC A
RETI
;----------------------------------------------------
;延时子程序
DELAY1: MOV R7,#60H ;200个机械周期的延迟
LL: DJNZ R7,LL
RET
DELAY2: MOV R2,#01H ;1s的延时子程序
LOOP3:MOV R3,#0FFH
LOOP4:MOV R4,#0FFH
LOOP5:NOP
NOP
NOP
NOP
NOP
DJNZ R4,LOOP5
DJNZ R3,LOOP4
DJNZ R2,LOOP3
RET
DELAY3: NOP
NOP
MOV P1.2,C ;发送数据
NOP
MOV R5,#08H
DJNZ R5,$
RET
;----------------------------------------------------
;发送子程序
TANSFER:MOV R6,#08H
RRC A
SETB P1.2
ACALL DELAY1
CLR P1.2 ;发送启始位
ACALL DELAY1
NOP
SETB TR0 ;发送8位数据
JNB F0,$
CLR F0
CLR TR0
ACALL DELAY1
SETB P1.2 ;发送结束位
ACALL DELAY1
RET
;---------------------------------------------------
;数据表
TAB: DB 0AAH,4CH,59H,01H,07H,01H,00H,00H,00H,01H
;---------------------------------------------------
END




[ft=,4,]接收程序
;RXD P1.3
;指示灯 P3.7
;---------------------------------------------------
ORG 000H
RESET: AJMP MAIN
ORG 00BH ;T0中断入口地址
AJMP IT0P
ORG 050H
;----------------------------------------------------
;主程序
MAIN: MOV SP,#60H
ACALL PT0M2 ;调初始化子程序
MOV R5,#0AH ;接收几个字节的数据
MOV R0,#30H
MOV DPTR,#TAB
LOOP1:CLR A ;调检验数据
MOVC A,@A+DPTR
MOV @R0,A
INC DPTR
INC R0
DJNZ R5,LOOP1
LOOP2:CLR A
MOV R0,#30H
MOV R1,#09H
LOOP3:ACALL RECEVE ;调接收子程序
XRL A,@R0 ;判断是否是前导码
JNZ LOOP3
INC R0
CLR P3.7 ;接收指示灯亮
LOOP4:CLR A
ACALL RECEVE ;开始接受数据
XRL A,@R0 ;判断数据是否正确
JNZ BJ ;当数据出现错返回重新接受
INC R0
DJNZ R1,LOOP4
BJ: SETB P3.7
AJMP LOOP2
;-----------------------------------------------------
;初始化子程序
PT0M2: MOV TMOD,#02H ;定时器0,方式2
MOV TL0,#0DH ;T0初值,计数250次,抛去了误差后的值
MOV TH0,#0DH
CLR TF0 ;初始化T0溢出中断标志位
SETB ET0 ;允许T0溢出中断
SETB EA ;允许中断
MOV PSW,#80H ;进位标志位初始化
RET
;----------------------------------------------------
;中断子程序
IT0P: ACALL CHECK ;调检验子程序
DJNZ R6,GO
SETB F0 ;建立T0中断标志位
GO: RRC A
RETI
;----------------------------------------------------
;接受子程序
RECEVE: MOV R6,#08H
WAIT1: MOV C,P1.3 ;接收启始位
JC WAIT1
NOP
MOV C,P1.3
JC WAIT1
NOP
MOV C,P1.3
JC WAIT1
ACALL DELAY1
NOP
; ACALL DELAY2 ;根据接收的波形的范围调整延时
SETB TR0 ;接收8位数据
JNB F0,$
CLR F0
CLR TR0
ACALL DELAY1
WAIT2: MOV C,P1.3 ;接收结束位
JNC WAIT2
NOP
MOV C,P1.3
JNC WAIT2
NOP
MOV C,P1.3
JNC WAIT2
RET
;----------------------------------------------------
;延时子程序
DELAY1: MOV R7,#60H ;200个机械周期的延迟
LL1: DJNZ R7,LL1
RET
DELAY2: MOV R4,#01H ;根据波形范围调整
LL2: DJNZ R4,LL2
RET
;----------------------------------------------------
;3次校验子程序
CHECK: PUSH ACC ;保留现场
CLR A
MOV C,P1.3 ;第一次采样
RLC A
MOV 20H,A
CLR A
MOV C,P1.3 ;第二次采样
RLC A
ADD A,20H ;累加和
MOV 21H,A
CLR A
MOV C,P1.3 ;第三次采样
RLC A
ADD A,21H ;累加和
MOV 22H,A
XRL A,#03H ;判断是否三次采样都是1
JZ CC1
MOV A,22H
XRL A,#02H ;判断是否两次采样都是1
JZ CC1
CLR C ;采样有两次或两次以上是零
AJMP CC2
CC1: SETB C
CC2: POP ACC
RET
;---------------------------------------------------
;数据表
TAB: DB 0AAH,4CH,59H,01H,07H,01H,00H,00H,00H,01H
;----------------------------
END
Tags:  usb模拟串口 模拟串口软件 串口模拟器 模拟串口

延伸阅读

最新评论

发表评论