//超声波测距,测距范围2cm-400cm; #include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit trig=P1^0;
sbit echo=P3^2;
sbit test=P1^1; //测试灯sbit dula=P2^6;
sbit wela=P2^7;
sbit BEEP=P2^3;
uint timeh,timel,distance;
uint ge,shi,bai,xiaoshu,flag,time;
/*共阴极数码管不带小数点代码表*/
uchar code list[]={
0x3f , 0x06 , 0x5b , 0x4f ,
0x66 , 0x6d ,0x7d , 0x07 ,
0x7f , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71 };
/*共阴极数码管带小数点代码表*/ uchar code listtwo[] = {
0xbf,0x86,0xdb,0xcf,0xe6,
0xed,0xfd,0x87,0xff,0xef};
/*长延时函数*/
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--); }
/*短延时函数*/
void delay20us()
{
uchar a;
for(a=0;a<100;a++); }
/*报警函数*/
void beer()
{
// BEEP=0;
delay(10);
}
/*定时器初始化*/
void initime0()
{
TMOD=0x01;
TH0=0;
TL0=0;
EA=0;
ET0=0;
EX0=0;
}
/*外部中断函数*/
void estern() interrupt 0
{
timeh=TH0;
timel=TL0;
beer();
flag=1; //进入中断,标志位就置1 EX0=0; //同时关断外部中断和定时器TR0=0;
}
/*显示函数*/
void display(distance)
{
bai=distance/1000;
shi=distance%1000/100; ge=distance%100; xiaoshu=distance%10;
dula=1;
P0=list[xiaoshu];
dula=0;
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
delay(2);
dula=1;
P0=listtwo[ge];
dula=0;
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
delay(2);
dula=1;
P0=list[shi];
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delay(1);
dula=1;
P0=list[bai];
dula=0;
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
delay(1);
}
/*被调用子函数*/
void diaoyong()
{
uint i;
EA=0;
echo=1; //为了检测电平的高低,首先必须拉高
trig=1;
delay20us();
trig=0;
while(echo==0); //如果进入中断即接收到超声波就向下执行
flag=0; //接收到就清除标志位
EA=1; //同时打开总中断
EX0=1; //打开外部中断
TR0=1; //开定时器
TH0=0; //定时器清零
TL0=0;
for(i=0;i<100;i++) //等待测量的结果
{
display(distance); //用100次显示循环来延时,解决数码管显示不亮问题
}
// delay(50); //用延时函数数码管闪烁
TR0=0; //延时一段时间后关断定时器
EX0=0; //延时一段时间后关断外部中断
if(flag==1) //如果进入中断,说明测距已经测好
{
time=timeh*256+timel;//计算测定距离,并显示
distance=time*0.1720;
display(distance);
}
if(flag==0) //如果没有进入中断,距离为0,同时灯闪烁
{
distance=0;
test=!test;
}
}
/*主函数*/
void main()
{
initime0();
test=0;
trig=0;
EA=1;
while(1)
{
diaoyong();
display(distance);
}
}。