标题:
单片机超声波测距不到一米,超出50厘米就不准了,附源码
[打印本页]
作者:
1021550891
时间:
2018-4-26 15:58
标题:
单片机超声波测距不到一米,超出50厘米就不准了,附源码
超声波测距不到一米,超出50厘米就不准了
主程序
#include "Ultrasonic.h"
/*软件延时,延时时间(t*10)us*/
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/* 获取测量数据,返回值:以毫米位单位的距离值 */
unsigned int GetDistance()
{
float time;
float result;
TH1 = 0; //定时器1清零,准备本次测距计数
TL1 = 0;
Trig = 1; //Trig输出高电平
DelayX10us(2); //延时20us
Trig = 0; //Trig输出低电平,至此产生一个20us的脉冲信号以启动超声波模块
while(!Echo); //等待回波信号,回波信号自动使能T1计数
while(Echo); //等待回波信号结束,T1同时自动停止
if (TF1 == 1) //TF1为1时说明定时器溢出了
{
TF1 = 0; //清除标志位
time = 65535; //溢出时,直接设置为最大计数值
}
else
{
time = TH1*256 + TL1; //未溢出时,读取其实际计数值
}
time = time * (12/11.0592) / 2; //将计数周期转换为实际时间(us);超声波测得的是来回距离,需要除以2得到单程距离所对应的时间
result = (time/1000000) * 340; // time(s)*速度 = 距离 ,340为声波在空气中的传播速度(m/s)
if (result > 4.0) //判断是否超出模块的测量范围
{
result = 4.0; //超出上限4m则设置为4m
}
else if (result < 0.02)
{
result = 0.02; //低于下限0.02m则设置为0.02m
}
return (unsigned int)(result*1000); //以无符号整形数返回测量结果,乘1000使其单位变为毫米
}
/*初始化超声波模块*/
void InitUltrasonic()
{
TMOD &= 0x0f;
TMOD |= 0x90; //设置T1为方式1,GATE=1启用门控模式;
TH1 = 0;
TL1 = 0;
ET1 = 0; //关闭T0中断
TR1 = 1; //使能定时器,由于使用GATE位控制定时器启停,所以定时器必须打开,启停将由外部信号触发 详情参考 <手把手将你学51单片机> P59
Trig = 0; //拉低模块触发引脚
}
#define _LCD1602_C
#include "Lcd1602.h"
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示RAM的地址
{
addr = 0x00 + x; //第一行字符地址从0x00起始
}
else
{
addr = 0x40 + x; //第二行字符地址从0x40起始
}
LcdWriteCmd(addr | 0x80); //设置RAM地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,str-字符串指针 */
void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str)
{
LcdSetCursor(x, y); //设置起始地址
while (*str != '\0') //连续写入字符串数据,直到检测到结束符
{
LcdWriteDat(*str++);
}
}
/* 初始化1602液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}
#include "Ultrasonic.h"
/*软件延时,延时时间(t*10)us*/
void DelayX10us(unsigned char t)
{
do {
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
} while (--t);
}
/* 获取测量数据,返回值:以毫米位单位的距离值 */
unsigned int GetDistance()
{
float time;
float result;
TH1 = 0; //定时器1清零,准备本次测距计数
TL1 = 0;
Trig = 1; //Trig输出高电平
DelayX10us(2); //延时20us
Trig = 0; //Trig输出低电平,至此产生一个20us的脉冲信号以启动超声波模块
while(!Echo); //等待回波信号,回波信号自动使能T1计数
while(Echo); //等待回波信号结束,T1同时自动停止
if (TF1 == 1) //TF1为1时说明定时器溢出了
{
TF1 = 0; //清除标志位
time = 65535; //溢出时,直接设置为最大计数值
}
else
{
time = TH1*256 + TL1; //未溢出时,读取其实际计数值
}
time = time * (12/11.0592) / 2; //将计数周期转换为实际时间(us);超声波测得的是来回距离,需要除以2得到单程距离所对应的时间
result = (time/1000000) * 340; // time(s)*速度 = 距离 ,340为声波在空气中的传播速度(m/s)
if (result > 4.0) //判断是否超出模块的测量范围
{
result = 4.0; //超出上限4m则设置为4m
}
else if (result < 0.02)
{
result = 0.02; //低于下限0.02m则设置为0.02m
}
return (unsigned int)(result*1000); //以无符号整形数返回测量结果,乘1000使其单位变为毫米
}
/*初始化超声波模块*/
void InitUltrasonic()
{
TMOD &= 0x0f;
TMOD |= 0x90; //设置T1为方式1,GATE=1启用门控模式;
TH1 = 0;
TL1 = 0;
ET1 = 0; //关闭T0中断
TR1 = 1; //使能定时器,由于使用GATE位控制定时器启停,所以定时器必须打开,启停将由外部信号触发 详情参考 <手把手将你学51单片机> P59
Trig = 0; //拉低模块触发引脚
}
复制代码
作者:
wulin
时间:
2018-4-26 20:57
这种低成本玩艺本来就是练练手的,别指望有多完美。要想性能好就买工业级的产品。
作者:
zl2168
时间:
2018-4-26 22:41
不是因为“低成本玩艺”,而是程序有问题。
作者:
zzzy
时间:
2018-4-26 23:50
没猜错的话,超过50厘米是因为定时器溢出了,建议你用双定时器,开始测量然后到收到回波,通过比较器得到精确计数,然后得到时间来算距离。
作者:
1021550891
时间:
2018-4-28 12:10
zzzy 发表于 2018-4-26 23:50
没猜错的话,超过50厘米是因为定时器溢出了,建议你用双定时器,开始测量然后到收到回波,通过比较器得到精 ...
能不能说的再清楚点
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1