基于51超声波测距器设计.docx
《基于51超声波测距器设计.docx》由会员分享,可在线阅读,更多相关《基于51超声波测距器设计.docx(16页珍藏版)》请在冰点文库上搜索。
基于51超声波测距器设计
程序清单
以下是用汇编语言编写的超声波测距控制源程序:
采用AT89S5112MHz晶振
显示缓冲单元在40H~43H,使用内存44H、45H、46H用于计算距离
20H用于标志
VOUTEQUP1.0;脉冲输出端口
*中断入口程序*
ORG0000H
LJMPSTART
ORG0003H
LJMPPINT0
ORG000BH
LJMPINTT0
ORG0013H
RETI
ORG001BH
LJMPINTT1
ORG0023H
RETI
ORG002BH
RETI
*主程序*
START:
MOVSP,#4FH
MOVR0,#40H;40~43H为显示数据存放单元(40为最高位)
MOVR7,#0BH
CLEARDISP:
MOV@R0,#00H
INCR0
DJNZR7,CLEARDISP
MOV20H,#00H
MOVTMOD,#21H;T1为8位自动重装模式,T0为16位定时器
MOVTH0,#00H;65ms初值
MOVTL0,#00H;40KHz初值
MOVTH1,#0F2H
MOVTL1,#0F2H
MOVP0,#0FFH
MOVP1,#0FFH
MOVP2,#0FFH
MOVP3,#0FFH
MOVR4,#04H;超声波脉冲个数控制(为赋值的一半)
SETBPX0
SETBET0
STEBEA
CLR00H
SETBTR0;开启测距定时器
START1:
LCALLDISPLAY
JNB00H,START1;收到反射信号时标志位为1
CLREA
LCALLWORK;计算距离子程序
SETBEA
CLR00H
SETBTR0;重新开启测距定时器
MOVR2,#64H;测量间隔控制(约4*100=400ms)
LOOP:
LCALLDISPLAY
DJNZR2,LOOP
SJMPSTART1
*中断程序*
;T0中断,65ms中断一次
INTT0:
CLREA
CLRTR0
MOVTH0,#00H
MOVTL0,#00H
SETBET1
SETBEA
SETBTR0;启动计时器T0,用以计算超声波来回时间
SETBTR1;开启发超声波用定时器T1
OUT:
RETI
;T1中断,发超声波用
INTT1:
CPLVOUT
DJNZR4,RETIOUT
CLRTR1;超声波发送完毕,关T1
CLRET1
MOVR4,#04H
SETBEX0;开启接收回波中断
RETIOUT:
RETI
;外中断0,收到回波时进入
PINT0:
CLRTR0;关计数器
CLRTR1
CLRET1
CLREA
CLREX0
MOV44H,TL0;将计数值移入处理单元
MOV45H,TH0
SETB00H;接收成功标志
RETI
*延时程序*
DL1MS:
MOVR6,#14H
DL1:
MOVR7,#19H
DL2:
DJNZR6,DL2
DJNZR6,DL1
RET
*显示程序*
;40H为最高位,43H为最低位,先扫描高位
DISPLAY:
MOVR1,#40H;G
MOVR5,#0F7H;G
PLAY:
MOVA,R5
MOVP0,#0FFH
MOVP2,A
MOVA,@R1
MOVDPTR,#TAB
MOVCA,@A+DPTR
MOVP0,A
LCALLDLIMS
INCR1
MOVA,R5
JNBACC.0,ENDOUT;G
RRA
MOVR5,A
AJMPPLAY
ENDOUT;MOVP2,#0FFH
MOVP0,#0FFH
RET
TAB;DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,88H,0BFH
;共阳数码管0,1,2,3,4,5,6,7,8,9,不亮,A,—
*距离计算程序(=计算值×17/1000cm)近似
WORK:
PUSHACC
PUSHPSW
PUSHB
MOVPSW,#18H
MOVR3,45H
MOVR2,44H
MOVR1,#00D
MOVR0,#17D
LCALLMUL2BY2
MOVR3,#03H
MOVR2,#0E8H
LCALLDIV4BY2
LCALLDIV4BY2
MOV40H,R4
MOVA,40H
JNZJJ0
MOV40H,#0AH;最高位为0,不点亮
JJ0:
MOVAR0
MOVR4,A
MOVAR1
MOVR5A
MOVR3,#00D
MOVR2,#100D
LCALLDIV4BY2
MOV41H,R4
MOVA,41H
JNZJJ1
MOVA,40H;此高位为0,先看最高位是否为不亮
SUBBA,#0AH
JNZJJ1
MOV41H,#0AH;最高位不亮,次高位也不亮
JJ1:
MOVA,R0
MOVR4,A
MOVA,R1
MOVR5,A
MOVR3,#00D
MOVR2,#10D
LCALLDIV4BY2
MOV42H,R4
MOVA42H
JNZJJ2
MOVA,41H;次高位为0,先看次高位是否为不亮
SUBBA,#0AH
JNZJJ2
MOV42H,#0AH;次高位不亮,次高位也不亮
JJ2:
MOV43H,R0
POPB
POPPSW
POPACC
RET
*两字节无符号数乘法程序
MUL2BY2:
CLRA
MOVR7,A
MOVR6,A
MOVR5,A
MOVR4,A
MOV46H,#10H
MULLOOP1:
CLRC
MOVA,R4
RLCA
MOVR4,A
MOVA,R5
RLCA
MOVR5,A
MOVA,R6
RLCA
MOVR6,A
MOVA,R7
RLCA
MOVR7,A
MOVA,R0
RLCA
MOVR0,A
MOVA,R1
RLCA
MOVR1,A
JNCMULLOOP2
MOVA,R4
ADDA,R2
MOVR4,A
MOVA,R5
ADDCA,R3
MOVR5,A
MOVA,R6
ADDCA,#00H
MOVR6,A
MOVA,R7
ADDCA,#00H
MOVR7,A
MULLOOP2:
DJNZ46H,MULLOOP1
RET
*四字节/两字节无符号数除法程序*
DIV4BY2:
MOV46H,#20H
MOVR0,#00H
MOVR1,#00H
DIVLOOP1:
MOVA,R4
RLCA
MOVR4,A
MOVA,R5
RLCA
MOVR5,A
MOVA,R6
RLCA
MOVR6,A
MOVA,R7
RLCA
MOVR7,A
MOVA,R0
RLCA
MOVR0,A
MOVA,R1
RLCA
MOVR1,A
CLRC
MOVA,R0
SUBBA,R2
MOVB,A
MOVA,R1
SUBBA,R3
JCDIVLOOP2
MOVR0,B
MOVR1,A
DIVLOOP2:
CPLC
DJNZ46H,DIVLOOP1
MOVA,R4
RLCA
MOVR4,A
MOVA,R5
RLCA
MOVR5,A
MOVA,R6
RLCA
MOVR6,A
MOVA,R7
RLCA
MOVR7,A
RET
;
END
附C51程序
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
externvoidcs_t(void);
externvoiddelay(uint);
externvoiddisplay(uchar*);
//datauchardisplay(uchar*);
datauchartestok;
voidmain(void)
{
datauchardispram[5];
datauinti;
dataulongtime;
P0=0xff;
P2=0xff;
TMOD=0x11;
IE=0x80;
while
(1)
{
cs_t();
delay
(1);
testok=0;
EX0=1;
ET0=1;
while(!
testok)display(dispram);
if(1==testok)
{
time=TH0;
time=(time<<8)|TL0;
time*=172;
time/=10000;
dispram[0]=(uchar)(time%10);
time/=10;
dispram[1]=(uchar)(time%10);
time/=10;
dispram[2]=(uchar)(time%10);
dispram[3]=(uchar)(time/10);
if(0==dispram[3])dispram[3]=17;
}else
{
dispram[0]=16;
dispram[1]=16;
dispram[2]=16;
dispram[3]=16;
}
for(i=0;i<300;i++)display(dispram);
}
}
voidcs_r(void)interrupt0
{
TR0=0;
ET0=0;
EX0=0;
testok=1;
}
voidovertime(void)interrupt1
{
EX0=0;
TR0=0;
ET0=0;
testok=2;
}
NAMECS_T
?
PR?
CS_T?
CS_TSEGMENTCODE
PUBLICCS_T
RSEG?
PR?
CS_T?
CS_T
CS_T:
PUSHACC
MOVTH0,#00H
MOVTL0,#00H
MOVA,#4D
SETBTR0
CS_T1:
CPLp1.0
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZACC,CS_T1
POPACC
RET
;
END
namedelay
?
pr?
_delay?
delaysegmentcode
public_delay
rseg?
pr?
_delay?
delay
_delay:
pushacc
mova,r7
jzdela1
incr6
dela1:
movr5,#50d
djnzr5,$
djnzr7,dela1
djnzr6,dela1
popacc
ret
end
NAMEDISPLAY
?
PR?
_DISPLAY?
displaysegmentcode
?
co?
_DISPLAY?
displaysegmentdata
EXTRNCODE(_DELAY)
PUBLIC_DISPLAY
RSEG?
CO?
_DISPLAY?
DISPLAY
?
_display?
byte:
dispbit:
ds1
dispnum:
ds1
rseg?
pr?
_display?
display
_display:
pushacc
pushdph
pushdpl
pushpsw
incdispnum
mova,dispnum
cjnea,#4d,disp1
DISP1:
JCDISP2
MOVDISPNUM,#00H
MOVDISPBIT,#0FEH
DISP2:
MOVA,R1
ADDA,DISPNUM
MOVR0,A
MOVA,@R0
MOVDPTR,#DISPTABLE
MOVCA,@A+DPTR
MOVP0,A
MOVA,DISPNUM
CJNEA,#2D,DISP3
CLRP0.7
DISP3:
MOVP2,DISPBIT
MOVR5,#00H
MOVR7,#0AH
LCALL_DELAY
MOVP0,#0FFH
MOVP2,#0FFH
MOVA,DISPBIT
RLA
MOVDISPBIT,A
POPPSW
POPDPL
POPDPH
POPACC
RET
DISPTABLE:
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EH,0BFH,0FFH
END