📄 1
字号:
;********************************************
;* 超声波测距器 *
;* 12MHZ晶振 *
;* LRM 2005.07.18 *
;********************************************
;测距范围7CM-11M,堆栈在4FH以上,20H用于标志
;显示缓冲单元在40H-43H,使用内存44H、45H、46H用于计算距离
;
VOUT EQU P0.6 ; 超声波脉冲输出端口
VIN EQU P0.7
;*************************************************
LAMPBLAK EQU P1.4 ;背光灯控制,=0时开,=1时关.
CS EQU P1.5 ;液晶使能,=1操作,=0禁止.
SID EQU P1.6 ;液晶串行数据输入口
SCLK EQU P1.7 ;液晶串行操作时钟口
;
;********************************************
;* 中断入口程序 *
;********************************************
;
ORG 0000H
LJMP START
ORG 0003H
RETI
ORG 000BH
LJMP INTT0
ORG 0013H
RETI
ORG 001BH
RETI
ORG 0023H
RETI
ORG 002BH
RETI
;
;********************************************
;* 主 程 序 *
;********************************************
;
START: MOV SP,#4FH
CLR CS ;液晶操
LCALL SETUP ;LCD初始化
LCALL LOGON ;开机显示画面
MOV R0,#40H ;40H-43H为显示数据存放单元(40H为最高位)
MOV R7,#0BH
CLEARDISP: MOV @R0,#00H
INC R0
DJNZ R7,CLEARDISP
MOV 20H,#00H
MOV TMOD,#21H ;T1为8位自动重装模式,T0为16位定时器
MOV TH0,#00H ;65毫秒初值
MOV TL0,#00H
MOV P0,#0FFH
MOV P1,#0FFH
MOV P2,#0FFH
MOV P3,#0FFH
SETB ET0
SETB EA
SETB TR0 ;开启测距定时器
START1: JNB VIN,PINT0
AJMP START1
;
;****************************************************
;* 中断程序* *
;****************************************************
;T0中断,65毫秒中断一次
INTT0: CLR ET0
CLR TR0
MOV TH0,#00H
MOV TL0,#00H
MOV R4,#06H
SETB TR0 ;启动计数器T0,用以计算超声来回时间
VLOOP: CPL VOUT
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R4,VLOOP
SETB ET0
OUT: RETI
;
;回波招收程序
PINT0: CLR TR0 ;关计数器
CLR ET0 ;
MOV 44H,TL0 ;将计数值移入处理单元
MOV 45H,TH0 ;
LCALL WORK ;计算距离子程序
LCALL DATAUP
LCALL DELAY1
SETB TR0 ;重新开启测距定时器
SETB ET0
SJMP START1
;
;****************************************************
;* 距离计算程序 (=计数值*17/1000cm) *
;****************************************************
;
work: PUSH ACC
PUSH PSW
PUSH B
MOV PSW, #18h
MOV R3, 45H
MOV R2, 44H
MOV R1, #00D
MOV R0, #17D
LCALL MUL2BY2
MOV R3, #03H
MOV R2, #0E8H
LCALL DIV4BY2
LCALL DIV4BY2
MOV 40H, R4
MOV A,40H
JNZ JJ0
MOV 40H,#0FH ;最高位为零,不点亮
JJ0: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #100D
LCALL DIV4BY2
MOV 41H, R4
MOV A,41H
JNZ JJ1
MOV A,40H ;次高位为0,先看最高位是否为不亮
SUBB A,#0FH
JNZ JJ1
MOV 41H,#0FH ;最高位不亮,次高位也不亮
JJ1: MOV A, R0
MOV R4, A
MOV A, R1
MOV R5, A
MOV R3, #00D
MOV R2, #10D
LCALL DIV4BY2
MOV 42H, R4
MOV A,42H
JNZ JJ2
MOV A,41H ;次次高位为0,先看次高位是否为不亮
SUBB A,#0FH
JNZ JJ2
MOV 42H,#0FH ;次高位不亮,次次高位也不亮
JJ2: MOV 43H, R0
POP B
POP PSW
POP ACC
RET
;
;****************************************************
;* 两字节无符号数乘法程序 *
;****************************************************
; R7R6R5R4 <= R3R2 * R1R0
;
MUL2BY2: CLR A
MOV R7, A
MOV R6, A
MOV R5, A
MOV R4, A
MOV 46H, #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 46H, MULLOOP1
RET
;
;****************************************************
;* 四字节/两字节无符号数除法程序 *
;****************************************************
;R7R6R5R4/R3R2=R7R6R5R4(商)...R1R0(余数)
;
DIV4BY2: MOV 46H, #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 46H, 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
;
;**********以下液晶开机显示程序**************
;
DATAUP:
MOV A,#93H
LCALL WRITE_COM
MOV R1,#40H ;将40-43H数据查出字码写入LCD
MOV DPTR,#TABLE1
MOV R2,#04H ; 查4
MOV A,#00H
MOVCLOP:MOV A,@R1 ;
MOVC A,@A+DPTR
LCALL WRITE_DAT
INC R1
DJNZ R2,MOVCLOP ;
RET
;
;***************开机显示画面***********************
LOGON: MOV A,#80H ;第一行左第一个字开始
LCALL WRITE_COM
MOV DPTR,#CHINESE ;WORD 16*16点阵TEST
LCALL WRITE_HZ
MOV A,#90H ;第二行左第一个字开始
LCALL WRITE_COM
MOV DPTR,#CHINESE1 ;WORD 16*16点阵TEST
LCALL WRITE_HZ
CLR LAMPBLAK ;开背光灯
LCALL DELAY5S ;显示5秒
SETB LAMPBLAK ;关背光灯
MOV A,#90H ;第二行左第一个字开始
LCALL WRITE_COM
MOV DPTR,#CHINESE2 ;WORD 16*16点阵TEST
LCALL WRITE_HZ
RET
;**********初始化程序*************
SETUP:
MOV A,#01H ;CLEAR DISPLAY
LCALL WRITE_COM
MOV A,#00110000B ;FUNCTION SETTING
LCALL WRITE_COM
MOV A,#00000010B ;DDRAM SET TO '00H'
LCALL WRITE_COM
MOV A,#00000100B ;
LCALL WRITE_COM
MOV A,#00001100B ;DISPLAY ON
LCALL WRITE_COM
MOV A,#00000001B ;CLEARING SCREEN
LCALL WRITE_COM
MOV A,#10000000B ;SET DDRAM ADDRESS
LCALL WRITE_COM
LCALL DELAY
LCALL DELAY
LCALL DELAY
LCALL DELAY
RET
;************串行命令写入子程序****************
;写入命令字在A中
WRITE_COM:
LCALL DELAY1 ;
SETB CS
PUSH ACC
MOV R0,#8
MOV A,#11111000B
COMM1:
CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,COMM1
POP ACC
MOV R5,A
ANL A,#0F0H
MOV R0,#8
COMM2: CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,COMM2
MOV A,R5
SWAP A
ANL A,#0F0H
MOV R0,#8
COMM3: CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,COMM3
CLR CS
RET
;
;***********串行数据写入子程序****************
;写入数据字在A中
WRITE_DAT:
LCALL DELAY1
SETB CS
PUSH ACC
MOV R0,#8
MOV A,#11111010B
DATA1: CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,DATA1
POP ACC
MOV R5,A
ANL A,#0F0H
MOV R0,#8
DATA2: CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,DATA2
MOV A,R5
SWAP A
ANL A,#0F0H
MOV R0,#8
DATA3: CLR C
RLC A
MOV SID,C
CLR SCLK
SETB SCLK
DJNZ R0,DATA3
CLR CS
RET
;
;**************延时子程序**********************
;0.544ms
DELAY1:
MOV R7,#010H
D11: MOV R6,#010H
DJNZ R6,$
DJNZ R7,D11
RET
;0.13s
DELAY:
MOV R1,#00H
D2: MOV R2,#00H
DJNZ R2,$
DJNZ R1,D2
RET
;5.2s
DELAY5S:MOV R3,#28H
DE5S: LCALL DELAY
DJNZ R3,DE5S
RET
DELAY1S:MOV R3,#9
DE1S: LCALL DELAY
DJNZ R3,DE1S
RET
;
;************16*8点阵字写入子程序共16个******************
WRITE_ASCII:
MOV R4,#16
DDDD: CLR A
MOVC A,@A+DPTR
LCALL WRITE_DAT
INC DPTR
DJNZ R4,DDDD
RET
;************16*8点阵字写入子程序共7个******************
WRITE_ASCII7:
MOV R4,#7
DDDD7: MOV A,@R0
LCALL WRITE_DAT
INC R0
DJNZ R4,DDDD7
RET
;************16*16点阵汉字写入子程序共7个***********
WRITE_HZ: ;WRITE 7 CHINESE TO LCD
MOV R4,#7
DD: CLR A
MOVC A,@A+DPTR
INC DPTR
LCALL WRITE_DAT
CLR A
MOVC A,@A+DPTR
INC DPTR
LCALL WRITE_DAT
DJNZ R4,DD
RET
;************16*16点阵汉字写入子程序共2个***********
WRITE_HZ2: ;WRITE 8 CHINESE TO LCD
MOV R4,#2
DD4: CLR A
MOVC A,@A+DPTR
INC DPTR
LCALL WRITE_DAT
CLR A
MOVC A,@A+DPTR
INC DPTR
LCALL WRITE_DAT
DJNZ R4,DD4
RET
;
;*****************************16*8点阵的字符代码表**********************************
TABLE1: DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,3AH,3BH,3CH,3DH,3EH,20H
; 0 1 2 3 4 5 6 7 8 9 : ; < = > "不显"
;**********************************自造字符地址表***********************************
;
;******************"这里是16*16点阵的汉字代码表"************************************
CHINESE: DW 0DBA0H,0D5E3H,0BDADH,0BAA3H,0D1F3H,0D1A7H,0D4BAH,0DBA0H;—浙江海洋学院—
CHINESE1: DW 0DBA0H,0B5A5H,0C6ACH,0BBFAH,0CAB5H,0D1E9H,0DBA0H,0DBA0H;单片机实验—
CHINESE2: DW 0BEE0H,0C0EBH,0DBA0H,0DBA0H,0DBA0H,0C0E5H,0C3D7H,0DBA0H;距离----厘米
;;;;;;;;;;;;;;;;;;;;;;
END ;程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -