📄 main.asm
字号:
ORG 0000H ;主程序入口
AJMP START
; ORG 0023H ;中断服务子程序入口
AJMP RECEIVE
ORG 0030H
START: MOV P2,#7FH ;LED灯全灭,P2.7=0使TXEN=0,模块处于接收状态
LCALL DELAY_10ms ;时间延迟
MOV R0,#50H ;R0(50H)中存放接收数据地址
;MOV
SETB TR1 ;启动定时器T1
SETB EA ;开全局中断
SETB ES ;开串行口中断
; MOV R0,#50H ;R0为接收数据存放地址(50H)
;MOV R2,#01H ;R1存放命令
;MOV R3,#03H ;R2存放地址及命令发送次数(3次)
;CLR P2.7 ;设置TXEN=0,使模块处于接收状态
; LCALL DELAY_10ms ;时间延迟
; SJMP $ ;等待串口中断
; LJMP MAIN
;***********************************************************************
;串口数据接收中断子程序
RECEIVE: MOV R4,#00H ;R4为校验和寄存器
CLR RI
MOV A,SBUF ;接收字符
CJNE A,#0FFH,RXD_ERR ;接收是否FFH?不是则跳转
ADD A,R4 ;形成累加校验和
MOV R4,A
JNB RI,$ ;接收字符
CLR RI
MOV A,SBUF
CJNE A,#00H,RXD_ERR ;接收是否00H,不是则跳转
ADD A,R4
MOV R4,A
MOV R6,#00H ;R6存放接收次数(6次)
RXSIX: JNB RI,$ ;接收数据
CLR RI
MOV A,SBUF
ADD A,R4 ;形成校验和
MOV R4,A
CLR RI
; MOV A,SBUF ;接收校验和
; SUBB A,R4 ;比较校验和是不是正确
; JNZ RXD_ERR ;校验和不正确则跳转
LCALL COMPARE ;调用比较子程序比较三对地址和命令数据
MOV A,P2 ;判断三对数据是否至少有两对相同
CJNE A,#00H,RXD_END ;不相等(P2=00H)则跳转
; MOV R2,50H ;R2存放地址
MOV R3,51H ;R3存放命令标志
SJMP RXD_END
RXD_ERR: MOV P2,#00H ;数据错,灯全亮
RXD_END: CLR EA ;关闭中断
RETI
;***********************************************************************
MAIN: ; CLR EA ;关闭中断
LCALL PROCESSOR ;调数据处理子程序
SETB EA
LJMP MAIN_END
;END
;************************************************************************
;数据处理子程序
PROCESSOR: MOV A,50H ;50H存放地址标志
SUBB A,#254 ;比较地址标志Ra>=254?
JC IDDATA ;否(小于)则跳转(CY=1有借位,则小于254)
MOV A,R3 ;R3(Ri)命令标志
CJNE A,#01H,PROCE_1 ;R3=01?不等则跳转
LCALL REGISTER ;调报到子程序
AJMP PROCE_END ;返回
PROCE_1: CJNE A,#02H,PROCE_2 ;R3=02?不等则跳转
LCALL FLOOR ;调发言子程序
AJMP PROCE_END ;返回
PROCE_2: CJNE A,#03H,PROCE_ERR ;R3=03?不等则跳转
LCALL VOTER ;调表决子程序
AJMP PROCE_END ;返回
IDDATA: SUBB A,R2 ;比较是否为本机地址(R2存放本机地址)
JNZ PROCE_ERR ;不是则跳转
MOV A,R3 ;R3(Ri)命令标志
CJNE A,#07H,IDDATA_1 ;R3=07?不等则转移
CLR P1.5 ;取消发言
SETB P2.1 ;
SETB P2.2
AJMP PROCE_END ;返回
IDDATA_1: CJNE A,#08,PROCE_ERR ;R3=08?不等则跳转
SETB P1.5 ;允许发言
CLR P2.1
CLR P2.2
AJMP PROCE_END ;返回
PROCE_ERR: ; MOV P2,#00H ;出错处理(LED灯全亮)
PROCE_END: RET
;**********************************************************************
;报到子程序
REGISTER: MOV A,50H ;50H存放地址命令标志
CJNE A,#255,REG_2 ;Ra=255?不等则跳转
CLR P2.3 ;报到状态灯亮,允许报到
SETB EA ;开中断
REG_1: MOV C,P2.3 ;p2.3是报到状态显示位
JC REG_3 ;(P2.3=1)报到取消则转移
MOV C,P1.0 ;扫描P1.0,P1.0是S1按键
LCALL DELAY_10ms ;延时10ms消抖
ORL C,P1.0 ;再读P1.0状态,看两次结果是否都为0
JC REG_1 ;(P1.0=1)S1键没有按下则转移重新扫描
CLR EA ;关中断
;******************************************************
;需要修改的地址Ra和命令Ri
MOV R2,#00H ;R2存放本机地址,需要修改
MOV R3,#01H ;R3存放命令(01代表报到).需要修改
;******************************************************
; LCALL SEND ;调发送子程序
CLR P2.4 ;已报到灯亮
AJMP REG_END ;返回
REG_2: CJNE A,#254,REG_ERR ;Ra=254?不等则跳转
SETB P2.3 ;取消报到状态
SETB P2.4
REG_3: CLR EA ;开中断
AJMP REG_END ;返回
REG_ERR: ; MOV P2,#00H ;出错,灯全亮
REG_END: RET
;***********************************************************************
;报到子程序
FLOOR: MOV A,50H ;50H存放地址命令标志
CJNE A,#255,FLOOR_2 ;Ra=255?不等则跳转
CLR P2.0 ;报到状态灯亮,允许报到
SETB EA ;开中断
FLOOR_1: MOV C,P2.0 ;p2.0是发言状态显示位
JC FLOOR_3 ;(P2.0=1)发言取消则转移
MOV C,P1.1 ;扫描P1.1,P1.1是S2按键
LCALL DELAY_10ms ;延时10ms消抖
ORL C,P1.1 ;再读P1.1状态,看两次结果是否都为0
JC FLOOR_1 ;(P1.1=1)S2键没有按下则转移重新扫描
CLR EA ;关中断
;******************************************************
;需要修改的地址Ra和命令Ri
MOV R2,#00H ;R2存放本机地址,需要修改
MOV R3,#02H ;R3存放命令(02代表发言申请).需要修改
;******************************************************
LCALL SEND ;调发送子程序
CLR P2.1 ;已报到灯亮
AJMP FLOOR_END ;返回
FLOOR_2: CJNE A,#254,FLOOR_ERR ;Ra=254?不等则跳转
SETB P2.0 ;取消报到状态
SETB P2.1
SETB P2.2
FLOOR_3: CLR EA ;关中断
AJMP FLOOR_END ;返回
FLOOR_ERR: ; MOV P2,#00H ;出错,灯全亮
FLOOR_END: RET
;***********************************************************************
;报到子程序
VOTER: MOV A,50H ;50H存放地址命令标志
CJNE A,#255,VOTER_4 ;Ra=255?不等则跳转
CLR P2.5 ;表决状态灯亮,允许表决
SETB EA ;开中断
VOTER_1: MOV C,P2.5 ;p2.5是表决状态显示位
JC VOTER_5 ;(P2.5=1)表决取消则转移
MOV C,P1.2 ;扫描P1.1,P1.1是S2按键
LCALL DELAY_10ms ;延时10ms消抖
ORL C,P1.2 ;再读P1.1状态,看两次结果是否都为0
JC VOTER_2 ;(P1.1=1)S2键没有按下则转移
CLR EA ;关中断
;******************************************************
;需要修改的地址Ra和命令Ri
MOV R2,#00H ;R2存放本机地址,需要修改
MOV R3,#04H ;R3存放命令(04代表同意).需要修改
;******************************************************
LCALL SEND ;调发送子程序
CLR P2.6 ;已报到灯亮
AJMP VOTER_END ;返回
VOTER_2: MOV C,P1.3 ;扫描P1.1,P1.1是S2按键
LCALL DELAY_10ms ;延时10ms消抖
ORL C,P1.3 ;再读P1.1状态,看两次结果是否都为0
JC VOTER_3 ;(P1.1=1)S2键没有按下则转移
CLR EA ;关中断
;******************************************************
;需要修改的地址Ra和命令Ri
MOV R2,#00H ;R2存放本机地址,需要修改
MOV R3,#05H ;R3存放命令(04代表反对).需要修改
;******************************************************
LCALL SEND ;调发送子程序
CLR P2.6 ;已表决灯亮
AJMP VOTER_END ;返回
VOTER_3: MOV C,P1.4 ;扫描P1.1,P1.1是S2按键
LCALL DELAY_10ms ;延时10ms消抖
ORL C,P1.4 ;再读P1.1状态,看两次结果是否都为0
JC VOTER_1 ;
CLR EA ;关中断
;******************************************************
;需要修改的地址Ra和命令Ri
MOV R2,#00H ;R2存放本机地址,需要修改
MOV R3,#06H ;R3存放命令(06代表弃权).需要修改
;******************************************************
LCALL SEND ;调发送子程序
CLR P2.6 ;已表决灯亮
AJMP VOTER_END ;返回
VOTER_4: CJNE A,#254,VOTER_ERR ;Ra=254?不等则跳转
SETB P2.5 ;取消表决状态
SETB P2.6
VOTER_5: CLR EA ;开中断
AJMP VOTER_END ;返回
VOTER_ERR: ; MOV P2,#00H ;出错,灯全亮
VOTER_END: RET
;***********************************************************************
;发送子程序
;R2中存放本机地址,R1中存放命令
SEND: SETB P2.7 ;设置TXEN=1,使模块处于发送状态
MOV R4,#00H ;R5(校验和寄存器)清零
LCALL DELAY_10ms ;时间延迟
CLR TI
MOV A,#0FFH ;发送FFH
MOV SBUF,A
JNB TI,$
CLR TI
ADD A,R4 ;形成累加校验和
MOV R4,A
MOV A,#00H ;发送00H
MOV SBUF,A
JNB TI,$
CLR TI
ADD A,R4 ;形成校验和
MOV R4,A
MOV R6,#03H ;R6存放发送次数(3次)
TXTIMES: MOV A,R2 ;发送本机地址
MOV SBUF,A
JNB TI,$
CLR TI
ADD A,R4 ;形成校验和
MOV R4,A
MOV A,R3 ;发送命令
MOV SBUF,A
JNB TI,$
CLR TI
ADD A,R4 ;形成校验和
MOV R4,A
DJNZ R6,TXTIMES ;判断发送次数(3次)
MOV A,R4 ;发送校验和
MOV SBUF,A
JNB TI,$
CLR TI
CLR P2.7 ;使模块处于接收状态
RET
;************************************************************************
;比较子程序
;比较三对数据是否至少有两对想等,数据存放在50H开始数据寄存器
COMPARE: MOV A,50H
SUBB A,52H ;50H-52H=0?
JNZ C1 ;不等跳转
MOV A,51H
SUBB A,53H
JZ C4 ;相等退出
C1: MOV A,50H
SUBB A,54H
JNZ C2
MOV A,51H
SUBB A,55H ;51H-55H=0?
JZ C4
C2: MOV A,52H
SUBB A,54H
JNZ C3 ;不等跳转
MOV A,53H
SUBB A,55H ;53H-55H=0?
JNZ C3
MOV 50H,52H
MOV 51H,53H
SJMP C4 ;退出子程序
C3: MOV P2,#00H ;出错处理,灯全亮
C4: RET
;***********************************************************************
;延时子程序
DELAY_10ms: MOV R7,#32
DEL1: MOV R6,#142
NOP
DEL2: DJNZ R6,DEL2
DJNZ R7,DEL1
RET
MAIN_END: END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -