对于多超声波测距来说,如果你要同时做,你就得让这些超声波的频率互相间隔开,否则互相会产生干扰。
如果你觉得这种间隔不容易做到,也可以采用循环扫描法来做,也就是先确定比如4个点,每个点上都有一套超声波测距装置(一个发射探头,一个接收探头),按一定的规律循环扫描。比如先启动1号探头,发射,接收,测量好数据后。启动第2个,发射,接收,测量好数据。然后第3,第4个。全部测量完成后,把数据集中,按照中学几何(平面几何或者立体几何,具体跟你的探测点放置有关系,物体的位置就相当于以你的探测头为圆心,以探测出的距离为半径的一个圆弧上,由于目标只有一个,因此理论上,4个点测出的圆弧最终会相交于1点,也就是物体位置,利用平面或者立体坐标,以及圆的数学函数方程,可以轻易算出来),算出坐标。然后再启动一次循环,第二次测量出坐标。多测几次后,把坐标(可能是平面,也可能是立体坐标)进行统计测算(比如求平均值),就可以求出比较准确的物体的坐标了。
从现在的情况看,你要做这么几步:
1、首先确保你会使用一个超声波探头测量距离。
2、你要温习一下中学几何的知识。
3、我建议你不要玩模块,这种东西虽然看似比较简单,其实你真正能学会的东西不多。而且如果它的软硬件设计有缺陷(比如你现在遇到的问题),你查也没法查出来。
目前国内超声波测距器的设计大多采用汇编语言设计。由于单片机应用系统的日趋复杂,要求所写
的代码规范化,模块化,并便于多人以软件工程的形式进行协同开发,汇编语言作为传统的单片机应用系
统的编程语言,已经不能满足这样的实际需要了,而C语言以其结构化和能产生高效代码满足了这样的需
求,成为电子工程师进行单片机系统编程时的首先编程语言。在本设计中,由于C语言程序有利于实现较
复杂的算法,汇编语言程序具有较高的效率并且容易精确计算程序运行的时间,而超声波测距器的程序既
有较复杂的距离计算又要求精确计算超声波测距时程序运行的时间,所以本设计采用C语言和汇编语言
混合编程来实现。本文论述的是一种基于AT89C52单片机的超声波测距器,可用于汽车倒车等场合⋯。
1设计要求
设计一个超声波测距器,可以应用于汽车倒车、建筑施工工地以及一些工业现场的位置监控,也可用
于如液位、井深、管道长度的测量等场合。要求测量范围在0.10—5.00 m,测量精度lem,测量时与被测物
体无直接接触,能够清晰稳定地显示测量结果。
2设计思路
2.1超声波及其测距原理
超声波是指频率高于20KHz的机械波。为了以超声波作为检测手段,必须产生超声波和接收超声波。
完成这种功能的装置就是超声波传感器,习惯上称为超声波换能器或超声波探头。超声波传感器有发送
器和接收器,但一个超声波传感器也可具有发送和接收声波的双重作用。超声波传感器是利用压电效应
的原理将电能和超声波相互转化,即在发射超声波的时候,将电能转换为超声波,发射超声波;而在收到回
波的时候,则将超声振动转换成电信号。
超声波测距的原理一般采用渡越时间法TOt(time of fliight)。首先测出超声波从发射到遇到障碍物返
回所经历的时间,再乘以超声波的速度就得到二倍的声源与障碍物之间的距离。测量距离的方法有很多
种,短距离的可以用尺,远距离的有激光测距等,超声波测距适用于高精度的中长距离测量。因为超声波
收稿日期:2008-04-08
作者简介:周功明(1963一),男,副教授,主要研究方向:电子信息科学技术。
·50· 绵阳师范学院学报(自然科学版) 第27卷
在标准空气中的传播速度为331.45粑秒,由单片机负责计时,单片机使用12.0M晶振,所以此系统的测
量精度理论上可以达到毫米级。由于超声波指向性强,能量消耗缓慢,在介质中传播距离远,因而超声波
可以用于距离的测量。利用超声波检测距离,设计比较方便,计算处理也较简单,并且在测量精度方面也
能达到要求。
超声波发生器可以分为两类:一类是用电气方式产生超声波,一类是用机械方式产生超声波。本课题
属于近距离测量,可以采用常用的压电式超声波换能器来实现7。
2.2超声波测距器的系统框图
根据设计要求并综合各方面因素,可以采用AT89C52单片机作为主控制器,用动态扫描法实现LED
数字显示,超声波驱动信号用单片机的定时器完成,超声波测距器的系统框图如下图l所示¨2|:
3系统组成
3.1硬件部分
主要由单片机系统及显示电路、超声波发射电路
和超声波检测接收电路三部分组成。采用AT89C52来
实现对CX20106A红外接收芯片和TCT40—10系列超
声波转换模块的控制。单片机通过P1.0引脚经反相
\
超声波接收E :, LED显示单片机r
/\
Z ∑
超声波发送高控制器
:> 扫描驱动
图1 超声波测距器系统设计框图
Fig.1 Ultrasonic eLangi.g system design diagram
器来控制超声波的发送,然后单片机不停的检测INT0引脚,当INTO引脚的电平由高电平变为低电平时就
认为超声波已经返回。计数器所计的数据就是超声波所经历的时间,通过换算就可以得到传感器与障碍
物之间的距离¨≈J。
3.2软件部分
主要由主程序、超声波发生子程序、超声波接收中断程序及显示子程序等部分。
4系统硬件电路设计
4.1单片机系统及显示电路
单片机采用AT89C52或其兼容系列。采用12MHz高精度的晶振,以获得较稳定的时钟频率,减小测
量误差。单片机用P1.0端口输出超声波转化器所需的40KHz方波信号,利用外中断0口检测超声波接收
电路输出的返回信号。显示电路采用简单实用的4位共阳LED数码管,段码用74LS244驱动,位码用PNP
三极管驱动。单片机系统及显示电路如下图2所示‘1。31。
图2单片机及显示电路原理图
Fig.2 MCU and display circuit schematics
第8期周功明等:基于AT89C52单片机的超声波测距器设计·51.
4.2超声波发射电路原理图
压电超声波转换器的功能:利用压电晶体谐振工作。内部结构如图3‘3Ⅲ1所示,它有两个压电晶片和
一个共振板。当它的两极外加脉冲信号,其频
率等于压电晶片的固有振荡频率时,压电晶片PI.O
将会发生共振,并带动共振板振动产生超声波,
这时它就是一超声波发生器;如没加电压,当共
振板接收到超声波时,将压迫压电振荡器作振
动,将机械能转换为电信号,这时它就成为超声
波接收转换器。超声波发射转换器与接收转换
器其结构稍有不同。
4.3超声波检测接收电路图3发射电路原理图
参考红外转化接收电路,本设计采用集成
F‘g·3 U1‘ms。nie劬啪mi‘妇c‘咖1‘∞hem蚯c
电路CX20106A,这是一款红外线检波接收的专用芯片,常用于电视机红外遥控接收器。考虑到红外遥控
常用的载波频率38KHz与测距超声波频率
40KHz较为接近,可以利用它作为超声波检测
电路。如图43 J[71超声波检测接收电路原理图
所示,适当改变C4的大小,可改变接收电路的
灵敏度和抗干扰能力。⋯. J。j-二
5系统程序设计
超声波测距软件设计主要由主程序,超声
波发射子程序,超声波接收中断程序及显示子
程序组成。下面对超声波测距器的算法,主程
序,超声波发射子程序和超声波接收中断程序
逐一介绍。
5.1超声波测距器的算法设计
GND
图4超声波检测接收电路原理图
Fig.4 Ultrasonic receiver and detection circuit schematic
图5_列示意了超声波测距的原理,即超声
波发生器T在某一时刻发出的一个超声波信号,当超声波遇到被测物
体后反射回来,就被超声波接收器R所接受。这样只要计算出发生信
号到接收返回信号所用的时问,就可算出超声波发生器与反射物体的
距离。
距离计算公式:d=s/2=(c木t)/2,其中d为被测物与测距器的距
离,s为声波的来回路程,c为声速,t为声波来回所用的时间。
图5超声波测距原理图
Fig.5 Ultrasonic Ranging schematic
声速c与温度有关(见表1),如温度变化不大,则可认为声速是基
本不变的。如果测距精度要求很高,则应通过温度补偿的方法加以校正。声速确定后,只要测得超声波往
返时间,即可求得距离。在系统加入温度传感器来监测环境温度,可进行温度补偿。这里可以用DSl8820
测量环境温度,根据不同的环境温度确定一声速提高测距的稳定性。为了增强系统的可靠性,可在软硬件
上采用抗干扰措施。
表1不同温度下的超声波速表
Table I Under different temperatures ultrasonic velocity Table
·52· 绵阳师范学院学报(自然科学版) 第27卷
5.2主程序
主程序首先对系统环境初始化,设置定时器1D工作模式为16位的定时计数器模式,置位总中断允许
位EA并给显示端Po和P2清0。然后调用超声波发生子程序送出一个超声波脉冲,为避免超声波从发射
器直接传送到接收器引起的直接波触发,需延迟0.1ms(这也就是测距器会有一个最小可测距离的原因)
后,才打开外中断0接收返回的超声波信号。由于采用12MHz的晶振,机器周期为lus,当主程序检测到接
收成功的标志位后,将计数器哟中的数(即超声波来回所用的时
间)按下式计算即可测得被测物体与测距仪之间的距离,设计时取
20℃时的声速为344 m/s则有:d=(C木TO)/2=172T0/10000cm
(其中,ID为计数器,ID的计数值)。
测出距离后结果将以十进制BCD码方式LED,然后再发超声
波脉冲重复测量过程。主程序框图如图6所示。
5.3超声波发生子程序和超声波接收中断程序
超声波发生子程序的作用是通过PI.0端口发送2个左右的
超声波信号频率约40KHz的方波,脉冲宽度为12 US左右,同时把
计数器,ID打开进行计时。超声波测距器主程序利用外中断0检
测返回超声波信号,一旦接收到返回超声波信号(INT0引脚出现
低电平),立即进入中断程序。进入该中断后就立即关闭计时器
,ID停止计时,并将测距成功标志字赋值l。如果当计时器溢出时
还未检测到超声波返回信号,则定时器rID溢出中断将外中断0关
闭,并将测距成功标志字赋值2以表示此次测距不成功H旬J。
5.4超声波测距器的部分程序清单
/宰超声波测距器d片机c程序使用Keil C51 ver 7.09
。
木/
#include<re951.h>
#define uchar unsigned int
#define uint unsigned int
#define ulong unsigned long
Extem void ca_t(void);
Extem void delay(uint);
Extem void display(unchar);
Data unehar testtok;
/木超声波测距器主程序术/
Void main(void)
{data unchar dispram[5];
data uint i;
data ulong time;
p0=0xff;
pl=0xff;
TMOD=0X11:
IE=0x80;
While(1)
{.“}
开始
系统初始化
发送超声波脉冲
等待发射超声波
计算距离
显示结果0.5s
图6主程序框图
diagram of the main program
第8期周功明等:基于AT89C52单片机的超声波测距器设计·53·
6软硬件调试
超声波测距仪的制作和调试,其中超声波发射和接收采用中15的超声波换能器TCT40一IOFl(T发
射)和TCT40—10S1(R接收),中心频率为40kHz,安装时应保持两换能器中心轴线平行并相距4—8 cm,
其余元件无特殊要求。若能将超声波接收电路用金属壳屏蔽起来,则可提高抗干扰能力。根据测量范围
要求不同,可适当调整与接收换能器并接的滤波电容C4的大小,以获得合适的接收灵敏度和抗干扰能力。
硬件电路制作完成并调试好后,便可将程序编译好下载到单片机试运行。根据实际情况可以修改超
声波发生子程序每次发送的脉冲宽度和两次测量的间隔时间,以适应不同距离的测量需要∞71。
7 结束语
本文设计的是基于AT89C52单片机的超声波测距器,可应用于汽车倒车等场合,提醒驾驶员倒车时有
效的避开可能对倒车造成危害的障碍物和行人,从而有效避免由于倒车造成的汽车碰撞或擦伤经济损失
和人身安全问题。具有较强的实用性。
参考文献:
[1] 周功明.基于AT89C2051d片机的防盗自动报警电子密码锁系统设计[J].绵阳师范学院学报,2007,26(5):112—
116.
[14]
张齐.单片机应用系统设计技术一基于c语言编程[M].北京:电子工业出版社,2006.
李光飞.单片机c程序设计实例指导[M].北京:航空航天大学业出版社,2005.
楼燃苗,李光飞.51系列单片机设计实例[M].北京:航空航天大学业出版社,2003.
Zhongbo Li.Electronic Technique[M].Beijing:Mechannic Industrical Prees,2003.
赖麒文.8051单片机c语言彻底应用[M].北京:科学业出版社,2002.
何希才.传感器及其应用电路[M].北京:电子工业出版社,2001.
丁元杰.单片微机原理及应用[M].北京:机械工业出版社,2001.
孙串友,孙晓斌.感测技术基础[M].北京:电子工业出版社,2001.
马忠梅.单片机的c语言应用程序设计[M].北京:航空航天大学业出版社,1999.
刘喜昂,周志宇.基予多超声传感器的机器人安全避障技术[J].测控技术,2003,23(2):71—73.
翟国富,刘茂恺.一种实时高精度的机器人用超声波测距处理方法[J].应用声学,1990,15(1):17—24.
Cray C,Swinhoe C F,Myinl.Target controlled infusion of ketamine曲analgessia for TIV A with propof01.Can.J Anesth,1999,
40:957.
R J Higgens.Electronics and Analog Integrated Circuits[M].N.J:Prentice—Hall Inc,2001.
你好,我前段时间使用了HC-SR04超声波测距仪来测距离,用51单片机控制,LCD1602显示距离,精确到001cm,最大可测400cm。
我把我的程序给你,能做个测距和显示的参考。
若我们使用的是同一型号的超声波测距仪,可以回复我一起讨论。
希望我的回答能帮助到你。
hello,读者们好!
前两章,主要讲述了环境参量的测量获取,想必大家都有些许收获。在这一章中,我将介绍如何利用超声波来测距。在现实生活中,利用超声波测距的应用很多,广泛应用于机器人避障 、物体测距 、液位检测 、公共安防、停车场检测等领域。
本次测距使用的超声波为HC-SRO4,该模块共有4个引脚,分别是两个电源引脚VCC和GND,一个触发控制信号输入(TRIG)和一个回响信号输出( ECHO),性能稳定,测度距离精确,模块高精度,盲区小。
那么,超声波模块测距原理是:首先,给Trig引脚至少10us的高电平信号,检测Echo是否有信号返回,若有信号返回,则Echo发出高电平。高电平持续的时间就是超声波从发射到返回的时间,所以测试距离为(高电平时间声速)/2。下面,就是超声波模块的时序图。
本模块使用方法简单,配合stm32的定时器TIM4,一个控制口发一个10us以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器TIM4计时,当此口变为低电平时就可以读定时器TIM4的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,即可以达到你移动测量的值。
(1)配置超声波的引脚
/初始化超声波引脚:Trig:PB0,Echo:PB1/
void ultra_gpio_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/使能GPIO的RCC时钟/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/配置Trig引脚/
GPIO_InitStructureGPIO_Pin = GPIO_Pin_0;
GPIO_InitStructureGPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructureGPIO_Mode = GPIO_Mode_Out_PP;//Trig
GPIO_Init(GPIOB,&GPIO_InitStructure);
/配置Echo引脚/
GPIO_InitStructureGPIO_Pin = GPIO_Pin_1;
GPIO_InitStructureGPIO_Mode = GPIO_Mode_IN_FLOATING;//Echo
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
由于PB0接超声波Trig引脚,所以选择推挽输出模式,PB1接超声波Echo引脚,所以选择浮空输入模式。这样,超声波模块引脚就配置完成。
(2)定时器TIM4初始化
/定时器4的NVIC配置/
void tim4_nvic_config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructNVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructNVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
NVIC_InitStructNVIC_IRQChannelSubPriority = 0;//子优先级为0
NVIC_InitStructNVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/定时器4初始化/
void tim4_config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
tim4_nvic_config(); //配置NVIC
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//开启时钟
TIM_DeInit(TIM4); //定时器4复位
TIM_TimeBaseInitStructTIM_Period = 1000-1; //自动重装载寄存器值
TIM_TimeBaseInitStructTIM_Prescaler = 72-1; //时钟预分频数
TIM_TimeBaseInitStructTIM_ClockDivision = TIM_CKD_DIV1; //采样分频
TIM_TimeBaseInitStructTIM_CounterMode = TIM_CounterMode_Up; //计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct); //初始化TIM4
TIM_ClearFlag(TIM4, TIM_FLAG_Update); //清除溢出中断标志
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM4, DISABLE);
}
由于考虑到测距时的距离过大,计数会溢出,出现不准确的现象,这里需要用到长计时,并且使用TIM4中断对计时变量进行自增,所以需要配置NVIC。这里设置的中断优先级比较高,因为测距不能被其他中断打断,否则可能出现数据不准的现象,或是数据抖动现象。其次,设置TIM4的中断溢出时间为1ms,此时还不能开启定时器TIM4。
(3)编写定时器中断程序
/定时器4中断服务函数/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4 ,TIM_IT_Update)!=RESET)
{
TIM4_NUM++;//长计时变量
}
TIM_ClearITPendingBit(TIM4 ,TIM_FLAG_Update);
}
为避免测量的距离过长,这里我们需要进行长计时,只需在中断函数里这样 *** 作:TIM4_NUM++,同时记得在每次测量距离前对TIM4_NUM复位即可。
(4)编写超声波测距相关函数
/启动超声波测距/
u16 ultra_measure(void)
{
u16 distance;
TRIG_H;
delay_us(20);
TRIG_L;
while(ECHO==RESET);
TIM_SetCounter(TIM4,0);
TIM4_NUM = 0;
TIM_Cmd(TIM4, ENABLE);
while(ECHO!=RESET);
TIM_Cmd(TIM4, DISABLE);
distance = (u16)ultra_get_distance();
return distance;
}
/获取超声波传播时间,间接计算出距离/
float ultra_get_distance(void)
{
u32 time;
float distance;
time = TIM4_NUM1000;
time += TIM_GetCounter(TIM4);//获取超声波测距总时间
TIM4->CNT = 0; //定时器复位
distance = (float)time0017;
return distance;
}
这里,需要查阅超声波手册中的时序图,方可编写程序。首先,向给trig 发送至少10 us的高电平脉冲,然后等待,捕捉 echo 端输出上升沿,捕捉到上升沿的同时,打开定时器开始计时,再次等待捕捉echo的下降沿,当捕捉到下降沿,读出计时器的时间,这就是超声波在空气中运行的时间,按照测试距离=(高电平时间声速)/2 就可以算出超声波到障碍物的距离。
这里我们测算的距离:distance = (float)time0017,计算的距离单位为cm。
(5)主函数调用测距函数
最后,在主函数里,调用测距函数即可获取到距离值,再通过lcd显示函数,显示出距离值。
value = ultra_measure();
lcd_display_string(0,32,"测量距离");
lcd_display_num_m(3, 48, value/1000);
lcd_display_num_m(3, 56, (value%1000)/100);
lcd_display_num_m(3, 64, (value%100)/10);
lcd_display_num_m(3, 72, value%10);
通过本章的介绍,相信你对于超声波测距应该了解不少了吧,相信你也可以做出来的。通过不断改变超声波和障碍物之间的位置,距离值会随之改变,是不是很有趣啊~
到目前为止,多功能时钟已经具备了显示时间、测量温湿度、测量空气质量以及测距的功能,但我们的LCD显示部分还没有优化。在下一章中,我将带着大家完成多功能时钟人机交互界面(简称UI)的开发,到时候,我们的界面就会变得比较美观了。敬请期待~
#ifndef ULTRASOUND_H
#define ULTRASOUND_H
#define uchar unsigned char
#define uint unsigned int
#define TRIG P1_3 //P1_2
#define ECHO P0_7 //P0_1
extern uchar RG;
extern uchar H1;
extern uchar L1;
extern uchar H2;
extern uchar L2;
extern uchar H3;
extern uchar L3;
extern uint data;
extern float distance;
extern uchar LoadRegBuf[4];
//void Delay(uint n);
void Delay_1us(uint microSecs);
void Delay_10us(uint n);
void Delay_1s(uint n);
void SysClkSet32M();
void Init_UltrasoundRanging();
void UltrasoundRanging(uchar ulLoadBufPtr);
__interrupt void P0_ISR(void);
#endif
×××××××××××××××××××××××××××××××××××××××××××
//×××××××××××Ultrasoundc
#include <ioCC2530h>
#include "Ultrasoundh"
uchar RG;
uchar H1;
uchar L1;
uchar H2;
uchar L2;
uchar H3;
uchar L3;
uint data;
float distance;
uchar LoadRegBuf[4];//全局数据,用以存储定时计数器的值。
void Delay_1us(uint microSecs)
{ while(microSecs--)
{ / 32 NOPs == 1 usecs 因为延时还有计算的缘故,用了31个nop/
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop");
}
}
void Delay_10us(uint n)
{ / 320NOPs == 10usecs 因为延时还有计算的缘故,用了310个nop/
uint tt,yy;
for(tt = 0;tt<n;tt++);
for(yy = 310;yy>0;yy--);
{asm("NOP");}
}
void Delay_1s(uint n)
{ uint ulloop=1000;
uint tt;
for(tt =n ;tt>0;tt--);
for( ulloop=1000;ulloop>0;ulloop--)
{
Delay_10us(100);
}
}
void SysClkSet32M()
{
CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ晶振
while(CLKCONSTA & 0x40); //等待晶振稳定
CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ
//此时的CLKCONSTA为0x88。即普通时钟和定时器时钟都是32M。
}
void Init_UltrasoundRanging()
{
P1DIR = 0x08; //0为输入1为输出 00001000 设置TRIG P1_3为输出模式
TRIG=0; //将TRIG 设置为低电平
P0INP &= ~0x80; //有上拉、下拉 有初始化的左右
P0IEN |= 0x80; //P0_7 中断使能
PICTL |= 0x01; //设置P0_7引脚,下降沿触发中断
IEN1 |= 0x20; // P0IE = 1;
P0IFG = 0;
}
void UltrasoundRanging(uchar ulLoadBufPtr)
{
SysClkSet32M();
Init_UltrasoundRanging();
EA = 0;
TRIG =1;
Delay_1us(10); //需要延时10us以上的高电平
TRIG =0;
T1CNTL=0;
T1CNTH=0;
while(!ECHO);
T1CTL = 0x09; //通道0,中断有效,32分频;自动重装模式(0x0000->0xffff);
L1=T1CNTL;
H1=T1CNTH;
ulLoadBufPtr++=T1CNTL;
ulLoadBufPtr++=T1CNTH;
EA = 1;
Delay_10us(60000);
Delay_10us(60000);
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
EA=0;
T1CTL = 0x00;
LoadRegBuf[2]=T1CNTL;
LoadRegBuf[3]=T1CNTH;
L2=T1CNTL;
H2=T1CNTH;
if(P0IFG&0x080) //外部ECHO反馈信号
{
P0IFG = 0;
}
T1CTL = 0x09;
T1CNTL=0;
T1CNTH=0;
P0IF = 0; //清中断标志
EA=1;
}
××××××××××××××××××××××××××××××××××××××
#include <ioCC2530h>
#include "Ultrasoundh"
void main(void)
{
while(1)
{
UltrasoundRanging(LoadRegBuf);
Delay_1s(1);
data=256H2+L2-L1-256H1;
distance=(float)data340/10000;
Delay_1s(2);
};
}
1、HC-SR04使用方法:给触发端子trig一个10us以上的高电平即可触发,触发后echo端子将接受到高电平,高电平的持续时间就是测距的往返时间。
2、例程:
#include<reg52h>#define uchar unsigned char
#define uint unsigned int
/位定义/
sbit CHUFA=P0^1; //位定义超声波触发端(10us以上高电平触发)
sbit JIESHOU=P0^3; //接收端(接受高电平)
sbit BEEP=P2^0; //蜂鸣器
sbit OUT0=P3^2; //外部中断0
uchar JS_FLAG; //接收标志
uint CF_TIME,t0,t1,shu;
/函数声明/
void timer0();
void int0();
void display(uint);
main(){
CHUFA=0; //初始化拉低触发端和接收端电平
JIESHOU=0;
JS_FLAG=0;
CF_TIME=15; //初始化触发时间(大于10us)
TMOD=0x11; //定时器方式选择
EA=1; //开总中断
ET0=1; //开定时器0中断
EX0=1; //开外部中断0
IT0=0; //外部中断选择下降沿触发
//JIESHOU=1;
while(1){
OUT0=JIESHOU; //外部中断0被赋值为接收端信号,当出现下降沿是触发外部中断0
if(JS_FLAG==0){ //如果没有接收到高电平则触发
CHUFA=1;
while(CF_TIME--); //10us以上高电平触发传感器
}
if(JIESHOU==1){
TR0=1; //如果接收端收到高电平则启动定时器
JS_FLAG=1; //并且标志位置1
BEEP=0; //蜂鸣器响
}
display(t1); //显示测量时间(秒)
}
}
/定时器0中断程序/
void timer0() interrupt 1{
TH0=(65536-10000)/256; //装初值 10ms
TL0=(65536-10000)%256;
t0++; //每进入一次中断t0加1
}
/外部中断0中断程序/
void int0() interrupt 0{
TR0=0; //一旦进入外部中断0,说明接收端收到下降沿信号。关闭定时器0
JS_FLAG=0; //接收标志位置0
BEEP=1; //关闭蜂鸣器
t1=t010/1000; //测量时间为 进入定时器中断次数t0乘以每次时间10ms,除以1000化为秒为单位
t0=0; //t0清零
}
/数码管显数函数/
void display(uint shu){
//数码管显示函数
}
关键这个电路是硬件设计好就可以。做一个40KHz的发射电路。。。用2051的一个IO控制电源。。。动态扫描LED显示
另外再做一个40KHZ的接收电路。。。二者频率对准。。。接收电路接收到发射信号的时候输出一个电压触发中断,先接通40KHZ发射电路的工作电压。。。单片机开始计时。。。等侍接收电路触发中断。当有中断。停止计时。。。
这个时间除以2再乘以超声波在空气中传播速度。应该就是等于你要测试的距离。。。
这是参考源代码,可能不全,仅作参考!
#include <AT892051H>
#define unit unsigned int
#define uchar unsigned char
sbit fs="P3"^0; //发送端;
sbit h="P3"^7;
sbit l="P3"^5; //数码管位选端;
sbit m="P3"^4;
uchar tab[16]=\{0x28,0xEB,0x32,0xA2,0xE1,0xA4,0x24,0xEA,0x20,0xA0,0x60,0x25,0x3C,0x23,0x34,0x74};//段码;
uchar u[3]; //显示数组;
unit count,b;
void delay(unit a) //延时;
\{
unit m;
for(m=0;m<a;m++);
}
void tx() //从P30发出40KHz的脉冲
\{
uchar n,p;
for(n=0;n<40;n++)\{
fs=1;
for(p=0;p<3;p++);
fs=0;
for(p=0;p<2;p++);
fs=0;
}
}
void display(void) //显示;
\{
for(;;)
\{
l=1;m=1;h=1;
P1=tab[u[0]];
m=0;
delay(10);
m=1;
P1=tab[u[1]];
l=0;
delay(10);
l=1;
P1=tab[u[2]];
h=0;
delay(10);
h=1;
}
}
void rx() interrupt 0 //外部中断0,接收信号
\{
TR0=0;
count=TH0256+TL0;
if(count<300);
if(count>=300)
\{
b=(17count)/1000;
u[0]=b%10;
u[1]=(b/10)%10;
u[2]=(b/100)%10;
display();
}
}
void over()interrupt 1 //T0溢出为无效测量FFF;
\{
u[0]=15;
u[1]=15;
u[2]=15;
display();
}
void main()
\{
fs=0;
delay(8600);
TH0=0;
TL0=0;
TMOD=0x01;
TR0=1;
EA=1;
ET0=1;
PT0=1;
tx();
IT0=1;
IE=0x83;
}
以上就是关于老师,关于多超声波测距,有什么样的方法才能同时测得数据。如果采用循环来测距应该怎么做全部的内容,包括:老师,关于多超声波测距,有什么样的方法才能同时测得数据。如果采用循环来测距应该怎么做、求基于AT89C52超声波测距简易设计的源程序,要求用3个LED管显示其测距,精确到小数点后2位如,X.XX米。、我自己写了一个超声波测距的程序,用51单片机,1602液晶显示,但是现在显示不出来,请各位大神帮忙等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)