单片机:随便解释下超声波时序图。有图的

单片机:随便解释下超声波时序图。有图的,第1张

这是一组完整的测试信号,触发信号告诉你测试开始,发出信号作为探测能量发射,回响信号是接收信号的结果。

作为系统会连续发射几组这样的信号,把接收信号平均结果作为显示,这样几组作为一个单元在系统内部不断工作,数据就会不断更新。

#include"reg52.h"

#include"intrins.h"

#define uchar unsigned char//无符号8位

#define uint unsigned int//无符号16位

#define ulong unsigned long//无符号32位

sbit K1=P1^0 //按下K1后,开始测距

sbit LEDRed=P1^1//测距指示灯,亮表示正在测距,灭表示测距完成

//sbit BEEP=P1^2 //报警测量超出范围

sbit Trig=P2^5 //HC-SR04触发信号输入

sbit Echo=P2^6 //HC-SR04回响信号输出

float xdata DistanceValue=0.0//测量的距离

float xdata SPEEDSOUND //声速

float xdata XTALTIME //单片机计数周期

uchar xdata stringBuf[6] //数值转字符串缓冲

//LCD1602提示信息

uchar code Prompts[][16]=

{

{"Measure Distance"}, //测量距离

{"- Out of Range -"}, //超出测量范围

{"MAX range 400cm "}, //测距最大值400cm

{"MIN range 2cm "}, //测距最小值2cm

{""}, //清屏

{" Press K1 Start "} //按键开始测量

}

uchar xdata DistanceText[]="Range: " //测量结果字符串

uchar xdata TemperatureText[]="Temperature:"//测量温度值

extern void LCD_Initialize() //LCD初始化

extern void LCD_Display_String(uchar *, uchar)//字符串显示

extern void ReadTemperatureFromDS18B20() //从DS18B20读取温度值

extern int xdata CurTempInteger

//毫秒延时函数

void DelayMS(uint ms)

//20微秒延时函数

void Delay20us()

//HCSR04初始化

void HCSR04_Initialize()

//测量距离

float MeasuringDistance()

//测距的数值排序求平均

float DistanceStatistics()

//输出距离值到LCD1602上

void DisplayDistanceValue(float dat)

//将无符号的整数转成字符串,返回字符串长度,不包括'\0'结束符

uchar UnsigedIntToString(uint value)

//蜂鸣器

//void Beep(uchar time)

//显示温度值

void DisplayTemperatureValue()

void main()

{

LCD_Initialize()//LCD1602初始化

LCD_Display_String(Prompts[0],0x00)

LCD_Display_String(Prompts[5],0x40)

ReadTemperatureFromDS18B20() //测温度

HCSR04_Initialize()//HC-SR04初始化

while(1)

{

if(K1==0)

{

DelayMS(5)

if(K1==0)

{

//Beep(1)

while(K1==0)

LEDRed=0

ReadTemperatureFromDS18B20()//测温度

DisplayTemperatureValue()

if(CurTempInteger<14)

CurTempInteger=14

else if(CurTempInteger>26)

CurTempInteger=26

SPEEDSOUND=334.1+CurTempInteger*0.61//计算声速

DistanceValue=DistanceStatistics() //测距并返回距离值

DisplayDistanceValue(DistanceValue)//显示距离值

LEDRed=1

}

}

}

}

//测距的数值排序求平均

float DistanceStatistics()

{

uchar i,j

float disData[7],t

//连续测距

for(i=0i<7i++)

{

disData=MeasuringDistance()

DelayMS(80)

}

//排序

for(j=0j<=6j++)

{

for(i=0i<7-ji++)

{

if(disData>disData[i+1])

{

t=disData

disData=disData[i+1]

disData[i+1]=t

}

}

}

return (disData[2]+disData[3]+disData[4])/3

}

//测量距离

float MeasuringDistance()

{

//最大定时时间约65ms

TH0=0

TL0=0

//生成20us的脉冲宽度的触发信号

Trig=1

Delay20us()

Trig=0

//等待回响信号变高电平

while(!Echo)

TR0=1 //启动定时器0

//等待回响信号变低电平

while(Echo)

TR0=0 //关闭定时器0

//返回距离值(mm)

return (SPEEDSOUND*XTALTIME*((float)TH0*256+(float)TL0))/2000

}

//HCSR04初始化

void HCSR04_Initialize()

{

//计算单片机计数周期 晶振=11.953M 单位us

XTALTIME=12/11.953

//温度25度时声速的值

SPEEDSOUND=334.1+25*0.61

Trig=0

Echo=0

TMOD=0x01

}

//输出距离值到LCD1602上

void DisplayDistanceValue(float dat)

{

uchar i=0,j=0,len

uint value

value=(uint)dat

//范围检查大于4000mm和小于20mm都为超出测量范围

if(value>4000)

{

LCD_Display_String(Prompts[1],0x00)

LCD_Display_String(Prompts[2],0x40)

//Beep(2)

}

else if(value<20)

{

LCD_Display_String(Prompts[1],0x00)

LCD_Display_String(Prompts[3],0x40)

//Beep(2)

}

else

{

//将数值转换成字符串

len=UnsigedIntToString(value)

//保留1位小数

while(stringBuf!='\0')

{

if(len-j==1)

{

DistanceText[6+j]='.'

j++

}else

{

DistanceText[6+j]=stringBuf

i++

j++

}

}

DistanceText[6+j]='c'

j++

DistanceText[6+j]='m'

i=7+j

//剩余位置补空格

while(i<16)

{

DistanceText=' '

i++

}

//LCD_Display_String(Prompts[0],0x00)

LCD_Display_String(DistanceText,0x40)

}

}

//显示温度值

void DisplayTemperatureValue()

{

TemperatureText[13]=CurTempInteger/10+'0'

TemperatureText[14]=CurTempInteger+'0'

TemperatureText[15]='C'

LCD_Display_String(TemperatureText,0x00)

}

//将无符号的整数转成字符串,返回字符串长度

uchar UnsigedIntToString(uint value)

{

uchar i=0,t,length

//从个位开始转换

do

{

stringBuf='0'+value

value=value/10

i++

}while(value!=0)

length=i

//将字符串颠倒顺序

for(i=0i<(length/2)i++)

{

t=stringBuf

stringBuf=stringBuf[length-i-1]

stringBuf[length-i-1]=t

}

stringBuf[length]='\0'

return length

}

//蜂鸣器

//延时函数 毫秒 @12.000MHz

void DelayMS(uint ms)

{

uchar i, j

while(ms--)

{

_nop_()

i = 2

j = 239

do

{

while (--j)

}while (--i)

}

}

//延时函数 20微秒 @12.000MHz

void Delay20us()

{

uchar i

_nop_()

i = 7

while (--i)

}

//定时器0中断

void Timer0() interrupt 1

{

}

//DS18B20代码:

#include

#include

#define uchar unsigned char //无符号8位

#define uint unsigned int //无符号16位

//定义DS18B20端口DS18B20_DQ

sbit DS18B20_DQ = P2^7

//当前采集的温度值整数部分

int xdata CurTempInteger

//当前采集的温度值小数部分

int xdata CurTempDecimal

void Delayus(uint count)

{

while (--count)

}

uchar Reset_DS18B20()

{

uchar status

DS18B20_DQ=1

Delayus(1)

//开始复位过程

DS18B20_DQ=0 //数据线拉低

Delayus(100) //延时480us-960us

DS18B20_DQ=1 //数据线拉高

Delayus(10) //延时15us-60us

status=DS18B20_DQ//读取数据线上的状态

Delayus(120)

return status

}

void WriteByteToDS18B20(uchar dat)

{

uchar i

for(i=0i<8i++)

{

DS18B20_DQ=0

DS18B20_DQ=dat&0x01 //发送1位数据

Delayus(15) //延时60us以上

DS18B20_DQ=1 //释放总线,等待总线恢复

dat>>=1 //准备下一位数据

}

}

uchar ReadByteFromDS18B20()

{

uchar i,dat=0

for(i=0i<8i++)

{

DS18B20_DQ=0 //拉低总线,产生读信号

dat>>=1

DS18B20_DQ=1//释放总线,准备读1位数据

Delayus(2)//延时4us

if(DS18B20_DQ) dat|=0x80//合并每位数据

Delayus(15)//延时60us

DS18B20_DQ=1//拉高总线,准备读下1位数据

}

return dat

}

void ReadTemperatureFromDS18B20()

{

uchar flag=0//正负符号标志

//存储当前采集的温度值

uchar TempValue[]={0,0}

if(Reset_DS18B20())

{

CurTempInteger=255

CurTempDecimal=0

}

else

{

WriteByteToDS18B20(0xCC)//跳过ROM命令

WriteByteToDS18B20(0x44)//温度转换命令

Reset_DS18B20()//复位

WriteByteToDS18B20(0xCC)//跳过ROM命令

WriteByteToDS18B20(0xBE)//读取温度暂存器命令

TempValue[0]=ReadByteFromDS18B20()//先读低字节温度值

TempValue[1]=ReadByteFromDS18B20()//后读高字节温度值

Reset_DS18B20()//复位

//计算温度值

//先进行正温度与负温度判断,高5位全为1(0xF8)则为负数

if((TempValue[1]&0xF8)==0xF8)

{

//负温度计算:取反加1,低字节为0时,高字节取反加1,否则不需要。

TempValue[1]=~TempValue[1]

TempValue[0]=~TempValue[0]+1

if(TempValue[0]==0x00) TempValue[1]++

flag=1//负数标志

}

//将温度值分为整数和小数两部分存储(默认为12位精度)

CurTempInteger=((TempValue[1]&0x07)<<4)|((TempValue[0]&0xF0)>>4) if(flag) CurTempInteger=-CurTempInteger

CurTempDecimal=(TempValue[0]&0x0F)*625

}

}

//LCD1602程序代码:

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define Delay4us(){_nop_()_nop_()_nop_()_nop_()}

sbit LCD_RS=P2^0

sbit LCD_RW=P2^1

sbit LCD_EN=P2^2

void LCDDelay(uint ms)

{

uchar i, j

while(ms--)

{

_nop_()

i = 2

j = 239

do

{

while (--j)

}while (--i)

}

}

bit LCD_Busy_Check()

{

bit result

LCD_RS=0LCD_RW=1LCD_EN=1

Delay4us()

result=(bit)(P0&0x80)

LCD_EN=0

return result

}

void Write_LCD_Command(uchar cmd)

{

while(LCD_Busy_Check())

LCD_RS=0LCD_RW=0 LCD_EN=0_nop_()_nop_()

P0=cmdDelay4us()

LCD_EN=1Delay4us()LCD_EN=0

}

void Write_LCD_Data(uchar dat)

{

while(LCD_Busy_Check())

LCD_RS=1LCD_RW=0LCD_EN=0

P0=datDelay4us()

LCD_EN=1Delay4us()LCD_EN=0

}

void LCD_Set_POS(uchar pos)

{

Write_LCD_Command(pos|0x80)

}

void LCD_Initialize()

{

Write_LCD_Command(0x01)LCDDelay(5)

Write_LCD_Command(0x38)LCDDelay(5)

Write_LCD_Command(0x0C)LCDDelay(5)

Write_LCD_Command(0x06)LCDDelay(5)

}

void LCD_Display_String(uchar *str, uchar LineNo)

{

uchar k

LCD_Set_POS(LineNo)

for(k=0k<16k++)

{

Write_LCD_Data(str[k])

}

}

void LCD_Display_OneChar(uchar Dat, uchar X, uchar Y)

{

Y &= 0x01//限制Y不能大于1(2行,0-1)

X &= 0x0F //限制X不能大于15(16个字符,0-15)

if(Y) {X |= 0x40} //当要在第二行显示时地址码+0x40

X |= 0x80//算出指令码

Write_LCD_Command(X)

Write_LCD_Data(Dat)

}

摘要超声波测距器,可以应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于如液位、井深、管道长度的测量等场合。要求测量范围在0.10-5.00m,测量精度1cm,测量时与被测物体无直接接触,能够清晰稳定地显示测量结果。由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此在移动机器人的研制上也得到了广泛的应用。 关键词 单片机AT82S51超声波传感器测量距离 一、设计要求 设计一个超声波测距器,可以应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用于如液位、井深、管道长度的测量等场合。要求测量范围在0.10-3.00m,测量精度1cm,测量时与被测物体无直接接触,能够清晰稳定地显示测量结果。 二、设计思路 超声波传感器及其测距原理 超声波是指频率高于20KHz的机械波。为了以超声波作为检测手段,必须产生超生波和接收超声波。完成这种功能的装置就是超声波传感器,习惯上称为超声波换能器或超声波探头。超声波传感器有发送器和接收器,但一个超声波传感器也可具有发送和接收声波的双重作用。超声波传感器是利用压电效应的原理将电能和超声波相互转化,即在发射超声波的时候,将电能转换,发射超声波;而在收到回波的时候,则将超声振动转换成电信号。 超声波测距的原理一般采用渡越时间法TOF(timeofflight)。首先测出超声波从发射到遇到障碍物返回所经历的时间,再乘以超声波的速度就得到二倍的声源与障碍物之间的距离 测量距离的方法有很多种,短距离的可以用尺,远距离的有激光测距等,超声波测距适用于高精度的中长距离测量。因为超声波在标准空气中的传播速度为331.45米/秒,由单片机负责计时,单片机使用12.0M晶振,所以此系统的测量精度理论上可以达到毫米级。 由于超声波指向性强,能量消耗缓慢,在介质中传播距离远,因而超声波可以用于距离的测量。利用超声波检测距离,设计比较方便,计算处理也较简单,并且在测量精度方面也能达到要求。 超声波发生器可以分为两类:一类是用电气方式产生超声波,一类是用机械方式产生超声波。本课题属于近距离测量,可以采用常用的压电式超声波换能器来实现。 根据设计要求并综合各方面因素,可以采用AT89S51单片机作为主控制器,用动态扫描法实现LED数字显示,超声波驱动信号用单片机的定时器完成,超声波测距器的系统框图如下图所示: 超声波测距器系统设计框图 三、系统组成 硬件部分 主要由单片机系统及显示电路、超声波发射电路和超声波检测接收电路三部分组成。采用AT89S51来实现对CX20106A红外接收芯片和TCT40-10系列超声波转换模块的控制。单片机通过P1.0引脚经反相器来控制超声波的发送,然后单片机不停的检测INT0引脚,当INT0引脚的电平由高电平变为低电平时就认为超声波已经返回。计数器所计的数据就是超声波所经历的时间,通过换算就可以得到传感器与障碍物之间的距离。 软件部分 主要由主程序、超声波发生子程序、超声波接收中断程序及显示子程序等部分。 四、系统硬件电路设计 1.单片机系统及显示电路 单片机采用89S51或其兼容系列。采用12MHz高精度的晶振,以获得较稳定的时钟频率,减小测量误差。单片机用P1.0端口输出超声波转化器所需的40KHz方波信号,利用外中断0口检测超声波接受电路输出的返回信号。显示电路采用简单实用的4位共阳LED数码管,段码用74LS244驱动,位码用PNP三极管驱动。单片机系统及显示电路如下图所示 单片机及显示电路原理图 2.超声波发射电路原理图参考期刊如图所示: 超声波发射电路原理图 压电超声波转换器的功能:利用压电晶体谐振工作。内部结构上图所示,它有两个压电晶片和一个共振板。当它的两极外加脉冲信号,其频率等于压电晶片的固有振荡频率时,压电晶片将会发生共振,并带动共振板振动产生超声波,这时它就是一超声波发生器如没加电压,当共振板接受到超声波时,将压迫压电振荡器作振动,将机械能转换为电信号,这时它就成为超声波接受转换器。超声波发射转换器与接受转换器其结构稍有不同。 3.超声波检测接受电路 参考红外转化接收期刊的电路采用集成电路CX20106A,这是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控常用的载波频率38KHz与测距超声波频率40KHz较为接近,可以利用它作为超声波检测电路。实验证明其具有很高的灵敏度和较强的抗干扰能力。适当改变C4的大小,可改变接受电路的灵敏度和抗干扰能力。 超声波接收电路图 五、系统程序设计 超声波测距软件设计主要由主程序,超声波发射子程序,超声波接受中断程序及显示子程序组成。下面对超声波测距器的算法,主程序,超声波发射子程序和超声波接受中断程序逐一介绍。 1.超声波测距器的算法设计 下图示意了超声波测距的原理,即超声波发生器T在某一时刻发出的一个超声波信号,当超声波遇到被测物体后反射回来,就被超声波接收器R所接受。这样只要计算出发生信号到接受返回信号所用的时间,就可算出超声波发生器与反射物体的距离。 距离计算公式:d=s/2=(c*t)/2 *d为被测物与测距器的距离,s为声波的来回路程,c为声速,t为声波来回所用的时间 声速c与温度有关,如温度变化不大,则可认为声速是基本不变的。如果测距精度要求很高,则应通过温度补偿的方法加以校正。声速确定后,只要测得超声波往返时间,即可求得距离。在系统加入温度传感器来监测环境温度,可进行温度被偿。这里可以用DS18B20测量环境温度,根据不同的环境温度确定一声速提高测距的稳定性。为了增强系统的可靠性,应在软硬件上采用抗干扰措施。 不同温度下的超声波声速表 温度/ -30 -20 -10 0 10 20 30 100 声速c(m/s) 313 319 325 323 338 344 349 386 2.主程序 主程序首先对系统环境初始化,设置定时器T0工作模式为16位的定时计数器模式,置位总中断允许位EA并给显示端口P0和P2清0。然后调用超声波发生子程序送出一个超声波脉冲,为避免超声波从发射器直接传送到接收器引起的直接波触发,需延迟0.1ms(这也就是测距器会有一个最小可测距离的原因)后,才打开外中断0接收返回的超声波信号。由于采用12MHz的晶振,机器周期为1us,当主程序检测到接收成功的标志位后,将计数器T0中的数(即超声波来回所用的时间)按下式计算即可测得被测物体与测距仪之间的距离,设计时取20℃时的声速为344m/s则有: d=(C*T0)/2=172T0/10000cm(其中T0为计数器T0的计数值) 测出距离后结果将以十进制BCD码方式LED,然后再发超声波脉冲重复测量过程。主程序框图如下 3.超声波发生子程序和超声波接收中断程序 超声波发生子程序的作用是通过P1.0端口发送2个左右的超声波信号频率约40KHz的方波,脉冲宽度为12us左右,同时把计数器T0打开进行计时。超声波测距器主程序利用外中断0检测返回超声波信号,一旦接收到返回超声波信号(INT0引脚出现低电平),立即进入中断程序。进入该中断后就立即关闭计时器T0停止计时,并将测距成功标志字赋值1。如果当计时器溢出时还未检测到超声波返回信号,则定时器T0溢出中断将外中断0关闭,并将测距成功标志字赋值2以表示此次测距不成功。 六.软硬件调试及性能 超声波测距仪的制作和调试,其中超声波发射和接收采用Φ15的超声波换能器TCT40-10F1(T发射)和TCT40-10S1(R接收),中心频率为40kHz,安装时应保持两换能器中心轴线平行并相距4~8cm,其余元件无特殊要求。若能将超声波接收电路用金属壳屏蔽起来,则可提高抗干扰能力。根据测量范围要求不同,可适当调整与接收换能器并接的滤波电容C4的大小,以获得合适的接收灵敏度和抗干扰能力。 硬件电路制作完成并调试好后,便可将程序编译好下载到单片机试运行。根据实际情况可以修改超声波发生子程序每次发送的脉冲宽度和两次测量的间隔时间,以适应不同距离的测量需要。根据所设计的电路参数和程序,测距仪能测的范围为0.07~5.5m,测距仪最大误差不超过1cm。系统调试完后应对测量误差和重复一致性进行多次实验分析,不断优化系统使其达到实际使用的测量要求。 后续工作需实验后才能验证 根据参考电路和集成的电路器件测距范围有限10m以内为好。 http://www.chuandong.com/cdbbs/2008-12/17/081217A9D4D0217.html希望对你有帮助!


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7826674.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-10
下一篇 2023-04-10

发表评论

登录后才能评论

评论列表(0条)

保存