程序的实现思路
首先单片机给超声波模块的Trig 引脚一个10us的高电平使其发射声波,同时开始打开定时器记录 Echo 引脚高电平的持续时间。因为音速是340m/s,所以 距离 =( (340m/s)* 时间 ) / 2
补充知识:
1、如何计算定时时间
51单片机的定时器有一个计脉冲数的寄存器,当我们打开定时器时这个寄存器的值就会每过一个机器周期后自加一,直到溢出(值大于65535)时定时器便会产生中断信号。而这个机器周期与使用的晶振频率有关。( 1M=1*10^6 )
一个机器周期的时间为:t=1∗12/fosc (fosc为晶振频率)
2、如何根据定时的时间计算出距离
首先知道速度和运动时间那么,距离 =( 速度* 时间 )
而我们测量的是声波发射出去后碰撞障碍物反射回来的时间此时声波已经走过了两遍我们要测量的距离,所以要除与2,距离 =( 速度* 时间 ) / 2
然后要做的就是单位换算,1m = 1*10^2cm、1s = 1*10^6us
示例(单位为cm)
S = t * 340*10^2 / 2 cm
#include <reg52.h>
//定义数码管的位选引脚
sbit wei_1 = P1^0;
sbit wei_2 = P1^1;
sbit wei_3 = P1^2;
sbit wei_4 = P1^3;
//定义超声波引脚
sbit Trig = P1^6;//发送波端口
sbit Echo = P1^7;//接收端口
//共阴极数码管段码0~F
unsigned char code smg[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};
void smg_saomiao(unsigned char weu,unsigned char dat);//声明数码管扫描函数
void delay_ms(unsigned int i); //声明延时函数
void startHC(void); //声明触发超声波传感器函数
void main(void)
{
float time=0.0,dis=0.0;
int num=0;
//选择定时器0、工作模式为1,初始值设定0开始数数,先不开始数数
TMOD &= 0xf0;
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0=0; //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
TL0=0;
TR0=0; //关闭定时器
while(1)
{
//超声波测距频率约10Hz,既100ms测量一次
if(num>14)
{
startHC();//发射声波
while(Echo==0);//等待模块发射声波
TR0=1; //打开定时器开始计时
while(Echo==1 && TF0==0);//等待模块接收碰撞障碍物后反射回来的声波
TR0=0; //关闭定时器停止计时
//计算出中间经过多少时间(晶振为11.0592Mhz的计数脉冲时间单位为1.085us,12Mhz为1us)
time = (float)(TH0 * 256.0 + TL0)*1.085; //us为单位
//距离 = 速度(340m/s)* 时间/2
dis = (float)time * 0.017;//计算得出单位为CM
num=0;//将计数变量清零
TH0=0;//将定时器的计数值清零
TL0=0;//将定时器的计数值清零
}
num++;
//扫描一遍数码管约7ms,7*14=98 约100ms
smg_saomiao(1,16);
smg_saomiao(2,(int)dis/100);
smg_saomiao(3,(int)dis%100/10);
smg_saomiao(4,(int)dis%10);
}
}
/****************************************************************
* 函 数 名 : Delay10us
* 函数功能 : 延迟10us
* 参数 : 无
* 返回值 : 无
******************************************************************/
void Delay10us(void) //@11.0592MHz
{
unsigned char i;
i = 3;
while (--i);
}
/****************************************************************
* 函 数 名 : startHC
* 函数功能 : 触发超声波传感器发出声波
* 参数 : 无
* 返回值 : 无
******************************************************************/
void startHC(void)
{
//发送触发信号
Trig = 0;
Trig = 1;
Delay10us();
Trig = 0;
}
/****************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时1ms
*参数i : 需要延时的毫秒数
*返回值 : 无
******************************************************************/
void delay_ms(unsigned int i)
{
unsigned int n;
while(i--)
for(n=0;n<110;n++);
}
/****************************************************************
* 函 数 名 : smg_saomiao
* 函数功能 : 驱动4位的共阴数码管
*参数wei : 选择要点亮的那一位数码管(1~4)
*参数dat : 显示的段码内容( 0~15 ——> 0~F)
*返回值 : 无
******************************************************************/
void smg_saomiao(unsigned char wei,unsigned char dat)
{
//判断要点亮哪一位数码管
if(wei ==1)
{
wei_1 = 0;
wei_2 = 1;
wei_3 = 1;
wei_4 = 1;
}else if(wei ==2)
{
wei_1 = 1;
wei_2 = 0;
wei_3 = 1;
wei_4 = 1;
}else if(wei ==3)
{
wei_1 = 1;
wei_2 = 1;
wei_3 = 0;
wei_4 = 1;
}else if(wei ==4)
{
wei_1 = 1;
wei_2 = 1;
wei_3 = 1;
wei_4 = 0;
}
P0 = smg[dat];//显示该位数码管的段码内容
delay_ms(3);//延时3-5ms
P0 = 0;//熄灭所有段码,即消影
}
|