《检测技术》课程设计
题目:超声波测距 姓名: 余磊,王子彦,倪晨轩 学号:031110413,031110415,031110418
学院:自动化学院 专业:自动化 班级:0311104 指导教师:张玲
日期:2014-06-18
1、课题背景介绍
本课题要完成的任务为设计一个超声波测距系统,设计超声波发射和接收系统,利用单片机进行计算和显示。同时要有环境温度测量,用来补偿计算及修正声速。
常用的超声波测距的方法有
1.相位检测法,通过测量返回波与发射波之间相差多少相位,判断距离,这种方法检测精度高,但是检测距离短,实现电路复杂。
2.声波幅值检测法,通过检测回波的幅值大小来判断距离,这种方法实现简单,成本较低,但是测量不精确。
3.渡越时间检测法,通过回波的返回延时来判断距离,这种方法实现较简单,成本不高,精度较高,所以本课题采用的方案为渡越时间检测法 2、方案设计 2.1传感器选择
本课题考虑到超声波传感器的分类,选择了一种收发一体的超声波测距传感器HC-SR04,其结构原理图如图1所示。
图1:HC-SR04超声波传感器原理图
图中,STC11芯片为一个微控制器用于控制超声波信号的发送和探测超声波信号。MAX232芯片为单电源电平转换芯片用来升压驱动超声波探头。TL074芯片是一个低噪声运放,用来放大接收信号。工作过程:当Tirg收到一个宽度超过10uS的高脉冲后,STC11芯片控制P53脚置低,然后通过P51和P52脚输出40KHz脉冲信号,该信号通过MAX232放大后驱动超声波探头发出超声波,信号发送完成
后将P67置高,P61脚置低,等待回波。当超声波接收探头接受到回波后,接收放大电路便输出放大后的接收信号到TL074的第一通道同相输入口,是Q2导通,P60此时变为低,STC11检测到这个变化便将Echo脚置低,表示接受到了回波。Echo口的高电平持续时间即为超声波发送到接收的延迟时间,通过单片机定时器测量这个时间,即可算出被测物和探头之间的距离
本课题选用的温度传感器为DS18B20温度传感器,这是一种常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20的连线图如图
2
图2:DS18B20连线图
本课题选用的显示仪器为LCD1602液晶,这是一种工业字符型液晶,能够同时显示16x02即32个字符,能够满足超声波测距仪的显示要求。其连线图如图3所示。
图3:LCD1602液晶连线图
2.2参数计算
1)声速计算公式
空气中的声速收到温度和大气压的影响,本课题设计的超声波测距仪只对温度引起的声速变化进行补偿。
使用DS18B20测得气温的摄氏度值,通过声速计算的经验公式
(2.1)
,T为摄氏度温标
可计算出当前声速,用于距离测量计算,其中
2)距离计算公式
本作品使用STC89C52单片机来测量回波延迟时间,使用的晶振频率为11.0592MHz,则计时器的计时精度为
(2.2)
当超声波传感器接收到回波时,得到16位计数器里面的值为x则距离的计算公式为
(2.3)
3)量程计算
本作品超声波测距仪的量程设计为0.1米到5米,但是考虑到超声波仪器的实际情况,其最小量程为2cm,最大量程在3-5米可调,调节最大量程是通过改变图1原理图中的R17来实现的,将R17调小,则可以获得较大的接收信号增益,最大测量距离也就越远。
4)分辨率
距离测量的分辨率为
,当气温为25摄氏度时,该超声波测距仪的分辨
率约为0.1毫米。实际使用中,考虑到测距的实际需要和单片机计算能力的限制,
本作品设计的超声波测距仪的分辨率为1厘米。
2.3系统结构图
系统结构图如图4所示
图4:系统结构图
2.4控制流程图 系统控制流程图如图5所示,本作品采用循环测量的方式,测量周期为1秒左右,每一秒测一次温度,测一次距离,温度值用于修正声速,从而得到实时精确的距离值。当超声波测距仪测量的距离超过量程后,超声波测距仪将会发出警报,并显示距离值为0。若收到回波信号,则将距离和温度显示在LCD上。
图5:控制流程图
2.5软件设计
本作品的程序使用C语言编写,源代码如下
#include #include
#include
#include
#define uchar unsigned char #define uint unsigned int
#define C0 33130 //0摄氏度时的声速//C=C0+0.606×T℃
#define PLUS_PER_DEG 0.606
sbit dula = P2^6;//段和位定义,防止数码管乱跳 sbit wela = P2^7;
sbit RS = P3^5; //LED写端口使能端,单片机的
T0口
sbit LCDEN = P3^4; //LED使能端口,单片机的T1口
sbit Tirg=P2^0; sbit Echo=P2^1; sbit fm=P2^3;
uchar table[] = "Temperature:"; uchar table1[]="Distance: m"; int tempValue=0;//温度值X100 double victor_100=C0;//声速X100 double distance_100=0;//距离X100 double percount=0; bit flag=1;
void delayUs()//微秒级延时 {
_nop_(); }
void delayxus(uchar x) { for(;x>0;x--);
}
void delayMs(uint a)//毫秒延时 {
uint i, j;
for(i = a; i > 0; i--) for(j = 100; j > 0; j--); }
/********************************1602*********************************/
void writeComm(uchar comm) {
RS = 0; P0 = comm; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); }
//写数据:RS=1, RW=0; void writeData(uchar dat) {
RS = 1; P0 = dat; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); }
void init() {
dula = wela = 0; writeComm(0x38); writeComm(0x0c); writeComm(0x06); writeComm(0x01); }
void writeString(uchar * str, uchar posx,bit posy) {
uchar i; uchar length=strlen(str);
writeComm(0x80+posx+posy*0x40);
for(i = 0; i
writeData(str[i]); } }
/********************************1602*********************************/
/*******************************DS18B20*******************************/ sbit ds = P2^2; void dsInit() {
unsigned int i;
ds = 0; i = 100; while(i>0) i--; ds = 1; i = 4; while(i>0) i--; }
void dsWait() {
unsigned int i; while(ds); while(~ds); i = 4;
while(i > 0) i--; }
bit readBit() {
unsigned int i; bit b; ds = 0; i++; ds = 1; i++; i++; b = ds; i = 8; while(i>0) i--; return b; }
unsigned char readByte() {
unsigned int i; unsigned char j, dat; dat = 0;
for(i=0; i
j = readBit();
dat = (j > 1); }
return dat; }
void writeByte(unsigned char dat) {
unsigned int i; unsigned char j; bit b;
for(j = 0; j
b = dat & 0x01; dat >>= 1;
if(b) {
ds = 0; i++; i++; ds = 1;
i = 8; while(i>0) i--; } else {
ds = 0;
i = 8; while(i>0) i--; ds = 1; i++; i++; } } }
void sendChangeCmd() {
dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0x44); }
void sendReadCmd() {
dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0xbe); }
int getTmpValue()
unsigned int tmpvalue; int value; float t;
unsigned char low, high; sendReadCmd();
low = readByte(); high = readByte();
tmpvalue = high; tmpvalue
value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5 return value; }
void display(int v,uchar posx,bit posy)//数字显示程序 {
unsigned char count;
unsigned char datas[] = {0, 0, 0, 0, 0}; unsigned int tmp = abs(v); datas[0] = tmp / 10000; datas[1] = tmp % 10000 / 1000; datas[2] = tmp % 1000 / 100; datas[3] = tmp % 100 / 10; datas[4] = tmp % 10;
writeComm(0x80+posx+posy*0x40);//设置显示起始地址
if(datas[0] != 0) {
writeData('0'+datas[0]); }
for(count = 1; count != 5; count++) {
writeData('0'+datas[count]); if(count == 2) {
writeData('.'); }
}
/*********************************DS18B20*******************************/
/********************************T0*************************************/ void T0init() { TMOD=0x11;//00010001定时器0工作方式1 //
TR0=1;
TL0=0x00;//初值为0x0000 TH0=0x00; //开终端 EA=1; ET0=1;
}
/********************************T0*************************************/
/******************************蜂鸣器 **********************************/ void alarm() { fm=0; delayMs(200); fm=1; P1=0x00;
}
/******************************蜂鸣器 **********************************/
/******************************HC-SR04**********************************/
void startHC()//启动超声波测距模块和定时器 { TL0=0x00; TH0=0x00; Tirg=1; delayxus(15); Tirg=0; }
void waitEcho()//等待回声,接受到回声后停止计数 {
}
void count()//根据计数值和温度修正计算距离 { }
victor_100=C0+tempValue*PLUS_PER_DEG; percount=victor_100*0.5425/1000000.0; P1=0xff; if(flag==1) { } else { } TH0=0; TL0=0;
flag=1;
alarm();//发出警报声表示测距失败 fm=1;
distance_100=0;
distance_100=(TH0*256+TL0)*percount; if((int)distance_100
if((int)distance_100>500) { }
alarm(); alarm();
TR0=1;
while(Echo&&flag); TR0=0;
*********************/
void main() {
init();
T0init();
sendChangeCmd();
writeString(table,0,0);
writeString(table1,0,1);
while(1) {
delayMs(800);//温度转换时间需要750ms以上,所以延时800毫秒
startHC(); waitEcho(); count();
display(tempValue,12,0);
display((int)distance_100,9,1); tempValue=getTmpValue(); sendChangeCmd();//温度转换
} }
//T0中断服务程序,在定时器溢出后将flag置0,表示测距失败
void T0_time() interrupt 1 { }
flag=0; TH0=0; TL0=0;
3、课设小结 本课题利用本学期所学有关传感器的知识,利用超声波传感器,温度传感器和单片机设计了一个带有温度补偿可以实时显示的超声波测距系统;利用51单片机开发板和相关资源,搭建了一个超声波测距仪实物,并且编程进行对其控制,实现了高精度测量距离并且实时显示的目标,达到了一定的实用效果。最终做出的实物如图6所示
图6:实物图
组员任务分配: 余磊:作品的设计和实物制作,报告的撰写。 王子彦:资料查找和作品实物测试,PPT制作 倪晨轩:资料查找,报告的修改完善,PPT修改和完善
11
《检测技术》课程设计
题目:超声波测距 姓名: 余磊,王子彦,倪晨轩 学号:031110413,031110415,031110418
学院:自动化学院 专业:自动化 班级:0311104 指导教师:张玲
日期:2014-06-18
1、课题背景介绍
本课题要完成的任务为设计一个超声波测距系统,设计超声波发射和接收系统,利用单片机进行计算和显示。同时要有环境温度测量,用来补偿计算及修正声速。
常用的超声波测距的方法有
1.相位检测法,通过测量返回波与发射波之间相差多少相位,判断距离,这种方法检测精度高,但是检测距离短,实现电路复杂。
2.声波幅值检测法,通过检测回波的幅值大小来判断距离,这种方法实现简单,成本较低,但是测量不精确。
3.渡越时间检测法,通过回波的返回延时来判断距离,这种方法实现较简单,成本不高,精度较高,所以本课题采用的方案为渡越时间检测法 2、方案设计 2.1传感器选择
本课题考虑到超声波传感器的分类,选择了一种收发一体的超声波测距传感器HC-SR04,其结构原理图如图1所示。
图1:HC-SR04超声波传感器原理图
图中,STC11芯片为一个微控制器用于控制超声波信号的发送和探测超声波信号。MAX232芯片为单电源电平转换芯片用来升压驱动超声波探头。TL074芯片是一个低噪声运放,用来放大接收信号。工作过程:当Tirg收到一个宽度超过10uS的高脉冲后,STC11芯片控制P53脚置低,然后通过P51和P52脚输出40KHz脉冲信号,该信号通过MAX232放大后驱动超声波探头发出超声波,信号发送完成
后将P67置高,P61脚置低,等待回波。当超声波接收探头接受到回波后,接收放大电路便输出放大后的接收信号到TL074的第一通道同相输入口,是Q2导通,P60此时变为低,STC11检测到这个变化便将Echo脚置低,表示接受到了回波。Echo口的高电平持续时间即为超声波发送到接收的延迟时间,通过单片机定时器测量这个时间,即可算出被测物和探头之间的距离
本课题选用的温度传感器为DS18B20温度传感器,这是一种常用的温度传感器,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20的连线图如图
2
图2:DS18B20连线图
本课题选用的显示仪器为LCD1602液晶,这是一种工业字符型液晶,能够同时显示16x02即32个字符,能够满足超声波测距仪的显示要求。其连线图如图3所示。
图3:LCD1602液晶连线图
2.2参数计算
1)声速计算公式
空气中的声速收到温度和大气压的影响,本课题设计的超声波测距仪只对温度引起的声速变化进行补偿。
使用DS18B20测得气温的摄氏度值,通过声速计算的经验公式
(2.1)
,T为摄氏度温标
可计算出当前声速,用于距离测量计算,其中
2)距离计算公式
本作品使用STC89C52单片机来测量回波延迟时间,使用的晶振频率为11.0592MHz,则计时器的计时精度为
(2.2)
当超声波传感器接收到回波时,得到16位计数器里面的值为x则距离的计算公式为
(2.3)
3)量程计算
本作品超声波测距仪的量程设计为0.1米到5米,但是考虑到超声波仪器的实际情况,其最小量程为2cm,最大量程在3-5米可调,调节最大量程是通过改变图1原理图中的R17来实现的,将R17调小,则可以获得较大的接收信号增益,最大测量距离也就越远。
4)分辨率
距离测量的分辨率为
,当气温为25摄氏度时,该超声波测距仪的分辨
率约为0.1毫米。实际使用中,考虑到测距的实际需要和单片机计算能力的限制,
本作品设计的超声波测距仪的分辨率为1厘米。
2.3系统结构图
系统结构图如图4所示
图4:系统结构图
2.4控制流程图 系统控制流程图如图5所示,本作品采用循环测量的方式,测量周期为1秒左右,每一秒测一次温度,测一次距离,温度值用于修正声速,从而得到实时精确的距离值。当超声波测距仪测量的距离超过量程后,超声波测距仪将会发出警报,并显示距离值为0。若收到回波信号,则将距离和温度显示在LCD上。
图5:控制流程图
2.5软件设计
本作品的程序使用C语言编写,源代码如下
#include #include
#include
#include
#define uchar unsigned char #define uint unsigned int
#define C0 33130 //0摄氏度时的声速//C=C0+0.606×T℃
#define PLUS_PER_DEG 0.606
sbit dula = P2^6;//段和位定义,防止数码管乱跳 sbit wela = P2^7;
sbit RS = P3^5; //LED写端口使能端,单片机的
T0口
sbit LCDEN = P3^4; //LED使能端口,单片机的T1口
sbit Tirg=P2^0; sbit Echo=P2^1; sbit fm=P2^3;
uchar table[] = "Temperature:"; uchar table1[]="Distance: m"; int tempValue=0;//温度值X100 double victor_100=C0;//声速X100 double distance_100=0;//距离X100 double percount=0; bit flag=1;
void delayUs()//微秒级延时 {
_nop_(); }
void delayxus(uchar x) { for(;x>0;x--);
}
void delayMs(uint a)//毫秒延时 {
uint i, j;
for(i = a; i > 0; i--) for(j = 100; j > 0; j--); }
/********************************1602*********************************/
void writeComm(uchar comm) {
RS = 0; P0 = comm; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); }
//写数据:RS=1, RW=0; void writeData(uchar dat) {
RS = 1; P0 = dat; LCDEN = 1; delayUs(); LCDEN = 0; delayMs(1); }
void init() {
dula = wela = 0; writeComm(0x38); writeComm(0x0c); writeComm(0x06); writeComm(0x01); }
void writeString(uchar * str, uchar posx,bit posy) {
uchar i; uchar length=strlen(str);
writeComm(0x80+posx+posy*0x40);
for(i = 0; i
writeData(str[i]); } }
/********************************1602*********************************/
/*******************************DS18B20*******************************/ sbit ds = P2^2; void dsInit() {
unsigned int i;
ds = 0; i = 100; while(i>0) i--; ds = 1; i = 4; while(i>0) i--; }
void dsWait() {
unsigned int i; while(ds); while(~ds); i = 4;
while(i > 0) i--; }
bit readBit() {
unsigned int i; bit b; ds = 0; i++; ds = 1; i++; i++; b = ds; i = 8; while(i>0) i--; return b; }
unsigned char readByte() {
unsigned int i; unsigned char j, dat; dat = 0;
for(i=0; i
j = readBit();
dat = (j > 1); }
return dat; }
void writeByte(unsigned char dat) {
unsigned int i; unsigned char j; bit b;
for(j = 0; j
b = dat & 0x01; dat >>= 1;
if(b) {
ds = 0; i++; i++; ds = 1;
i = 8; while(i>0) i--; } else {
ds = 0;
i = 8; while(i>0) i--; ds = 1; i++; i++; } } }
void sendChangeCmd() {
dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0x44); }
void sendReadCmd() {
dsInit(); dsWait(); delayMs(1); writeByte(0xcc); writeByte(0xbe); }
int getTmpValue()
unsigned int tmpvalue; int value; float t;
unsigned char low, high; sendReadCmd();
low = readByte(); high = readByte();
tmpvalue = high; tmpvalue
value = t * 100 + (value > 0 ? 0.5 : -0.5); //大于0加0.5, 小于0减0.5 return value; }
void display(int v,uchar posx,bit posy)//数字显示程序 {
unsigned char count;
unsigned char datas[] = {0, 0, 0, 0, 0}; unsigned int tmp = abs(v); datas[0] = tmp / 10000; datas[1] = tmp % 10000 / 1000; datas[2] = tmp % 1000 / 100; datas[3] = tmp % 100 / 10; datas[4] = tmp % 10;
writeComm(0x80+posx+posy*0x40);//设置显示起始地址
if(datas[0] != 0) {
writeData('0'+datas[0]); }
for(count = 1; count != 5; count++) {
writeData('0'+datas[count]); if(count == 2) {
writeData('.'); }
}
/*********************************DS18B20*******************************/
/********************************T0*************************************/ void T0init() { TMOD=0x11;//00010001定时器0工作方式1 //
TR0=1;
TL0=0x00;//初值为0x0000 TH0=0x00; //开终端 EA=1; ET0=1;
}
/********************************T0*************************************/
/******************************蜂鸣器 **********************************/ void alarm() { fm=0; delayMs(200); fm=1; P1=0x00;
}
/******************************蜂鸣器 **********************************/
/******************************HC-SR04**********************************/
void startHC()//启动超声波测距模块和定时器 { TL0=0x00; TH0=0x00; Tirg=1; delayxus(15); Tirg=0; }
void waitEcho()//等待回声,接受到回声后停止计数 {
}
void count()//根据计数值和温度修正计算距离 { }
victor_100=C0+tempValue*PLUS_PER_DEG; percount=victor_100*0.5425/1000000.0; P1=0xff; if(flag==1) { } else { } TH0=0; TL0=0;
flag=1;
alarm();//发出警报声表示测距失败 fm=1;
distance_100=0;
distance_100=(TH0*256+TL0)*percount; if((int)distance_100
if((int)distance_100>500) { }
alarm(); alarm();
TR0=1;
while(Echo&&flag); TR0=0;
*********************/
void main() {
init();
T0init();
sendChangeCmd();
writeString(table,0,0);
writeString(table1,0,1);
while(1) {
delayMs(800);//温度转换时间需要750ms以上,所以延时800毫秒
startHC(); waitEcho(); count();
display(tempValue,12,0);
display((int)distance_100,9,1); tempValue=getTmpValue(); sendChangeCmd();//温度转换
} }
//T0中断服务程序,在定时器溢出后将flag置0,表示测距失败
void T0_time() interrupt 1 { }
flag=0; TH0=0; TL0=0;
3、课设小结 本课题利用本学期所学有关传感器的知识,利用超声波传感器,温度传感器和单片机设计了一个带有温度补偿可以实时显示的超声波测距系统;利用51单片机开发板和相关资源,搭建了一个超声波测距仪实物,并且编程进行对其控制,实现了高精度测量距离并且实时显示的目标,达到了一定的实用效果。最终做出的实物如图6所示
图6:实物图
组员任务分配: 余磊:作品的设计和实物制作,报告的撰写。 王子彦:资料查找和作品实物测试,PPT制作 倪晨轩:资料查找,报告的修改完善,PPT修改和完善
11