C51:使用超声波测量距离
测量原理:
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; //清零定时器1TR1=1; //开启定时器1while((P11==1)&&(TF1==0));//等待P11变成低电平TR1=0; //当P11变成低电平关闭定时器1if(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初始化函数的一部分,大家在实操的时候记得补全,得到距离后,就可以写一个数码管操作函数,将得到的距离显示在数码管上。数码管显示距离(包含小数部分)的部分,大家可以参考一下我写的读取温度的这篇博客,原理是一样的。
DS18B20扩展:在数码管上显示温度时包含小数部分-CSDN博客