📄 testptr2000.asm
字号:
;////////////////////////////////////////////////////////////////////////////
;初始化模块
;////////////////////////////////////////////////////////////////////////////
Init:
;变量地址定义
DIGSET EQU P2 ;数字设定端口
DIGSHOW EQU P1 ;数字显示端口
RUNLAMP BIT P0.0 ;运行灯端口
CS BIT P3.2 ;频道1/2选择端口
PWR BIT P3.3 ;电源待机/工作控制端口
TXEN BIT P3.4 ;接收/发射转换端口
READY EQU 30H ;全文发射开始标志字节
HEAD1 EQU 31H ;字节帧起始标志第1字节
HEAD2 EQU 32H ;字节帧起始标志第2字节
DATA1 EQU 33H ;字节帧数据拷贝第1字节
DATA2 EQU 34H ;字节帧数据拷贝第2字节
DATA3 EQU 35H ;字节帧数据拷贝第3字节
SUM EQU 36H ;字节帧校验和字节
OVER EQU 37H ;全文发射结束标志字节
nToTal EQU 40H ;全文总字节数
nTxed EQU 41H ;发射字节数
nRxed EQU 42H ;接收字节数
temp EQU 49H ;临时缓存
bReady BIT 00H ;发射开始帧标志
bOver BIT 01H ;发射结束帧标志
;程序主初始化
ORG 100H ;程序入口地址跳过中断向量区
MOV SP, #5FH ;程序断点堆栈地址跳过RAM通用和专用寄存器区
;串口初始化
MOV IE, #10011010B ;开串口、定时器中断
MOV TMOD, #20H ;计数/定时模式2-8位自动重载计数
MOV TH1, #0FDH ;设置TH1,波特率9600BPS
MOV SCON, #01010000B ;串口模式1,8位数据位,串行口接收致能
SETB TR1 ;启动计数器1
CLR TI ;清发送标志
CLR RI ;清接收标志
;发射/接收初始化
MOV DIGSET, #0FFH ;写P2口,置读方式
CLR CS ;选频道1
SETB PWR ;工作状态
MOV READY, #0AAH ;定义全文发射开始标志
MOV HEAD1, #0FFH ;定义字节帧起始标志1
MOV HEAD2, #00H ;定义字节帧起始标志2
MOV OVER, #55H ;定义全文发射结束标志
MOV nToTal, #0FFH ;定义全文总字节数
IfTx:
CLR RUNLAMP ;点运行灯
MOV DIGSHOW,#0FFH ;发射/接收显示灯初始全灭
MOV nTxed, #00H ;发射字节数清0
MOV nRxed, #00H ;接收字节数清0
CLR bReady ;清发射开始标志
CLR bOver ;清发射结束标志
MOV R0, #00H ;当前接收字节清0
MOV R1, #00H ;上次接收字节清0
MOV A, DIGSET ;读数字设定口
CJNE A,#0FFH,ToTx ;区分发射/接收
LJMP PreRx
ToTx:
LJMP PreTx
;////////////////////////////////////////////////////////////////////////////
;接收模块
;////////////////////////////////////////////////////////////////////////////
;准备接收
PreRx:
CLR TXEN ;进入接收状态
CALL Sub_Delay5ms ;延时5毫秒,等待状态转换完成
;接收字节帧起始标志
RxHead:
JNB RI, $ ;等待收完
MOV A, SBUF ;接收字节帧起始标志1
CLR RI ;清接收标志
CJNE A,HEAD1,RxHead
JNB RI, $ ;等待收完
MOV A, SBUF ;接收字节帧起始标志2
CLR RI ;清接收标志
CJNE A,HEAD2,RxHead
;接收字节帧数据拷贝
RxData:
JNB RI, $ ;等待收完
MOV DATA1, SBUF ;接收字节帧数据拷贝1
CLR RI ;清接收标志
JNB RI, $ ;等待收完
MOV DATA2, SBUF ;接收字节帧数据拷贝2
CLR RI ;清接收标志
JNB RI, $ ;等待收完
MOV DATA3, SBUF ;接收字节帧数据拷贝3
CLR RI ;清接收标志
;接收字节帧校验和
RxSum:
JNB RI, $ ;等待收完
MOV SUM, SBUF ;接收字节帧校验和
CLR RI ;清接收标志
;验算校验和
MatchSum:
MOV A, DATA1 ;算收到的数据拷贝校验和
ADD A, DATA2
ADD A, DATA3
CJNE A,SUM, If1Equ2 ;若算得的校验和与收到的不同,则比较三份数据拷贝,三局两胜
MOV A, R0 ;保存当前数据为前次数据
MOV R1, A
MOV R0, DATA1 ;由于校验和正确,当前数据可为三份数据拷贝的任意一个
LJMP IfReady ;判断是否开始全文接收
;数据拷贝三局两胜
If1Equ2:
MOV A,DATA1 ;比较数据拷贝1、2,若不同则进一步比较数据拷贝2、3
CJNE A,DATA2,If2Equ3
MOV A, R0 ;保存当前数据为前次数据
MOV R1, A
MOV R0, DATA1 ;由于数据拷贝1、2相同,当前数据可为两者的任意一个
LJMP IfReady ;判断是否开始全文接收
If2Equ3:
MOV A,DATA2 ;比较数据拷贝2、3,若不同则进一步比较数据拷贝3、1
CJNE A,DATA3,If3Equ1
MOV A, R0 ;保存当前数据为前次数据
MOV R1, A
MOV R0, DATA2 ;由于数据拷贝2、3相同,当前数据可为两者的任意一个
LJMP IfReady ;判断是否开始全文接收
If3Equ1:
MOV A,DATA3 ;比较数据拷贝3、1,若再不同则丢弃并继续接收下一帧
CJNE A,DATA1,RxHead
MOV A, R0 ;保存当前数据为前次数据
MOV R1, A
MOV R0, DATA3 ;由于数据拷贝3、1相同,当前数据可为两者的任意一个
;判断是否开始全文接收
IfReady:
MOV A, R0
CJNE A,READY,IfOver ;不是开始帧,则进一步判断是否结束帧
MOV nRxed, #00H ;是开始帧,接收字节数清0
LJMP RxHead ;继续接收下一帧
;判断是否结束全文接收
IfOver:
MOV A, R0
CJNE A,OVER,ShowRxData ;也不是结束帧,则显示正确数据
CALL Sub_Delay10s ;是结束帧,保持数据显示30秒
SETB RUNLAMP ;灭运行灯
MOV A, nRxed ;显示接收字节数
CPL A ;
MOV DIGSHOW,A ;
CALL Sub_Delay10s ;保持结束状态30秒
LJMP IfTx ;重新开始
;显示正确的接收数据
ShowRxData:
INC nRxed ;是数据帧,接收字节计数
MOV A, R0
MOV temp, R1
CJNE A,temp, ShowRenew ;若与前次数据不同,则更新数据显示
LJMP RxHead ;否则继续接收
ShowRenew:
MOV A, R0 ;更新数据显示
CPL A ;
MOV DIGSHOW,A ;
LJMP RxHead ;继续接收
;////////////////////////////////////////////////////////////////////////////
;发射模块
;////////////////////////////////////////////////////////////////////////////
;准备发射
PreTx:
SETB TXEN ;进入发射状态
CALL Sub_Delay5ms ;延时5毫秒,等待状态转换完成
MOV DIGSHOW,A ;发射信号显示
CPL A ;电平求反
MOV R0, A ;得到发射数据
Add A, R0 ;得到校验和
Add A, R0
MOV SUM, A
;发射引导信号
MOV R1, #10
TxLead:
MOV SBUF, #0AAH ;发射引导随机数
JNB TI, $ ;等待发完
CLR TI ;清发射标志
DJNZ R1, TxLead
SETB bReady
;发射字节帧起始标志
TxHead:
MOV SBUF, HEAD1 ;发射字节帧起始标志1
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, HEAD2 ;发射字节帧起始标志2
JNB TI, $ ;等待发完
CLR TI ;清发射标志
;发射全文开始标志
TxReady:
JNB bReady, TxOver ;若已发射字节数>0,则进一步判断是否已发完全文
MOV SBUF, READY ;发射全文开始标志拷贝1
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, READY ;发射全文开始标志拷贝2
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, READY ;发射全文开始标志拷贝3
JNB TI, $ ;等待发完
CLR TI ;清发射标志
CLR bReady ;清全文开始帧标志
LJMP TxSum ;发射校验和
;发射全文结束标志
TxOver:
MOV A, nTxed ;取已发射字节数
CJNE A,nTotal,TxData ;若已发射字节数<全文总字节数,则发射数据
MOV SBUF, OVER ;发射全文结束标志拷贝1
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, OVER ;发射全文结束标志拷贝2
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, OVER ;发射全文结束标志拷贝3
JNB TI, $ ;等待发完
CLR TI ;清发射标志
SETB bOver ;设置全文发送完毕标志
LJMP TxSum ;发射校验和
;发射数据
TxData:
MOV SBUF, R0 ;发射数据拷贝1
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, R0 ;发射数据拷贝2
JNB TI, $ ;等待发完
CLR TI ;清发射标志
MOV SBUF, R0 ;发射数据拷贝3
JNB TI, $ ;等待发完
CLR TI ;清发射标志
INC nTxed ;已发射字节计数
;发射校验和
TxSum:
MOV SBUF, SUM ;发射校验和
JNB TI, $ ;等待发完
CLR TI ;清发射标志
CALL Sub_Delay556us ;等待收端收完一帧
;显示发射结束
ShowOver:
JNB bOver, TxHead ;未发射完毕则继续发射
CALL Sub_Delay10s ;保持发射数据显示30秒
SETB RUNLAMP ;灭运行灯
MOV A, nTxed ;显示已发射字节数
CPL A
MOV DIGSHOW,A
CALL Sub_Delay10s ;保持结束状态显示30秒
LJMP IfTx ;重新开始
;////////////////////////////////////////////////////////////////////////////
;延时子程序
;////////////////////////////////////////////////////////////////////////////
;延时10秒子程序
Sub_Delay10s:
MOV R4, #10
Delay1s:
CALL Sub_Delay1s
DJNZ R4, Delay1s
RET
;延时1秒子程序
Sub_Delay1s:
MOV R5, #200
Delay5ms:
CALL Sub_Delay5ms
DJNZ R5, Delay5ms
RET
;延时5毫秒子程序
Sub_Delay5ms:
MOV R6, #9
Delay556us:
CALL Sub_Delay556us
DJNZ R6, Delay556us
RET
;延时556微秒子程序
Sub_Delay556us:
MOV R7, #0FFH
DJNZ R7, $
RET
;////////////////////////////////////////////////////////////////////////////
;定时器中断服务程序
;////////////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////
END ;程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -