一、设计目标
使用51单片机和超声波测距模块实现超声波测距。
二、主要功能
超声波测距。
三、硬件部分
51单片机,超声波测距模块,导线,动态数码管,74HC245芯片,74HC138芯片。
图1
图2
文章来源地址https://www.toymoban.com/news/detail-489124.html
图3
文章来源:https://www.toymoban.com/news/detail-489124.html
图4
图1为超声波测距模块的内部电路图。
图2为超声波测距的输出和接收声波的时序逻辑图。
图3、图4为动态数码管的控制。使用51单片机的P0_0、P0_1、P0_2端连接74HC138芯片的A、B、C引脚,从而控制哪一个数码管被点亮。
四、程序框图
五、代码说明
代码由延时函数、定时器函数、算距离函数、测时间函数、数码管控制函数、数码管显示结果函数、主函数组成
延时函数和数码管控制函数配合,负责动态数码管显示的硬件控制。
定时器函数用于测距时定时。
测时间函数计算超声波发出到接收的时间。
算距离函数用于对测量的时间进行计算得出距离。
数码管显示结果函数用于对测量出的结果进行显示。
数码管控制函数用来控制动态数码管点亮第几位和显示的数字。
1.主函数
主函数对函数进行调用,首先调用测时间函数得出超声波发出到接收的时间。然后调用算距离函数将时间转化为距离(单位:厘米)。最后调用数码管显示结果函数显示测量的结果。
/******************************************主函数***************************************/
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();//传感器接收到高电平的时间
distance = GetDistance(time);
xianshi(distance);
}
}
2.子函数1
数码管控制函数。使用switch()功能,根据硬件中的表格,提前将点亮每个动态数码管所需的信号定义好。Switch()可以采集输入动态数码管函数的值,其中前边一位是点亮第几位动态数码管。另外再定义一个数字数组,数组的内容为单个动态数码管显示0-9即全灭时所需的P3端输出值。
unsigned char shuzi[]={0x3f/*0*/,0x06/*1*/,0x5b/*2*/,0x4f/*3*/,0x66/*4*/,0x6d/*5*/,0x7d/*6*/,0x07/*7*/,0x7f/*8*/,0x6f/*9*/};//显示的数字(num)的数组
void shumaguan(unsigned char wei,num)//第几位(wei)显示
{
switch(wei)
{
case 1:P0_2=0;P0_1=0;P0_0=0;break;
case 2:P0_2=0;P0_1=0;P0_0=1;break;
case 3:P0_2=0;P0_1=1;P0_0=0;break;
case 4:P0_2=0;P0_1=1;P0_0=1;break;
case 5:P0_2=1;P0_1=0;P0_0=0;break;
case 6:P0_2=1;P0_1=0;P0_0=1;break;
case 7:P0_2=1;P0_1=1;P0_0=0;break;
case 8:P0_2=1;P0_1=1;P0_0=1;break;
}
P3=shuzi[num];
delay(1);
}
3.子函数2
延时函数。和数码管控制函数配合,负责动态数码管显示的硬件控制。
/******************************************延时函数***************************************/
void delay(unsigned int xms)//延时x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
4.子函数3
定时器函数。因输出超声波时需要10us的高电平,因此定义该函数。同时也可以用于计算发出到接收的时间。
/**********************************定时器函数 延时10us*************************************/
void Delay10us()
{
TMOD |= 0x01;//16位定时器/计数器
TH0 = 0xFF;//赋初值
TL0 = 0xF6;//赋初值
TR0 = 1;//启动
while(!TF0);//溢出
TF0 = 0;//清溢出
}
5.子函数4
算距离函数。用于将测出的时间转化为距离。
/******************************************算距离函数***************************************/
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;//cm 距离=高电平时间×声速/2 0.017cm/us
return distance;//将距离返回主函数
}
6.子函数5
测时间函数。与定时器函数配合实现超声波的发出与时间测量。
/******************************************测时间函数***************************************/
unsigned int RunOnce()
{
unsigned int time;
/******************发送10us高电平信号*************/
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
/**************等待高电平信号接收*****************/
while(!Echo);
/*********T0清0重新计数(高电平持续时间)*********/
TH0 = 0;
TL0 = 0;
TR0 = 1;
/*********等待高电平信号接收结束******************/
while(Echo);
/*******************关闭T0计数********************/
TR0 = 0;
/**********高电平时间赋值,单位us*****************/
time = TH0*256 + TL0;
TH0 = 0;
TL0 = 0;
return time;
}
7.子函数6
动态数码管显示结果函数。用于控制动态数码管显示测量出的距离。
/**************************************动态数码管显示结果***********************************/
void xianshi(int d)
{
int k=8,m;
while(d!=0)
{
m=(d%10);//在数码管上显示个位,从后往前显示
shumaguan(k,m);
k--;//数码管向前移位
d=d/10;
}
}
六、系统测试
测最近有效距离,为3cm。
测最远有效距离,为560cm。
七、源代码
#include <REGX51.H>
#include<intrins.h>
sbit Trig = P1^0;
sbit Echo = P1^1;
/******************************************延时函数***************************************/
void delay(unsigned int xms)//延时x毫秒
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=112;j>0;j--);
return;
}
/******************************************数码管控制函数***************************************/
unsigned char shuzi[]={0x3f/*0*/,0x06/*1*/,0x5b/*2*/,0x4f/*3*/,0x66/*4*/,0x6d/*5*/,0x7d/*6*/,0x07/*7*/,0x7f/*8*/,0x6f/*9*/};//显示的数字(num)的数组
void shumaguan(unsigned char wei,num)//第几位(wei)显示
{
switch(wei)
{
case 1:P0_2=0;P0_1=0;P0_0=0;break;
case 2:P0_2=0;P0_1=0;P0_0=1;break;
case 3:P0_2=0;P0_1=1;P0_0=0;break;
case 4:P0_2=0;P0_1=1;P0_0=1;break;
case 5:P0_2=1;P0_1=0;P0_0=0;break;
case 6:P0_2=1;P0_1=0;P0_0=1;break;
case 7:P0_2=1;P0_1=1;P0_0=0;break;
case 8:P0_2=1;P0_1=1;P0_0=1;break;
}
P3=shuzi[num];
delay(1);
}
/**********************************定时器函数 延时10us*************************************/
void Delay10us()
{
TMOD |= 0x01;//16位定时器/计数器
TH0 = 0xFF;//赋初值
TL0 = 0xF6;//赋初值
TR0 = 1;//启动
while(!TF0);//溢出
TF0 = 0;//清溢出
}
/******************************************算距离函数***************************************/
float GetDistance(unsigned int time)
{
float distance;
distance = (float)time * 0.017;//cm 距离=高电平时间×声速/2 0.017cm/us
return distance;//将距离返回主函数
}
/******************************************测时间函数***************************************/
unsigned int RunOnce()
{
unsigned int time;
/******************发送10us高电平信号*************/
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
/**************等待高电平信号接收*****************/
while(!Echo);
/*********T0清0重新计数(高电平持续时间)*********/
TH0 = 0;
TL0 = 0;
TR0 = 1;
/*********等待高电平信号接收结束******************/
while(Echo);
/*******************关闭T0计数********************/
TR0 = 0;
/**********高电平时间赋值,单位us*****************/
time = TH0*256 + TL0;
TH0 = 0;
TL0 = 0;
return time;
}
/**************************************动态数码管显示结果***********************************/
void xianshi(int d)
{
int k=8,m;
while(d!=0)
{
m=(d%10);//在数码管上显示个位,从后往前显示
shumaguan(k,m);
k--;//数码管向前移位
d=d/10;
}
}
/******************************************主函数***************************************/
void main()
{
unsigned int time = 0;
float distance;
while(1)
{
time = RunOnce();//传感器接收到高电平的时间
distance = GetDistance(time);
xianshi(distance);
}
}
到了这里,关于【C语言】51单片机超声波测距(实作 非仿真)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!