超声波测距

前言

在写蓝桥杯中的超声波测距模块时,总是会出现很多问题。如:显示的值乱跳,不稳定,测得距离较近等。在这里我将对一些问题的解决办法提供给大家参考,超声波的原理这里不再赘述,文章最后我将给大家提供我自己写的超声波程序供大家参考。

问题一

显示的距离值一直在跳动,不稳定。

显示的距离值是通过TH1和TL1的值来确定的,一直跳变说明这两个的值发生改变了,解决思路就是确定TH1,TL1的值在每次程序运行的过程中不会改变。

因此,我们要在定时器初始化的时候确定TH1,TL1的值,在每次测距程序运行完成后刷新TH1,TL1的值。

参考取值程序

void InitTimer()//配置T0和T1
{
	TMOD=0X00;
	TH0=(65536-2000)/255;
	TL0=(65536-2000)%255;
	TH1=0;
	TL1=0;
	ET0=1;
	TR0=1;
	EA=1;
}

void meaure()
{
	unsigned int time;
	SEND(); //发送超声波的程序 
	TR1=1;
	TF1=0;	
	while((RX==1)&&(TF1==0));//当接收到超声波或者定时器溢出了退出循环
	TR1=0;	
	if(TF1==1)
	{
		TF1=0;
		distance=999;
	}
	else
	{
		time=TH1;
		time=(time << 8) | TL1;
		distance= (uint)(time*0.017);
	}
	//即使更新TH1,TL1的值。.
	TH1=0;
	TL1=0;	
}

问题二

显示的距离值比较小

显示的距离值和超声波接收的时间有关,接收的时间和超声波的频率有关,所以出现距离值过近的问题可以通过修改发送超声波的频率来解决。

参考历程

void SEND()
{
	uchar i=8;
	do
	{
		TX=1;
		Delay12us(); //通过添加空指令来改变超声波的频率
		_nop_();
		_nop_();
		_nop_();
		TX=0;
		Delay12us();
		_nop_();
		_nop_();
		_nop_();
	}while(i--);
}

参考历程

#include "stc15f2k60s2.h"
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int
sbit TX=P1^0;
sbit RX=P1^1;

void meaure();
void Dis_SEG();	
void InitTimer();
uchar code SEG_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
uchar SEG_buf[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};

uint distance=0;

void Delay400ms()		//@12.000MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 19;
	j = 62;
	k = 43;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

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

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

void main()
{
	InitTimer();
	while(1)
	{		
		meaure();
		Dis_SEG();
		Delay400ms(); //刷新的次数不用太快,3-4HZ即可
	}
}

void hc138(uchar n)
{
	switch(n)
	{
		case 4: P2= (P2&0x1f) | 0x80;
			break;
		case 5: P2= (P2&0x1f) | 0xa0;
			break;
		case 6: P2= (P2&0x1f) | 0xc0;
			break;
		case 7: P2= (P2&0x1f) | 0xe0;
			break;
	}

}

void SEG_bit(uchar pos,uchar value)
{
	hc138(6);
	P0= 0x01 << pos;
	hc138(7);
	P0=value;
	P2 &= 0x1f;
}

void SEND()
{
	uchar i=8;
	do
	{
		TX=1;
		Delay12us();
		_nop_();
    	_nop_();
		_nop_();
		TX=0;
		Delay12us();
		_nop_();
		_nop_();
		_nop_();
	}while(i--);
	
}

void meaure()
{
		uint time;
		SEND();
		TR1=1;
		TF1=0;	
		while((RX==1)&&(TF1==0));
		TR1=0;
			
		if(TF1==1)
		{
			TF1=0;
			distance=999;
		}
		else
		{
			time=TH1;
			time=(time << 8) | TL1;
			distance= (uint)(time*0.017);
		}
	
		TH1=0;
		TL1=0;	
	
}

void InitTimer()
{
	TMOD=0X00;
	TH0=(65536-2000)/255;
	TL0=(65536-2000)%255;
	TH1=0;
	TL1=0;
	ET0=1;
	TR0=1;
	EA=1;	
}

void Dis_SEG()
{
	SEG_buf[5]=SEG_duan[distance/100];
	SEG_buf[6]=SEG_duan[(distance/10)%10];
	SEG_buf[7]=SEG_duan[distance%10];
}

void Timer0() interrupt 1
{
	static uchar i=0;
	
	SEG_bit(i,SEG_buf[i]);
	i++;
	i &= 0x07;
	
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值