📄 int.asm
字号:
EXTRN DATA(snd_len0,snd_chk0,rec_chk0,Sdatabit,Rdatabit,AckAddr)
EXTRN DATA(uart0_status,uart1_status,snd_chk1,rec_chk1,snd_len1,rec_len1)
EXTRN DATA(rec_cmd0,rec_cmd1,SBUF1,LAddr)
EXTRN BIT(rec_bHead0,isLAddr_bFlg,byte_bFinish,RI2,reclen0_bFlg,recaddr0_bFlg,reccmd0_bFlg,reclen1_bFlg,SM)
EXTRN IDATA(SndUart0,RecUart0,SndUart1,RecUart1,Uart0_Over,Uart1_Over,CallTallOver,TmpMs,MsCount)
TH2 DATA 0CDH
TL2 DATA 0CCH
T2CON DATA 0C8H
TR2 EQU T2CON.2
TF2 EQU T2CON.7
MS200 EQU 0C8H ;250ms计时器
TH2INIT EQU 0FBH ;取第2个bit的中点值
TL2INIT EQU 080H ;
UART_RXD EQU P3.2
UART_TXD EQU P3.4
BANK0_REG EQU 00H ;选择第0组寄存器
BANK1_REG EQU 08H ;选择第1组寄存器
BANK2_REG EQU 10H ;选择第2组寄存器
BANK3_REG EQU 18H ;选择第3组寄存器
CSEG AT 0003H
ORG 0003H
LJMP INT0COM_SERVER
ORG 000BH
LJMP T0_SERVER
ORG 0023H
LJMP Uart0_Comm
ORG 002BH
LJMP Uart1_Comm
ORG 0030H
;串口数据收发 Addr+len+cmd+data0...data3+...+chk
Uart0_Comm:
PUSH ACC
PUSH PSW
MOV PSW,#BANK1_REG
JB RI,RECBYTE0
SNDBYTE0:
CLR TI
CJNE R1,#01H,CSNDDATA0
;发送完毕
MOV uart0_status,#02H ;02发送完毕
;接收数据状态
SETB P3.6
LJMP ENDCOM00
;发送下一个Byte
CSNDDATA0:
DEC R1 ;R1的地址与snd_len0地址相同
MOV SBUF,@R0 ;R0 snd0_start
;发送指针下移一个
INC R0
ENDCOM00:
POP PSW
POP ACC
RETI
RECBYTE0:
CLR RI
MOV A,SBUF
JB rec_bHead0,LABLEN0
CJNE A,#0CCH,ENDCOM0 ;头字节
SETB rec_bHead0
SETB reclen0_bFlg
SETB reccmd0_bFlg
SETB recaddr0_bFlg ;准备接收地址
MOV rec_chk0,#0CCH
MOV uart0_status,#03H ;03正在接收上级数据
MOV R0,#Uart0_Over ;接收数据记时开始
MOV @R0,#0
LJMP ENDCOM0
LABLEN0:
JNB reclen0_bFlg,LRECCMD
CLR reclen0_bFlg
XRL rec_chk0,A
MOV R0,A ;R0表示长度字
MOV R1,#RecUart0 ;R1表示数据存放字
LJMP ENDCOM0
;接收命令
LRECCMD:
JNB reccmd0_bFlg,RECADDR
MOV rec_cmd0,A
XRL rec_chk0,A
CLR reccmd0_bFlg
DEC R0 ;长度减1
;是否是轮询命令
CJNE A,LAddr,ENDCOM0 ;轮询命令
SETB isLAddr_bFlg ;是本机地址
CLR recaddr0_bFlg
LJMP ENDCOM0
;接收第一个地址
RECADDR:
JNB recaddr0_bFlg,LABRDATA0
CJNE A,LAddr,NOLAddr
XRL rec_chk0,A
CLR recaddr0_bFlg
SETB isLAddr_bFlg ;是本机地址
DEC R0 ;长度减1
LJMP ENDCOM0
NOLAddr:
CLR isLAddr_bFlg ;非本机地址
POP PSW
POP ACC
RETI
;接收数据
LABRDATA0:
CJNE R0,#01H,REC_DATA0
CLR rec_bHead0 ;接收完成
JNB isLAddr_bFlg,RecNext ;不是本机命令
CJNE A,rec_chk0,CHKERR0
RFINISH0:
MOV uart0_status,#04H ;接收数据完成
POP PSW
POP ACC
RETI
CHKERR0:
MOV uart0_status,#05H ;校验错误
LJMP ENDCOM0
RecNext:
MOV uart0_status,#02H ;接收数据非本机的,状态复位
LJMP ENDCOM0
REC_DATA0:
MOV @R1,A
INC R1
XRL rec_chk0,A
DEC R0
ENDCOM0:
POP PSW
POP ACC
RETI
;-------------------------------------------
;INT0中断服务程序
INT0COM_SERVER:
;等待下一个位的接收时间
MOV TH2,#TH2INIT
MOV TL2,#TL2INIT
;Timer2计时开始
SETB TR2
;INT0中断标志清除
CLR IE0
MOV Rdatabit,#09H ;前面第1位没有收
CLR byte_bFinish
;INT0关闭
CLR EX0
;当前Uart1为接收状态
SETB RI2
RETI
;T2服务子程序
Uart1_Comm:
PUSH ACC
PUSH PSW
CLR TF2
MOV PSW,#BANK3_REG
JB RI2,RECBYTE1
;发送数据
SndByteBit: ;发送一个位
CJNE R1,#0AH,SETSNDBIT ;Sdatabit与R1为同一地址变量
;发送开始Bit位
DEC Sdatabit
;数据包长度-第一字节
DEC snd_len1
CLR UART_TXD
POP PSW
POP ACC
RETI
SETSNDBIT:
;比较byte是否发完
CJNE R1,#00H,SND1BIT
;一个字节发完
SndByte:MOV A,snd_len1
;比较看是否发完了
JZ SND1FISH
;没有发完 发送下一个Byte
MOV SBUF1,@R0
;发送数据指针下移一位
INC R0
;发送完整一贞数据位长度
MOV R1,#0AH ;10bit
POP PSW
POP ACC
RETI
SND1FISH:
;一个完整的数据包发送完毕
MOV uart1_status,#02H ;发送数据完毕
;Timer2停止数据的接收
CLR TR2
;充许INT0中断
CLR IE0
SETB EX0
POP PSW
POP ACC
RETI
SND1BIT:MOV A,SBUF1
MOV C,SM ;SM在这里用作停止位
RRC A
;保存没有发完的数据
MOV SBUF1,A
;剩下数据位-1
DEC Sdatabit
MOV UART_TXD,C
POP PSW
POP ACC
RETI
RECBYTE1:
;没有接收完的BIT个数
MOV R0,Rdatabit
;正在接收的Byte
MOV A,R2
CJNE R0,#01H,RECBIT0
;一个字节接收完毕,INT0接收设置
;INT0中断标志清除
CLR IE0
;充许INT0中断
SETB EX0
;停止Timer2接收数据
CLR TR2
;SETB UART_RXD
;比较是否收到头字节,产生原因是还没有收完最后1bit,提前打开了INT0
; JB byte_bFinish,ENDCOM1
;设置 1 Byte接收完成标志
SETB byte_bFinish
;比较是否是头字节
CJNE A,#0CCH,LABLEN1 ;头字节为0CCH
MOV R0,rec_len1
CJNE R0,#00H,LABLEN1
MOV rec_chk1,A
SETB reclen1_bFlg
LJMP ENDCOM1
LABLEN1:
JNB reclen1_bFlg,LABRDATA1
CLR reclen1_bFlg
MOV rec_len1,A ;rec_len1表示长度字
XRL rec_chk1,A
MOV R1,#RecUart1 ;R1表示数据存放字
LJMP ENDCOM1
LABRDATA1:
DEC rec_len1
MOV R0,rec_len1
CJNE R0,#00H,REC_DATA1
CLR EX0 ;关INT0的中断
;接收完成
CJNE A,rec_chk1,CHKERR1
MOV uart1_status,#03H ;接收完毕
RFINISH1:
MOV R0,#RecUart1
MOV rec_cmd1,@R0 ;接收正确
POP PSW
POP ACC
RETI
CHKERR1:
MOV uart1_status,#04H ;校验错误
LJMP ENDCOM1
REC_DATA1:
MOV @R1,A
INC R1
XRL rec_chk1,A
ENDCOM1:POP PSW
POP ACC
RETI
;=================================
;接收一个BIT
RECBIT0:
MOV C,UART_RXD
RRC A
MOV R2,A
RECENDBIT:
DEC Rdatabit
POP PSW
POP ACC
RETI
;==============================
;------------------------------
;定时器T0 //5MS中断定时 22.1184
T0_SERVER:
PUSH ACC
PUSH PSW
MOV PSW,#BANK2_REG
MOV TH0,#0DCH
MOV TL0,#00H
;TmpMs 5MS计时
MOV R0,#TmpMs
MOV A,@R0
ADD A,#1
MOV @R0,A
;Com0_Over 5MS计时
MOV R0,#Uart0_Over
MOV A,@R0
ADD A,#1
MOV @R0,A
;Com1_Over 5MS计时
MOV R0,#Uart1_Over
MOV A,@R0
ADD A,#1
MOV @R0,A
;1S计时
MOV R0,#MsCount
INC @R0
CJNE @R0,#MS200,ENDCOUNTTIME
MOV @R0,#0
MOV R0,#CallTallOver
INC @R0
ENDCOUNTTIME:
POP PSW
POP ACC
RETI
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -