📄 系统.asm
字号:
;****************************************************
;*超声波倒车雷达
;*12MHz晶振
;*共阳LED显示器,空位显示0,2*4位一体数码管(8位)
;****************************************************
;堆栈在4F以上,20H用于接收成功标志,21H用于当前距离与设定值判定标志(1表示相等->报警)
;显示缓冲单元40H-43H为设定安全距离显示;44H-47H为实际距离显示
;内存4AH,4BH,4CH用于计算距离
;
;
;
VOUT EQU P3.0
;
;
;
;***************************************************
;* 中断入口
;***************************************************
;
ORG 0000H
LJMP START
ORG 0003H
LJMP PINT0
ORG 000BH
LJMP INTT0
ORG 0013H
RETI
ORG 001BH
LJMP INTT1
ORG 0023H
RETI
ORG 002BH
RETI
;**************************************************
; 主程序
;**************************************************
START: MOV SP, #4FH
MOV R0, #40H ;40~47H为显示数据存放单元(40为最高位)
MOV R7,#0FH
CLEARDISP: MOV @R0, #00H
INC R0
DJNZ R7, CLEARDISP
CALL KEY_PLAER
CALL KEY_SCAN1 ;调用设定距离程序
START0: MOV 20H, #00H
MOV TMOD, #21H ;T1为8位自动重装模式,T0为16位定时器
MOV TH0, #8AH ;65ms初值
MOV TL0, #0CFH
MOV TH1, #0F4H ;40KHz初值
MOV TL1, #0F4H
MOV P0, #0FFH
MOV P1, #0FFH
MOV P2, #0FFH
MOV P3, #0FFH
MOV R4, #08H ;超声波脉冲个数控制(为赋值的一半)
SETB PX0
SETB ET0
SETB EA
SETB TR0 ;开启测距定时器
START1: LCALL DISPLAY
JNB 00H, START1 ;收到反射信号时标志位为1
CLR EA
LCALL WORK ;计算距离子程序
LCALL CMP
JB 30H,WARN
SETB EA
CLR 30H
CLR 00H
SETB TR0 ;重新开启测距定时器
MOV R2, #064H ;测量间隔控制(约4*100=400ms)64H
LOOP: LCALL DISPLAY
DJNZ R2, LOOP
SJMP START0
WARN:
CLR TR0 ;关计数器
CLR TR1
CLR EX0
CLR EA
CLR ET0
CLR ET1
CALL ALARM
SJMP WARN
;
;****************************************
;中断程序
;****************************************
;T0中断,65ms中断一次
;
INTT0: CLR EA
CLR TR0
MOV TH0, #8AH
MOV TL0, #0CFH
SETB ET1
SETB EA
SETB TR0 ;启动计时器T0,用以计算超声波来回时间
SETB TR1 ;开启发超声波用定时器T1
OUT: RETI
;
;T1中断,发超声波用
;
INTT1: CPL VOUT
DJNZ R4,RETIOUT
CLR TR1 ;超声波发送完毕,关T1
CLR ET1
MOV R4,#08H
CLR IE0
SETB EA
SETB EX0 ;开启接收回波中断
RETIOUT: RETI
;
;外中断0,收到回波时进入
;
PINT0:
CLR TR0 ;关计数器
CLR TR1
CLR EA
CLR ET0
CLR ET1
CLR EX0
MOV 4AH, TL0 ;将计数值移入处理单元
MOV 4BH, TH0
SETB 00H ;接收成功标志
RETI
;********************************
;键盘设定安全距离
;********************************
KEY_SCAN1: ;识别键盘有无键按下子程序
MOV P2,#0F0H ;置列线为0,行线为1
MOV A,P2 ;读P2口
ANL A,#0F0H ;取出高四位
MOV B,A ;暂存到B
MOV P2,#0FH ;置列线为1,行线为0
MOV A,P2 ;读P2口
ANL A,#0FH ;取出低四位
ORL A,B ;高四位与低四位逻辑或运算重新组合
CJNE A,#0FFH,KEY_IN1_1 ;0FFH为无按键按下
JMP KEY_SCAN1
KEY_IN1_1: ;识别具体按键值子程序
MOV B,A ;将按键的特征编码暂存于B
MOV DPTR,#KEY_TABLE
MOV R3,#0FFH
KEY_IN1_2:
INC R3 ;顺序码加1
MOV A,R3
MOVC A,@A+DPTR ;查表
CJNE A,B,KEY_IN1_3 ;比较,若相同则找到按键的特征编码。
MOV A,R3 ;找到特征编码后,取顺序码
MOV 43H,A ;存入43H单元
CALL KEY_PLAER
MOV 42H,43H
MOV 43H,#00H
CJNE R3,#10,KEY_SCAN2 ;输入是否结束
JMP EXIT
KEY_IN1_3:
CJNE A,#00H,KEY_IN1_2 ;末完,继续查
JMP KEY_SCAN1 ;00H为结束码
KEY_SCAN2: ;识别键盘有无键按下子程序
MOV P2,#0F0H ;置列线为0,行线为1
MOV A,P2 ;读P2口
ANL A,#0F0H ;取出高四位
MOV B,A ;暂存到B
MOV P2,#0FH ;置列线为1,行线为0
MOV A,P2 ;读P2口
ANL A,#0FH ;取出低四位
ORL A,B ;高四位与低四位逻辑或运算重新组合
CJNE A,#0FFH,KEY_IN2_1 ;0FFH为无按键按下
JMP KEY_SCAN2
KEY_IN2_1: ;识别具体按键值子程序
MOV B,A ;将按键的特征编码暂存于B
MOV DPTR,#KEY_TABLE
MOV R3,#0FFH
KEY_IN2_2:
INC R3 ;顺序码加1
MOV A,R3
MOVC A,@A+DPTR ;查表
CJNE A,B,KEY_IN2_3 ;比较,若相同则找到按键的特征编码。
MOV A,R3 ;找到特征编码后,取顺序码
MOV 43H,A ;存入43H单元
CJNE R3,#10,OUT2 ;输入是否结束
MOV 43H,42H
MOV 42H,#00H
MOV 41H,#00H
JMP EXIT
OUT2:
CALL KEY_PLAER
MOV 41H,42H
MOV 42H,43H
MOV 43H,#0AH
JMP KEY_SCAN3
KEY_IN2_3:
CJNE A,#00H,KEY_IN2_2 ;末完,继续查
JMP KEY_SCAN2 ;00H为结束码
KEY_SCAN3: ;识别键盘有无键按下子程序
MOV P2,#0F0H ;置列线为0,行线为1
MOV A,P2 ;读P2口
ANL A,#0F0H ;取出高四位
MOV B,A ;暂存到B
MOV P2,#0FH ;置列线为1,行线为0
MOV A,P2 ;读P2口
ANL A,#0FH ;取出低四位
ORL A,B ;高四位与低四位逻辑或运算重新组合
CJNE A,#0FFH,KEY_IN3_1 ;0FFH为无按键按下
JMP KEY_SCAN3
KEY_IN3_1: ;识别具体按键值子程序
MOV B,A ;将按键的特征编码暂存于B
MOV DPTR,#KEY_TABLE
MOV R3,#0FFH
KEY_IN3_2:
INC R3 ;顺序码加1
MOV A,R3
MOVC A,@A+DPTR ;查表
CJNE A,B,KEY_IN3_3 ;比较,若相同则找到按键的特征编码。
MOV A,R3 ;找到特征编码后,取顺序码
MOV 43H,A ;存入43H单元
CJNE R3,#10,OUT3 ;输入是否结束
MOV 43H,42H
MOV 42H,41H
MOV 41H,#00H
JMP EXIT
OUT3: CALL KEY_PLAER
JMP EXIT
KEY_IN3_3:
CJNE A,#00H,KEY_IN3_2 ;末完,继续查
JMP KEY_SCAN3 ;00H为结束码
EXIT:
NOP
NOP
CALL DISPLAY
RET
KEY_TABLE:DB 07DH ;0 顺序码
DB 0EEH,0EDH,0EBH ;1,2,3 顺序码
DB 0DEH,0DDH,0DBH ;4,5,6 顺序码
DB 0BEH,0BDH,0BBH ;7,8,9 顺序码
DB 077H ;D 输入结束确认
DB 00H ;结束码
;*******************************
; 报警程序
;*******************************
ALARM:
CLR TR0 ;关计数器
CLR TR1
CLR EA
CLR ET0
CLR ET1
CLR EX0
CPL P3.1
CALL DISPLAY
JMP ALARM
RET
;********************************
; 显示程序
;********************************
KEY_PLAER:
MOV R1,#07FH ;扫描初值送入R1
MOV R2,#08H ;扫描位数送入R2
MOV R0,#40H ;开始填充显示单元
DISP0: MOV A,@R0 ;显示内容送入A
MOV DPTR,#TABLE ;获得表头
MOVC A,@A+DPTR ;查表获得显示数据
MOV P0,A ;显示单元数据
MOV P1,R1 ;开始显示当前位
MOV A,R1 ;准备显示下一位
RR A
MOV R1,A
INC R0 ;取下一个单元地址
CALL DELAY ;延时0.25S
DJNZ R2,DISP0 ;重复显示下一个
;显示完成,返回
RET
;**********************************
DISPLAY: MOV R1,#40H
MOV R5,#07FH
PLAY: MOV A,R5
MOV P0,#0FFH
MOV P1,A
MOV A,@R1
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV P0,A
CALL DL1MS
INC R1
MOV A,R5
JNB ACC.0,ENDOUT
RR A
MOV R5,A
JMP PLAY
ENDOUT: MOV P1,#0FFH
MOV P0,#0FFH
RET ;显示完成,返回
;
TABLE:DB 03H,9FH,25H,0DH,99H,49H,41H,01FH,01H,09H,03H
;********************************
;延时程序
;********************************
DL1MS: MOV R6,#14H
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;*******************************
;晶振12MHZ,延时0.25秒
;*******************************
DELAY:MOV 72H,#100
LOOP3:MOV 71H,#100
LOOP1:MOV 70H,#10
LOOP0:DJNZ 70H,LOOP0
DJNZ 71H,LOOP1
MOV 70H,#46
LOOP2:DJNZ 70H,LOOP2
NOP
DJNZ 72H,LOOP3
MOV 70H,#48
LOOP4:DJNZ 70H,LOOP4
RET
;**************************************************
;* 距离计算程序(=计算值×17/1000cm) 近似 *
;**************************************************
WORK:PUSH ACC
PUSH PSW
PUSH B
MOV PSW, #18H ;RS1=1,RS0=1
MOV R3, 4BH
MOV R2, 4AH
MOV R1, #00D
MOV R0, #17D ;与17相乘
LCALL MUL2BY2 ;R7R6R5R4<=R3R2*R1R0
MOV R3, #03H
MOV R2, #0E8H
LCALL DIV4BY2 ;R7R6R5R4/R3R2=R7R6R5R4(商)......R1R0(余数)
LCALL DIV4BY2 ;R7R6R5R4/R3R2=R7R6R5R4(商)......R1R0(余数)
MOV 44H, R4
MOV A, 44H
JNZ JJ0 ;A不等于0时,跳转
MOV 44H, #00H ;最高位为0,不点亮
JJ0: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #100D
LCALL DIV4BY2
MOV 45H, R4
MOV A, 45H
JNZ JJ1
MOV A, 44H ;此高位为0,先看最高位是否为不亮
SUBB A, #0AH
JNZ JJ1
MOV 45H, #00H ;最高位不亮,次高位也不亮
JJ1: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #10D
LCALL DIV4BY2
MOV 46H, R4
MOV A, 46H
JNZ JJ2
MOV A, 45H ;次高位为0,先看次高位是否为不亮
SUBB A, #0AH
JNZ JJ2
MOV 46H, #00H ;次高位不亮,次高位也不亮
JJ2: MOV 47H, R0
DEC 45H
DEC 45H
DEC 45H
DEC 45H
DEC 45H
DEC 45H
MOV A,45H
CJNE A,#00H,JJ4
JMP JJ5
JJ4:
MOV A,46H
CJNE A,#00H,JJ5
MOV 46H,#09H
DEC 45H
JMP JJ6
JJ5: DEC 46H
JJ6: POP B
POP PSW
POP ACC
RET
;************************************
;* 两字节无符号数乘法程序 *
;************************************
;R7R6R5R4<=R3R2*R1R0
;16次叠加R3R2运算,主要是移位
MUL2BY2: CLR A
MOV R7, A
MOV R6, A
MOV R5, A
MOV R4, A
MOV 4CH, #10H
MULLOOP1:CLR C
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
JNC MULLOOP2
MOV A, R4
ADD A, R2
MOV R4, A
MOV A, R5
ADDC A, R3
MOV R5, A
MOV A, R6
ADDC A, #00H
MOV R6, A
MOV A, R7
ADDC A, #00H
MOV R7, A
MULLOOP2:DJNZ 4CH, MULLOOP1
RET
;**************************************
;* 四字节/两字节无符号数除法程序 *
;**************************************
;R7R6R5R4/R3R2=R7R6R5R4(商)......R1R0(余数)
DIV4BY2: MOV 4CH, #20H
MOV R0, #00H
MOV R1, #00H
DIVLOOP1:MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
MOV A, R0
RLC A
MOV R0, A
MOV A, R1
RLC A
MOV R1, A
CLR C
MOV A, R0
SUBB A, R2
MOV B, A
MOV A, R1
SUBB A, R3
JC DIVLOOP2
MOV R0, B
MOV R1, A
DIVLOOP2:CPL C
DJNZ 4CH, DIVLOOP1
MOV A, R4
RLC A
MOV R4, A
MOV A, R5
RLC A
MOV R5, A
MOV A, R6
RLC A
MOV R6, A
MOV A, R7
RLC A
MOV R7, A
RET
;********************************
;距离比较
;********************************
CMP:
MOV A,41H
CJNE A,#00H,CMP1
MOV A,45H
CJNE A,#00H,CMP1
MOV A,42H
CJNE A,46H,LESS0
MOV A,43H
CJNE A,47H,LESS0
SETB 30H
JMP OUTCMP
LESS0: JC OUTCMP ;C=1跳走,操作数1《操作数2时,C=1
SETB 30H
JMP OUTCMP
CMP1: MOV A,41H
CJNE A,45H,LESS1
MOV A,42H
CJNE A,46H,LESS1
MOV A,43H
CJNE A,47H,LESS1
SETB 30H
JMP OUTCMP
LESS1:JC OUTCMP ;C=1跳走,操作数1《操作数2时,C=1
SETB 30H
JMP OUTCMP
OUTCMP: NOP
NOP
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -