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