#include<reg52.h>
#include<intrins.h>
unsigned int th,tl,time,juli; //定义四个个全局变量
unsigned char code tab []={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09};
sbit out=P1^0; //40KHz超声波输出口
unsigned int chenggong=0;
unsigned int chaobiao=0;
unsigned int flag; //定义一个变量作为标志位
void reset() //初始化子程序
{
TMOD=0x21; //开T1的方式2,8位自动重装载,开T0的方式1,16位的,最大计数为65536
TH0=0x00; /*65ms计数初值*/
TL0=0x00;
ET0=1; //开定时器0分中断
EA=1; //开总中断
// TR0=1; //不启动定时器0,等要发射时才启动,开始计数
TH1=0xf4; //定时器1赋值,用来产生40KHz的波形
TL1=0xf3;
ET1=1; //开定时器1的分中断
// TR1=1; //不启动定时器1,用来控制发射
// EX0=1; //开分中断
IT0=1; //下降沿触发
flag=0; //标志位清零
P1=0xff; //P1口作为输入口,置1
}
//=========延时程序,时间可控,由a的值决定大小===================
void delay(int a)
{
while(a--)
;
} //给a=1000延时时间为1ms
//=========定时器1中断子程序=====================================
void timer1() interrupt 3
{
out=!out; //每隔12us取反一次,会引起误差
}
//=========定时器T0中断程序=======================================
void TIMER0() interrupt 1
{
chaobiao=1; //显示超标的灯,范围为0.065*340/2米
}
/***************************外部中断0程序***************************/
PINT0() interrupt 0
{
EA=0; //进入外部中断0后就关掉总中断
th=TH0; //将时间送入暂存器
th<<=8;
tl=TL0;
time=th|tl; //算时间,高8位要乘以256,再相加
time*=12; //因为定时器默认为12分频
juli=time/58; //为什么除以58等于厘米, Y米=(X秒*344)/2
// X秒=( 2*Y米)/344 ==》X秒=0.0058*Y米 ==》厘米=微秒/58
chenggong=1; //显示测距成功指示灯
TH0=0x00; //清掉
TL0=0x00;
TR0=0; //关掉定时器0,等发射时再开
EX0=0; //关掉外部中断0
EA=1; //开总中断
}
//===========显示子程序===========================
void display(unsigned int d)
{
int q,b,s,g;
q=d/1000;
b=d%1000/100;
s=d%1000%100/10;
g=d%1000%100%10;
P0=0Xfd;
P2=tab[q];
delay(50);
P2=0xff;
P0=0Xfb;
P2=tab[b];
delay(50);
P2=0xff;
P0=0Xf7;
P2=tab[s];
delay(50);
P2=0xff;
P0=0Xef;
P2=tab[g];
delay(50);
P2=0xff;
}
//===========主程序====================================
void main()
{
unsigned int j; //用来显示跑圈计数,显示10次
j=10;
reset(); //初始化
while(1)
{
EX0=0; //先不开外部中段
TR1=1; //启动定时器1.产生40KHz频率
TR0=1; //启动定时器0,计数
delay(30); //延时4ms,发射一段的波形
TR1=0; //停止发射
delay(5); //延时一段时间后,再开外部中断,时间大概为0.04/340秒,避免发射
//后直接接收。而不是反射回来的信号。所以它的盲区是小于4cm
EX0=1; //启动外部中断0
if(chenggong==1 && chaobiao==0)
{
while(j--)
{
display(juli); //显示10个周期
}
j=10;
}
else
{
chaobiao=0;
display(0);
}
}
} |