测量原理:
1.P10管脚产生40kHz方波,并开始计时
2.P11读取到低电平,结束计时,就可以得到时间T
3.根据公式距离=时间*时间/2 (声速为340m/s),即可计算距离
因为我们在程序中需要使用定时器2来进行中断操作,这里我们需要再选择一个定时器来计时,这里我们使用定时器1,启动定时器1后,每过1us,计数器值+1,当计数器加到65535时,需要将计数器清零,然后继续计时。
编程思路:
1.编程实现P10输出40kHz的方波,推荐发送8个方波,因为这样最符合P10管脚产生40kHz方波的要求
2.清零TL1和TL0,并启动定时器1
3.等待P11接收到低电平
4.关闭定时器1,并根据TL1和TL0的值,计算距离
1.方波发送函数如下,使用该函数发送8个方波
void Send_Wave()
{
unsigned char i;
for(i=0;i<8;i++)
{
P10=1;
Delay12us();
P10=0;
Delay12us();
}
}
解释:这里用了Delay12us()函数,是因为一个完整的方波发送周期为12*2=24us,那么频率为1/24=41.66,最接近要求的40kHz。要生成Delay12us()函数,使用stc-isp即可,之前我的delay软件延时博客中有讲,感兴趣的可以参考一下。C51:Delay软件延时_51单片机delay延时函数教程-CSDN博客
2.超声波距离计算函数:
unsigned int Distance_Get()
{
unsigned int dist;
Send_Wave(); //发送8个方波
TH1=0; TL1=0; //清零定时器1
TR1=1; //开启定时器1
while((P11==1)&&(TF1==0));//等待P11变成低电平
TR1=0; //当P11变成低电平关闭定时器1
if(TF1==1)
{
TF1=0;
}
else
{
dist=(TH1<<8|TL1)*0.017;//计算距离,单位是cm
}
return dist;
}
解释:TH1读取的是高8位的时间的值,TL1读取的是低8位时间的值,所以需要先将TH1左移8位,然后使用 | 操作得到总时间。声速为340m/s,因为我们返回的距离的单位是cm,所以转换一下为0.034cm/us,又由于是一来一回的距离,所以需要除以2,即*0.017
一个简单的程序示例:
unsigned int dist_cnt;
unsigned int dist_sonic;
void Sonic_process()
{
if(dist_cnt==100)
{
dist_cnt=0;
dist_sonic=Distance_Get();
}
}
int main()
{
while(1)
{
Timer2Init();
Sonic_process();
}
}
void Timer2Init() interrupt 12
{
dist_cnt++;
}
当然我是省略了定时器2初始化函数的一部分,大家在实操的时候记得补全,得到距离后,就可以写一个数码管操作函数,将得到的距离显示在数码管上。数码管显示距离(包含小数部分)的部分,大家可以参考一下我写的读取温度的这篇博客,原理是一样的。