蓝桥杯单片机速成7-超声波测距

目录

一.简介

二、超声波实现

1.计算公式

2.实现原理

三、实际使用

一.简介


在蓝桥杯“单片机设计与开发”比赛中,超声波测距是一直以来都是国赛中重要的考点,几乎每届必考。虽然省赛还没有考过,但也不能排除以后不考,它和其他的外设模块不同,没有底层驱动代码提供,得自己来写实现代码

 在蓝桥杯单片机的竞赛综合平台CT107D中,超声波模块的TX引脚接到单片机的P1.0端口,RX引脚接到单片机的P1.1端口。设计程序,进行超声波测距,最大测量范围约140cm

基本原理:想必大家在高中物理做过超声波测距的题

超声波发射模块向某一方向发射超声波,在发射时刻的同时开始计时,超声波在空气中传播,途中碰到障碍物就立即返回来,超声波接收器收到反射波就立即停止计时

二、超声波实现

1.计算公式

距离=声速*总时间/2

最大测量范围约140cm

2.实现原理

1.产生8个或10个频率为40KHZ,占空比为50%的方波信号,通过TX引脚发送出去(1/40 000 = 25us,25/2=12.5us,所以TX电平翻转时间为12us即可)

2.启动定时器,直到RX引脚接收到方波信号或者计时器计数溢出后关闭定时器

3.判断导致定时器停止的原因

        若是因为定时器溢出而导致的停止计数,就说明超出了测量距离,可以就按变量最大的值255(我们定义的是u8),也可以通过其他方式表示

        若是因为RX=0(接收到方波时RX=0)而停止的,就进行距离测量

        dis = v*t/2,v=340m/s = 34000cm/s = 0.034cm/us
        t 的单位是us,所以dis = t*v/2 = t*0.017

4.测量完一次就清零计数值

代码实现:

sbit TX = P1^0;
sbit RX = P1^1;

void Delay12us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	_nop_();
	i = 30;
	while (--i);
}


u8 Sonic_Measure()
{
	u8 i,dis;
	for(i=0;i<10;i++)//产生8个或10个方波信号
	{
		TX = 1;
		Delay12us();
		TX = 0;
		Delay12us();
	}
	TR0 = 1;//开启定时器
	while(RX == 1  && TF0 == 0);//接收到时RX = 0
	TR0 = 0;//关闭定时器
	
	if(TF0 == 1)//定时器溢出
	{
		TF0 = 0;
		dis = 255;
	}
	else //定时器未溢出,就收到了
	{
		dis = (TH0*256+TL0)*0.017;
	}
	TH0 = 0;
	TL0 = 0;
	return dis;
}

上面的延时是用Delay实现的,难免有些误差,我们也可以直接使用定时器进行计时 

 

void Sonic_Timer1Init(void)		//12微秒@11.0592MHz,16位
{
	AUXR &= 0xBF;		//定时器时钟12T模式----->每过1us计数器+1
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x10;		//设置定时器模式
	TL1 = 0xF5;		//设置定时初值
	TH1 = 0xFF;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//定时器1停止计时
}

u8 Sonic_Measure()
{
	u8 i,dis;
	Sonic_Timer1Init();
	TX = 0; //先拉低,其实先拉高也行
	for(i=0;i<10;i++)	//产生40KHZ的方波信号,1/40KHZ = 0.025s = 25us
	{									//所以要产生占空比为50%的就是12.5us翻转一次
		TR1 = 1;				//要发送十个
		while(!TF1);    //计数器溢出 TF0 = 1,退出循环,溢出时是12us
		TF1 = 0;
		TX ^= 1;				//TX翻转一次,TX = 0,TX ^1 = 1,	TX = 1,TX ^ 1 = 0;
		Sonic_Timer1Init();//初始化,重装定时器值为12us
	}
	
	//开始测距
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//定时器1停止计时
	TL1 = 0;		//设置定时初值
	TH1 = 0;		//设置定时初值
	TR1 = 1; 		//定时器开始计时
	
	while(RX  && !TF1);//当接收到返回的超声波时RX = 0,退出循环,当定时器计数溢出TF1 = 1时退出循环
	TR1 = 0;//暂停计时
	
	if(TF1)//若定时器溢出了,即超声波还没有返回到接收头,那就给最大距离255
	{
		TF1 = 0;
		dis = 255;
	}
	else//接收到了,定时器未溢出,就计算距离
	{
		dis = (TH1*256+TL1)*0.017;//TH1为高八位,则真实际数值为TH1<<8即TH1*256
															//dis = v*t/2,v=340m/s = 34000cm/s = 0.034cm/us
															//t 的单位是us,所以dis = t*v/2 = t*0.017
	}
	//因为每次执行此函数,开头都有初始化定时器,所以这里不用再为下一次测距做准备了
	return dis;
}

三、实际使用

#include <STC15F2K60S2.H>
#include "intrins.h"
#include "csb.h"
#include "seg.h"

#define wan(x)		x/10000
#define qian(x)		x/1000%10
#define bai(x)		x/100%10
#define shi(x)		x/10%10
#define ge(x)		x%10

u8 csb_mea;

void main()
{
	All_Init();
	Timer0Init();	
	Sonic_Init();
	while(1)
	{		
       if(csb_f)
		{
		    csb_f=0;			
		    csb_mea = Sonic_Mea();
		    if(csb_mea<10)
		         seg_set(21,16,16,16,16,16,16,ge(csb_mea));	
		    else if(csb_mea<100)
		         seg_set(21,16,16,16,16,16,shi(csb_mea),ge(csb_mea));		
		    else
		         seg_set(21,16,16,16,16,bai(csb_mea),shi(csb_mea),ge(csb_mea));
		}    
	}
}



void Timer0_ISR()			interrupt 1
{
	seg_loop();
	count++;
	if(count % 300 == 0)csb_f = 1;
	count%=1000;
	
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值