单片机超声波测距模块

合集下载

DL-51单片机入门系列教程之七《超声波测距模块编程》

DL-51单片机入门系列教程之七《超声波测距模块编程》

51入门系列教程超声波测距模块编程Revision0.01(2011-10-18)刚好这次做机器人用到了超声波,才开始看它的工作原理,感觉还很简单,但是调试到最后,发现了很多问题,该碰到的都碰到了,趁着写单片机入门教程的机会,写出来分享给大家。

先把超声波的工作原理贴出来:从超声波的工作原理可以知道,其实只要单片机的两个引脚就足够,一个引脚接发送端,一个引脚接接收端即可。

工作时,发送端引脚置高电平10us时间的脉冲,这将激发超声波模块发送8个40khz周期的电平信号,然后模块的收端开始检测回波(实际上,两个眼睛,一个是发送的,一个是用来接收的)。

一旦发现有回波信号,就会输出一个响应给接收端引脚,这个响应是一个高电平脉冲。

所以,我们只要在接收端去检测是否有高电平脉冲即可。

但从程序编写与调试的过程来看,并没有那么简单。

因为超声波第一次发送40KHZ的信号出去后反射回来,有可能又被反弹回去,这样以来,相当于超声波在两个障碍物之间不断地来回反弹,导致接收端不断地收到”回波信号“——实际上第一次反弹回来的才是回波信号,其他的都是二次、三次...的反弹回波信号。

如果每次检测到回波就让蜂鸣器响一次,那么,我们程序运行时,可能会听到蜂鸣器不断地响,可能就是这个原因。

另外,需要关注的是,超声波如果前面没有障碍物,也会在接收端引脚上故意输出140us的电平,以”防止发射信号对回响信号的影响“。

从上面的分析看来,不管超声波前面有无障碍物,接收端引脚肯定都会出现高电平脉冲。

所以我们在编程时,必须过滤掉这140us。

讲完超声波的工作原理,我们来看下编写程序的思路。

由于超声波可能会连续收到回响信号,导致接收端不断出现高电平脉冲,而实际上,我们有用的仅仅是第一次反射回来的回响信号,因此,使用”查询接收端引脚是否出现高电平“的方法行不通。

可以使用外部中断,只检测第一次反射回来的信号,后续的反射信号全部丢弃不管。

下面看下140us的处理。

51单片机超声波测距离(带温度补偿)

51单片机超声波测距离(带温度补偿)

超声波模块原理图:发射接收原理图PCB:51单片机原理图:软件部分C语言程序:/*=========================================================== =========调试要求:1.MCU:A T89S52芯片或AT89C522.晶振:12MHz调试注意:本程序带温度补偿,采用DS18B20测量温度1.LCD1602液晶屏有显示后,才接入超声波模块。

2.注意超声波模块电源的极性。

不清楚请参好淘宝的电路图3.没有选用频率为12MHz晶振,用了别的频率晶振,单片机定时器的测量值与发出的40KHz频率脉冲不对。

4.使用者经常误发出20KHZ脉冲当40KHZ脉冲。

(40KHz频率脉冲,周期25us,占空比为50% = 12.5us)5.如果是用开发板调超声波模块,请检查开发板上的电路是否与超声波模块的控制脚复用了, 若复用了,请通过跳线分开发板上的电路。

6如果使用的是万用板,请确定单片机的复位电路和晶振电路是否正常,同时单片机的31脚(EA)记得接高电平。

============================================================= =======*/#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int//===============================LCD1602接口定义=====================/*-----------------------------------------------------|DB0-----P2.0 | DB4-----P2.4 | RW-------P0.1 ||DB1-----P2.1 | DB5-----P2.5 | RS-------P0.2 ||DB2-----P2.2 | DB6-----P2.6 | E--------P0.0 ||DB3-----P2.3 | DB7-----P2.7 | 注意,P0.0到P0.2需要接上拉电阻---------------------------------------------------============================================================= */#define LCM_Data P2 //数据接口#define Busy 0x80 //用于检测LCM状态字中的Busy标识sbit LCM_RW = P0^1; //读写控制输入端,LCD1602的第五脚sbit LCM_RS = P0^2; //寄存器选择输入端,LCD1602的第四脚sbit LCM_E = P0^0; //使能信号输入端,LCD1602的第6脚//===============================超声波模块定义========================sbit RemPin =P3^2;// 接收端(这个不能修改,因为是外部中断(INT0)的引脚) sbit TxPin =P3^1;// 发射端//******************************************************************** ***//ds18b20数字温度传感器控制引脚定义sbit dq_ds18b20=P3^3;//定义控制DS18B20//******************************************************************** ***//LCD显示模块的函数声明void WriteDataLCM (uchar WDLCM);//LCD模块写数据void WriteCommandLCM (uchar WCLCM,BuysC); //LCD模块写指令uchar ReadDataLCM (void);//LCD模块读数据uchar ReadStatusLCM (void);//读LCD模块的忙标void DisplayOneChar (uchar X,uchar Y,uchar ASCII);//在第X+1行的第Y+1位置显示一个字符void DisplayListChar (uchar X,uchar Y,uchar delayms,uchar code *DData); void DisplayCursorPos (uchar X, uchar Y);void LCMInit (void);void DisplayIntData (uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu);void DisplayCharData (uchar X, uchar Y,uchar ZiFu);//******************************************************************** **//延时函数声明void delay25us_40KHz(unsigned char us);void DelayUs(uint us);void DelayMs(uint Ms);void delay_3us();//3US的延时程序void delay_8us(unsigned int t);//8US延时基准程序void delay_50us(unsigned int t);//延时50*T微妙函数的声明//******************************************************************** ***//DS18B20测温函数定义void w_1byte_ds18b20(uchar value);//向DS18B20写一个字节uchar r_1byte_ds18b20(void);//从DS18B20读取一个字节的数据void rest_ds18b20(void);//DS18B20复位程序void readtemp_ds18b20(void);//读取温度void display_temp(void);//温度显示程序//******************************************************************** ***//参数定义uint length = 0; // 测距的长度0.00Muchar flag = 0; // 测距的标志有信号接收=1uchar templ,temph;uint speed;//根据温度计算出来的声音速度uchar t_b,t_s,t_g,t_x;//从左到右分别存储温度百位,十位,个位,小数位uchar flag1;//温度正负性暂存,1为正数,0为负数const unsigned char tabl3[]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x0 8,0x09,0x09};/*=========================================================== ================主程序============================================================= ================*/void main(void){uchar i;LCMInit(); //1602初始化EX0 = 1; //允许总中断中断,使能INT0 外部中断ET0 = 1;TMOD=0x11; //设定T0为16位时器,设定T1为16位时器DisplayOneChar( 0,14,'m');DisplayListChar(0,0,0, "Distanc: "); //显示字符串while(1){readtemp_ds18b20();display_temp();//显示温度for(i=0;i<20;i++){DisplayIntData(0, 13,length,5,3);//显示测量距离TH0=0x00;TL0=0x00;TR0=1; //启动定时器0EA = 1; //允许所有中断delay25us_40KHz(15); //发出脉冲信号DelayMs(200);}}}//******************************************************************** ***********//温度显示函数void display_temp(){if(flag1==1)//温度为正数时的显示程序{DisplayOneChar( 1,2,'+');}else{DisplayOneChar( 1,2,'-');}//显示温度信息DisplayOneChar( 1,0,'T');DisplayOneChar( 1,1,':');DisplayOneChar( 1,3,t_s+0x30);DisplayOneChar( 1,4,t_g+0x30);DisplayOneChar( 1,5,'.');DisplayOneChar( 1,6,t_x+0x30);//显示速度信息DisplayOneChar( 1,8,'S');DisplayOneChar( 1,9,':');DisplayOneChar( 1,10,speed/100%10+0x30);DisplayOneChar( 1,11,speed/10%10+0x30);DisplayOneChar( 1,12,speed%10+0x30);DisplayOneChar( 1,13,'M');DisplayOneChar( 1,14,'/');DisplayOneChar( 1,15,'S');}//****************************************************//读取温度void readtemp_ds18b20(void){uchar temp32;rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0x44); //启动温度转换delay_8us(2);rest_ds18b20();w_1byte_ds18b20(0xcc); //跳过读序列号的操作w_1byte_ds18b20(0xbe); //读取温度寄存器等(共可读9个寄存器)前两个就是温度templ=r_1byte_ds18b20();temph=r_1byte_ds18b20();if((temph&0xf0))//判断温度的正负性{flag1=0;temph=-temph;templ=-templ;t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据speed=331.4-0.607*(temp32 | templ);}else//为正数{t_x=tabl3[templ & 0x0f];//计算温度的小数temp32=temph & 0x0f;temp32<<=4;templ>>=4;temp32=temp32 | templ;t_b=temp32/100%10;//计算温度的百位数据t_s=temp32/10%10;//计算温度的十位数据t_g=temp32%10;//计算温度的个位数据flag1=1;speed=311.4+0.607*(temp32 | templ);}}/*=========================================================== =========功能:在1602显示一个整数数据说明:显示一个整数数据-9999->32625. 从右至左显示数据5位:============================================================= =========*/void DisplayIntData(uchar X, uchar Y,int ZhengShu,uchar Digit,uchar XiaoShu) {uchar i=0,k=0, BCD[5]={0};if(Digit>5) Digit=5;if(ZhengShu<0){k=1;//负数示志位ZhengShu=-ZhengShu;}BCD[4] =ZhengShu / 10000; //求出万位数据ZhengShu = ZhengShu % 10000;BCD[3] =ZhengShu / 1000; //求出千位数据ZhengShu = ZhengShu % 1000;BCD[2] =ZhengShu / 100; //求出百位数据ZhengShu = ZhengShu % 100;BCD[1] =ZhengShu / 10; //求出十位数据BCD[0] =ZhengShu % 10; //求出个位数据for(i=0;i<Digit;i++)//输出显示的数值{if((i==XiaoShu)&&(0!=XiaoShu)){DisplayOneChar(X,Y-i,'.');//输出小数点Y= Y-1;}DisplayOneChar(X,Y-i,BCD[i]+0x30); //显示一个字符}if(k==1)DisplayOneChar(X,Y-1,'-');//输出负符}//****************************************************************//读一个字节uchar r_1byte_ds18b20(void){uchar i=0;uchar value= 0;for (i=0;i<8;i++){value>>=1;dq_ds18b20=0;// DQ_L;delay_3us();dq_ds18b20=1; //DQ_H;delay_8us(2);if(dq_ds18b20==1) value|=0x80;delay_8us(6); //延时40us}dq_ds18b20=1;return value;}//******************************************************************** ***********//子程序功能:向DS18B20写一字节的数据void w_1byte_ds18b20(uchar value){uchar i=0;for(i=0;i<8;i++){dq_ds18b20=1;delay_3us();dq_ds18b20=0;delay_8us(2);if (value& 0x01) dq_ds18b20=1; //DQ = 1delay_50us(1); //延时50us 以上delay_8us(2);value>>=1;}dq_ds18b20=1; //DQ = 1}//;**************************************************//ds18b20复位子程序void rest_ds18b20(void){rest:delay_3us(); //稍做延时delay_3us();dq_ds18b20=1;delay_3us();dq_ds18b20=0;// DQ_L;delay_50us(11);//480us<T<960usdq_ds18b20=1;//拉高总线delay_8us(5);if(dq_ds18b20==1){return;}delay_50us(2); //延时90usif(dq_ds18b20==1){return;}else{goto rest;}}//==============================超声波模块测试子程序================================================/*=========================================================== =========注意:是用12MHz晶振设定延时时间:x*25us 与产生40KHZ的脉冲============================================================= =======*/void delay25us_40KHz(unsigned char us){while(us--){TxPin = 0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TxPin = 1;_nop_();_nop_();_nop_();_nop_();}TxPin = 1;}/*=========================================================== ==================中断程序的入口(注意:接收与发射的电平是相反的)============================================================= ==================*/void init0int() interrupt 0{uint timer_us = 0;TR0=0; //关闭定时器0timer_us =TH0*256+TL0;if(timer_us>190)timer_us=timer_us-180; //修正测距的距离if(timer_us<=735){timer_us=timer_us-96;//二次修正}if(timer_us>5059){timer_us+=29;}if(timer_us>5470){timer_us+=29;}if(timer_us>6410){timer_us+=29;}if(timer_us>7410){timer_us+=29;}if(timer_us>8410){timer_us+=29;}if(timer_us>9410){timer_us+=29;}if(timer_us>10410){timer_us+=29;}length = ((unsigned long)(speed)*timer_us)/2000;//计算长度,是扩大100倍flag = 0;EA = 0; //禁止所有中断}/*=========================================================== =========功能:在1602显示一个字符数据说明:显示一个字符数据0~256. 从左至右显示数据3位============================================================= =========*/void DisplayCharData(uchar X, uchar Y,uchar ZiFu){uchar i=0;uchar V alueBCD[3];V alueBCD[0] = ZiFu / 100; //求出百位数据ZiFu = ZiFu % 100;V alueBCD[1] = ZiFu / 10; //求出十位数据V alueBCD[2] = ZiFu % 10; //求出个位数据for(i=0;i<3;i++)//输出显示的数值{DisplayOneChar(X,Y+i,V alueBCD[i]+0x30); //显示一个字符}}/*=========================================================== ================超出测量时间============================================================= ================*/void timer0int (void) interrupt 1{TR0=0; //关闭定时器0length = 0; //超出测量时间显示示0flag = 1; //EA = 0; //禁止所有中断}/*=========================================================== ===========LCM初始化============================================================= =========*/void LCMInit(void){LCM_Data = 0;WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,0);DelayMs(5);WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号WriteCommandLCM(0x08,1); //关闭显示WriteCommandLCM(0x01,1); //显示清屏WriteCommandLCM(0x06,1); // 显示光标移动设置WriteCommandLCM(0x0C,1); // 显示开及光标设置DelayMs(100);}/*=========================================================== =========显示光标的位置============================================================= =======*/void DisplayCursorPos( unsigned char X, unsigned char Y){X &= 0x1;Y &= 0xF; //限制Y不能大于15,X不能大于1if (X) Y |= 0x40; //当要显示第二行时地址码+0x40;Y |= 0x80; // 算出指令码WriteCommandLCM(Y, 1); //这里不检测忙信号,发送地址码}/*=========================================================== =========按指定位置显示一串字符:第X 行,第y列注意:字符串不能长于16个字符============================================================= =========*/void DisplayListChar(uchar X,uchar Y,uchar delayms, uchar code *DData){unsigned char ListLength;ListLength = 0;X &= 0x1;Y &= 0xF; //限制X不能大于15,Y不能大于1while (DData[ListLength]!='\0') //若到达字串尾则退出{if (Y <= 0xF) //X坐标应小于0xF{DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符ListLength++;Y++;DelayMs(delayms);//延时显示字符串}elsebreak;//跳出循环体}}/*=========================================================== =========设定延时时间:x*1us============================================================= =======*/void DelayUs(uint us){while(us--);}/*=========================================================== =========设定延时时间:x*1ms============================================================= =======*/void DelayMs(uint Ms){uint i,TempCyc;for(i=0;i<Ms;i++){TempCyc = 250;while(TempCyc--);}}//==============================LCD1602显示子程序================================================/*=========================================================== ==========写数据函数: E =高脉冲RS=1 RW=0============================================================= =========*/void WriteDataLCM(unsigned char WDLCM){ReadStatusLCM(); //检测忙LCM_Data = WDLCM;LCM_RS = 1;LCM_RW = 0;LCM_E = 0; //若晶振速度太高可以在这后加小的延时LCM_E = 0; //延时LCM_E = 1;}/*=========================================================== =========写指令函数: E=高脉冲RS=0 RW=0============================================================= =========*/void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测{if (BuysC) ReadStatusLCM(); //根据需要检测忙LCM_Data = WCLCM;LCM_RS = 0;LCM_RW = 0;LCM_E = 0;LCM_E = 0;LCM_E = 1;}/*=========================================================== =========//读数据============================================================= =========*/unsigned char ReadDataLCM(void){LCM_RS = 1;LCM_RW = 1;LCM_E = 0;LCM_E = 0;LCM_E = 1;return(LCM_Data);}/*=========================================================== =========正常读写操作之前必须检测LCD控制器状态:E=1 RS=0 RW=1;DB7: 0 LCD控制器空闲,1 LCD控制器忙。

基于单片机控制的超声波测距系统的设计

基于单片机控制的超声波测距系统的设计

基于单片机控制的超声波测距系统的设计一、概述。

超声波测距技术是一种广泛应用的测距技术,它能够非常精确地测量物体到传感器的距离。

本文介绍的基于单片机控制的超声波测距系统主要由控制模块、信号处理模块和驱动模块三部分组成。

其中,控制模块主要实现超声波信号的发射与接收,信号处理模块主要实现对测量结果的处理和计算,驱动模块主要实现对LED灯的控制。

二、硬件设计。

1.超声波发射模块:采用 SR04 超声波发射传感器,并通过单片机的PWM 输出控制 SR04 的 trig 引脚实现超声波信号的发射。

2.超声波接收模块:采用SR04超声波接收传感器,通过单片机的外部中断实现对超声波信号的接收。

3.控制模块:采用STM32F103单片机,通过PWM输出控制超声波发射信号,并通过外部中断接收超声波接收信号。

4.信号处理模块:采用MAX232接口芯片,将单片机的串口输出转换成RS232信号,通过串口与上位机进行通信实现测量结果的处理和计算。

5.驱动模块:采用LED灯,通过单片机的GPIO输出控制LED灯的亮灭。

三、软件设计。

1.控制模块:编写程序实现超声波信号的发射与接收。

其中,超声波发射信号的周期为 10us,超声波接收信号的周期为 25ms。

超声波接收信号的处理过程如下:(1)当 trig 引脚置高时,等待 10us。

(2)当 trig 引脚置低时,等待 echo 引脚为高电平,即等待超声波信号的回波。

(3)当 echo 引脚为高电平时,开始计时,直到 echo 引脚为低电平时,停止计时。

(4)根据计时结果计算物体到传感器的距离,将结果通过串口输出。

2.信号处理模块:编写程序实现接收计算结果,并将结果通过串口与上位机进行通信。

具体步骤如下:(1)等待串口接收数据。

(2)当接收到数据时,将数据转换成浮点数格式。

(3)根据测量结果控制LED灯的亮灭。

以上就是基于单片机控制的超声波测距系统的设计。

该系统能够通过精确测量物体到传感器的距离并对测量结果进行处理和计算,能够广泛应用于各种实际场合。

基于STM32的HC-SR04超声波测距模块实验

基于STM32的HC-SR04超声波测距模块实验

基于STM32的HC-SR04超声波测距模块实验硬件环境STM32F407探索板(其他开发板皆可以)HC-SR04超声波模块软件环境KEIL5CUBEMX串口调试助手(sscom或其他)实验目标•了解HC-SR04超声波模块工作原理•实现超声波模块测距1、超声波模块介绍1.1 超声波测距原理及系统组成超声波测距是借助于超声脉冲回波渡越时间法来实现的。

设超声波脉冲由传感器发出到接收所经历的时间为t,超声波在空气中的传播速度为c,则从传感器到目标物体的距离D可用下式求出:D = ct/2,图2是相应的系统框图。

基本原理:经发射器发射出长约 6mm,频率为 40KHZ 的超声波信号。

此信号被物体反射回来由接收头接收,接收头实质上是一种压电效应的换能器。

它接收到信号后产生 mV 级的微弱电压信号。

1.2 HC-SR04模块原理HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达高到3mm,模块包括超声波发射器、接收器与控制电路。

基本工作原理:(1)采用IO 口TRIG 触发测距,给最少10us 的高电平信呈。

(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。

测试距离=(高电平时间*声速(340M/S))/2,下面是实物图。

如上图接线,VCC供5V电源,GND为地线,TRIG触发控制信号输入,ECHO 回响信号输出等四个接口端。

1.3 超声波时序图以上时序图表明你只需要提供一个10uS以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。

一旦检测到有回波信号则输出回响信号。

回响信号的脉冲宽度与所测的距离成正比。

由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。

公式:uS/58=厘米或者uS/148=英寸;或是:距离=高电平时间*声速(340M/S)/2;建议测量周期为60ms以上,以防止发射信号对回响信号的影响。

毕业设计基于51单片机的超声波测距模块设计

毕业设计基于51单片机的超声波测距模块设计

西南科技大学毕业设计(论文)题目名称:基于51单片机的超声波测距模块设计年级:2003级■本科□专科学生学号:20035095学生姓名:时余春指导教师:何宏森胡天链学生单位:信息工程学院技术职称:讲师学生专业:生物医学工程教师单位:信息工程学院西南科技大学教务处制基于51单片机的超声波测距模块设计摘要:本文介绍了一种基于单片机的脉冲反射式超声波测距模块。

该模块以空气中超声波的传播速度为确定条件,利用反射超声波测量待测距离。

论文概述了超声检测的发展及基本原理,介绍超声波传感器的原理及特性。

对于测距系统的一些主要参数进行了讨论。

并且在介绍超声测距系统功能的基础上,提出了系统的总体构成。

针对测距系统发射、接收、检测、显示部分的总体设计方案进行了论证。

进一步介绍了单片机AT89C51在系统中的应用,分析了系统各部分的硬件及软件实现。

最后利用测距系统进行验证。

实验表明,各主要波形及技术指标均达到设计要求。

该系统对室内有限范围的距离测量具有较高的精度和可靠性,最后文中分析了误差产生的原因及如何对系统进行完善。

关键词:51单片机;超声波;测距Design of Ultrasonic Distance Measurement Based on AT89C51 MCUAbstract: The thesis introduces a kind of single-pulse-refection ultrasonic distance meter system module in detail based on Microcontroller. The system could measure certain distance with the reflected wave on condition in which the speed of transmitting wave is fixed. This paper summarizes the development and foundational principle of ultrasonic detections. Then it presents the theory and characters of ultrasonic sensor. At the same time, it discusses a number of main technical parameters. Moreover, it proposes the whole structure of the system by introducing the function of ultrasonic distance meter. And then the transmission receiver, detection, display scheme of this distance meter system is demonstrated. Specially, after the application of AT89C51 microcontroller, it analyzes the hardware and soft ware realization of each part in this system. At last the result and error analysis of the experiments is presented. It is proved by experiments that the design of the system is provided with high accuracy and reliability. In the end, the further measures of modification are presented.Keywords: AT89C51 MCU, ultrasonic, distance measurer目录第1章绪论 (1)1.1课题背景 (1)1.1.1 机器人感知系统研究现况 (1)1.1.2 传感器技术概况 (1)1.2课题目的及意义 (2)1.3课题设计研究范围及成果 (2)第2章超声波传感器模块测距方案分析 (3)2.1超声波与超声波的应用 (3)2.2超声波传感器 (4)2.2.1 超声波传感器的原理及结构 (4)2.2.2 超声波传感器的分类 (6)2.2.3 超声波发射器 (7)2.2.4 超声波接收器 (8)2.3系统主要参数考虑 (10)2.3.1 传感器的指向角θ (10)2.3.2 声速 (10)2.3.3 测量盲区 (10)2.4超声波传感器模块设计原理 (11)2.5典型的超声波传感器测距模块 (11)第3章超声波传感器测距模块的硬件设计 (13)3.1超声波传感器测距模块的总体 (13)3.2超声波传感器测距模块的设计难点及解决方法 (14)3.2.1 提高测距精度的依据 (15)3.2.2 系统设计干扰问题及其解决方法 (15)3.3硬件电路设计说明 (15)3.3.1 发射部分 (16)3.3.2 接收部分 (16)3.3.3 测温部分 (16)3.3.4 超声波测距模块 (16)3.4主要器件选择及其简介 (16)3.4.1 LM358运放简介 (16)3.4.2 温度传感器DS18B20 (17)3.4.3 AT89C51单片机简介 (19)3.5硬件电路的具体设计 (20)3.5.1 电源的设计 (20)3.5.2 超声波发生电路 (21)3.5.3 超声波回波接收检测 (22)3.5.4 温度补偿电路 (23)3.5.5 LED动态扫描显示电路 (23)3.6系统抗干扰措施 (24)第4章系统软件结构设计 (26)4.1主程序结构 (26)4.2中断程序 (27)4.3回波接收程序 (29)第5章系统实验结果分析 (30)结论与展望 (32)致谢 (33)参考文献 (34)附录1:超声波测距模块设计原理图 (35)附录2:超声波测距模块设计PCB图 (36)附录3:超声波测距模块设计PCB3D效果图 (37)附录4:DS18B20温度采集补偿程序 (38)第1章绪论1.1 课题背景本设计依托电子技术、嵌入式处理计算技术、机器人技术、传感器技术,并根据当前科学技术发展潮流,引出对用于机器人中的超声波传感器测距模块的研究与设计。

51单片机超声波测距C程序

51单片机超声波测距C程序

51单片机超声波测距C程序(2018-01-26 14:09:10>超声波检测原理超声波测距的程序流程图程序如下://超声波模块程序〃超声波模块程序//Trig = P2A0//Echo = P3A2#in elude <reg52.h>#defi ne uchar un sig ned char#defi ne uint un sig ned int//void delay( uint z>{uint x,y 。

for(x=z 。

x>0。

x-->for(y=110 。

y>0。

y-->。

//void delay_20us(>{uchar a 。

for(a=0。

a<100。

a++>。

}//*********************************************************** ****// 显示数据转换程序void display(uint temp>{uchar ge,shi,bai 。

bai=temp/100 。

shi=(temp%100>/10 。

ge=temp%10。

wela=1 。

P0=0xf7。

wela=0 。

dula=1 。

P0=table[bai] 。

delay(1> 。

dula=1 。

P0=0x00 。

// 关位码dula=0 。

wela=1 。

P0=0xef 。

wela=0 。

dula=1 。

P0=table[shi] 。

dula=0 。

delay(1> 。

dula=1 。

P0=0x00。

// 关位码dula=0 。

dula=1 。

P0=table[ge] 。

dula=0 。

wela=1 。

P0=0xdf 。

wela=0。

dula=1 。

P0=0x00。

// 关位码dula=0 。

}//***************************************************************void main(>{uint distance 。

单片机超声波模块的尺寸标准

单片机超声波模块的尺寸标准

单片机超声波模块的尺寸标准
对于常见的超声波传感器模块,其尺寸通常在20mm x 15mm x 15mm左右。

这种尺寸的超声波模块通常适用于小型的电子设备和嵌入式系统,例如避障小车、测距仪等。

而对于一些更复杂、功能更强大的超声波模块,其尺寸可能会更大一些,一般在30mm x 20mm x 20mm左右。

此外,一些超声波模块可能会采用不同的封装形式,例如贴片式、插件式等,这也会对其尺寸产生影响。

在选择超声波模块时,除了尺寸外,还需要考虑其工作频率、测距范围、精度等参数,以确保选择到符合需求的模块。

总的来说,单片机超声波模块的尺寸标准并不是固定的,而是根据具体的产品设计和制造商的要求而有所不同。

在使用或购买超声波模块时,最好参考具体的产品规格书或询问制造商以获取准确的尺寸信息。

基于单片机的超声波模块

基于单片机的超声波模块

基于单片机的超声波模块(Me007)测距(1602显示)模块实物图:模块使用方法:1.模块引脚从左到右(见图)模块引脚分别为VCC、trig(控制端)、echo(接收端)、out(空脚)、GND2.主要技术参数:1:使用电压:DC5V2:静态电流:小于2mA3:电平输出:高电平VCC-0.2V 低<0.2V4:感应角度:不大于15 度5:探测距离:2cm-500cm6:探测精度:3MM板上接线方式,VCC、trig(控制端)、echo(接收端)、out(空脚)、GND。

OUT 脚为此模块作为防盗模块时的开关量输出脚,测距模块不用此脚!3.使用方法:(1)采用IO 触发测距,给TRIG至少10us的高电平信号(实际上25US最佳);(2)模块自动发送8 个40khz的方波,自动检测是否有信号返回;(3)有信号通过ECHO 返回,ECHO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.本产品使用方法简单,用单片机IO口控制TRIG发一个10US以上(25US最佳)的高电平,就可以在接收口(ECHO)等待高电平输出.当ECHO 从低变到高就可以开定时器计时,当ECHO 变为低电平时就可以读定时器的值,此时就为此次测距的时间,据公式测试距离=(高电平时间*声速(340M/S))/2;方可算出距离.如此不断的周期测,就可以达到你移动测量的值了!程序:(当时我用过的,直接可以用,程序分为三模块:1602,Me007,main,下面分别给出各个文件,用51新建工程,把个文件添加到工程里就可以了,当时我用的是STC89C52)说明:本程序用的是查询法,中断法也很简单,把ECHO端(接到外部中断0端,然后把主函数while(1)的内容放到外部中断0中断服务函数里,大家自己改!main.c#include <reg52.h>#include "1602.h"#include "Me007.h"uchar code table[]="*>4M*";//***************************************************************************** //** 函数:1602显示距离函数** //** 功能:1602显示超声波模块到障碍物的距离** //** 类型:内部函数** //***************************************************************************** void Disp_1602(){uchar i;if((S>4000)||flag==1) //如果距离>2m或定时器溢出{ //(中断溢出可以算出距离>5m了) flag=0; //恢复中断溢出标志位为0,为下一次准备write1602_com(0x86); //给出显示的1602位置for(i=0;i<5;i++) //距离>5m,显示"*>5M*"{write1602_dat(table[i]);}}else //距离<=5m时1602显示出距离值{ //不显示mm位,最后显示的单位为cm write1602_com(0x86);write1602_dat(0x30+S/1000); //米位write1602_dat(0x30+S/100%10); //分米位write1602_dat(0x30+S/10%10); //毫米位write1602_dat(0x63); //"c"write1602_dat(0x6d); //"m"}}//***************************************************************************** //** 函数:主函数** //** 功能:启动超声波模块,把距离值用1602显示** //** 类型:内部函数** //***************************************************************************** void main(void){TMOD=0x01;Timer0_init(); //初始化定时器0init_LCD1602(); //LCM初始化while(1){StartModule(); //启动超声波模块if(ECHO==1) //如果ECHO变为1后打开定时器计时,{ //得出距离1602显示Count_ultrasonic();Disp_1602();}}}1602.c#include <reg52.h>#include "1602.h"//***************************************************************************** //** 函数:延时函数** //** 功能: 延时zms ** //** 参数:z为延时长度(ms) ** //** 类型:内部函数** //***************************************************************************** void delay_1602(uint z){uint x,y;for(x=0;x<=z;x++)for(y=0;y<=112;y++);}//***************************************************************************** //** 函数:1602写指令函数** //** 功能: 在1602上写入要执行的相关指令** //** 参数:com为要写入的指令数据** //** 类型:外部函数** //***************************************************************************** void write1602_com(uchar com){LCD1602_EN=0;LCD1602_RW=0; //设为写操作LCD1602_RS=0; //设为写指令操作P0=com; //写入指令delay_1602(5); //t(sp2)LCD1602_EN=1; //EN上升沿把数据读走delay_1602(5); //t(pw)LCD1602_EN=0;}//***************************************************************************** //** 函数:1602写数据函数** //** 功能: 在1602上指定位置写入要显示的内容(数据) ** //** 参数:dat为要写入的内容(数据) ** //** 类型:外部函数** //***************************************************************************** void write1602_dat(uchar dat){LCD1602_EN=0;LCD1602_RW=0; //设为写操作LCD1602_RS=1; //设为写数据操作P0=dat; //写入指令delay_1602(5); //t(sp2)LCD1602_EN=1; //EN上升沿把数据读走delay_1602(5); //t(pw)LCD1602_EN=0;}//***************************************************************************** //** 函数:1602初始化函数** //** 功能: 初始化1602液晶** //** 类型:外部函数** //** 说明:按照数据手册写的** //***************************************************************************** void init_LCD1602()delay_1602(5);write1602_com(0x38);delay_1602(5);write1602_com(0x38);delay_1602(5);write1602_com(0x38);write1602_com(0x38); //设置显示模式(5X7点阵,8位数据端口)write1602_com(0x08); //设置数据地址指针(关闭显示和光标)write1602_com(0x01); //清屏指令(数据指针和显示清零)write1602_com(0x06); //光标设置(地址指针和光标自动加1,//整屏显示不移动)write1602_com(0x0c); //显示开/关设置(开显示但不显示光标)}// *****注意:1602时以字符/数字的ASCII码显示的,所以想要显示相应的字符/数据,// *****是要把其的ASCII值写入到1602中,ASCII值可以看字符手册得到!1602.h#ifndef __1602_H__#define __1602_H__#define uint unsigned int#define uchar unsigned charsbit LCD1602_RS=P2^0; //1602数据/命令选择端sbit LCD1602_RW=P2^1; //1602读/写选择端sbit LCD1602_EN=P2^2; //1602使能信号端extern void write1602_com(uchar com); //在1602上写入要执行的相关指令extern void write1602_dat(uchar dat); //在1602上指定位置写入要显示的内容(数据) extern void init_LCD1602(); //初始化1602液晶#endifMe007.c#include <reg52.h>#include <intrins.h>#include "Me007.h"bit flag=0; //定时器中断溢出标志位uint time=0; //用于存放定时器时间值unsigned long S=0; //用于存放距离值,为4位数,单位mm//*****************************************************************************//** 函数:定时器0初始化程序** //** 功能: 初始化定时器0 ** //** 参数:无** //** 类型:外部函数** //***************************************************************************** void Timer0_init(){// TMOD=0x01; //设T0为方式1,GATE=1;EA=1;TH0=0;TL0=0; //初值为0ET0=1;}//***************************************************************************** //** 函数:启动超声波函数** //** 功能: 启动超声波** //** 参数:无** //** 类型:外部函数** //** 说明:在TRIG端给>10us的高电平即可** //***************************************************************************** void StartModule(){TRIG=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();TRIG=0;}//***************************************************************************** //** 函数:超声波距离计算函数** //** 功能: 计算超声波模块到障碍物的距离** //** 参数:无** //** 类型:外部函数** //***************************************************************************** void Count_ultrasonic(){TR0=1; //打开定时器,开始计时while(ECHO); //当ECHO为1时计入循环,让定时器计时TR0=0; //如果ECHO变为0关闭计数//*** 然后计算定时器值time ***time=TH0*256+TL0;//定时器每加1时间为振荡周期的12倍TH0=0;TL0=0; //重新恢复定时器初值为0,为下一次计时做准备S=time*0.17; //距离S=声速(340m/s*time),最后算出单位为mm }//***************************************************************************** //** 函数:定时器0中断处理函数** //** 功能: 用于计算ECHO端高电平时间** //** 类型:中断处理函数函数** //***************************************************************************** void Timer0() interrupt 1{flag=1; //中断溢出标志(中断溢出可以算//出距离远远>5m了)ECHO=0;}Me007.h#ifndef __Me007_H__#define __Me007_H__#define uint unsigned int#define uchar unsigned charsbit TRIG=P1^0; //TRIG端sbit ECHO=P1^1; //ECHO端extern bit flag; //量程溢出标志位extern unsigned long S; //用于存放距离值,为4位数,单位mm extern void Timer0_init(); //初始化定时器0extern void StartModule(); //启动超声波模块函数extern void Count_ultrasonic(); //计算超声波模块到障碍物的距离#endif。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
cache[4]=distance%10;
table2[0]=cache[1]+'0';
table2[1]=cache[2]+'0';
table2[2]=cache[3]+'0';
table2[4]=cache[4]+'0';
write_com(0x80+2);
delay(20);
for(a=0;a<13;a++)
调试测量的部分测距数据如下表所示:
测试序号
显示距离(m)
实际距离(m)
误差(m)
1
0.035
0.034
0.001
2
1.00
1.00
0
3
1.257
1.255
0.002
4
1.364
1.365
0.001
5
2.148
2.147
0.001
调试测量的部分数据
八、设计体会与收获
本次试验目的为设计利用超声波传输中距离与时间的关系,采用STC51单片机进行控制和数据处理,设计出能够精确测量两点间距离的超声波测距仪。我们这次设计共有三个模块,分别是超声波模块,显示屏模块和报警模块。一开始搭建完成后,在调试的时候出现了很多问题,后来经过重新检查,最后才完成。
4.其他电路设计
a.复位电路
单片机在RESET端加一个大于20ms正脉冲即可实现复位,上电复位和按钮组合的复位电路如下:
图6复位电路
在系统上电的瞬间,RST与电源电压同电位,随着电容的电压逐渐上升,RST电位下降,于是在RST形成一个正脉冲。只要该脉冲足够宽就可以实现复位,即((RC(20ms。一般取R(1K(,C(22uF。当人按下按钮S1时,使电容C1通过R1迅速放电,待S1弹起后,C再次充电,手动复位。R1一般取200(。
trig=0;
while(echo==0);
flag=0;
EA=1;
EX0=1;
TR0=1;
TH0=0;
TL0=0;
sbit test=P1^3;
sbit dula=P2^6;
sbit wela=P2^7;
sbit BEEP=P2^3;
sbit rs=P1^0;
sbit rw=P1^1;
sbit lcden=P2^5;
sbit k1=P3^4;
uchar table1[]={"Distance Test:"};
uchar table2[]={"000.0cm"};
附录Ⅰ:超声波测距仪系统电路原理图
图11超声波测距仪系统电路原理图
附录Ⅱ:程序代码
`#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit trig=P1^2;
sbit echo=P3^2;
}
void write_date(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void init()
{
rw=0;
dula=0;
wela=0;
write_com(0x38);
delay(20);
write_com(0x0f);
b.时钟电路
当使用单片机的内部时钟电路时,单片机的XATL1和XATL2用来接石英晶体和微调电容,如图所示,晶体一般可以选择3M~24M,电容选择
30pF左右。我们选择晶振为12MHz,电容33pF。
图7时钟电路
图8按键电路
c.按键电路
我们通过P1.0来启动测量,程序中通过查询P1.0的电平来检测是否按键被按下,电路原理如下:
六、问题分析与解决方法
1.在拿到设计要求之后,我们根据超声波模块的工作原理:给超声波传感器模块一个触发电平,超声波传感器的发射管自动发送8个40KHZ的方波,当超声波检测到障碍物时就会信号返回,接收管接收到信号返回之后,单片机处理从单片机发送信号到接收到返回信号这段时间里超声波传感器模块输出高电平。这段高电平持续时间即为超声波从发射到返回的传播时间。测量距离=(高电平持续时间*波速)/2。我们的设计方案是利用计数器0进行计数,通过捕获上升沿和下降沿用计数器来计算高电平的持序时间,实现数据的测量。而且经讨论学习后知道,高电平持续时间=计数值×单片机的机器周期(1us)。
2.在设计数码管显示电路时,在刚开始连接电路时,发现连好之后,数码管不亮,最后我们分析电路,单片机IO口输出电流太小,不足以驱动数码管,于是我们加了一个与门的驱动器,使之前的3A电流变为5A,由此数码管就足以驱动。
七、设计结果
a.测试环境及工具
测试距离:在实验室的特定环境中测量了0.03~2.15m。
{
write_date(table1[a]);
delay(20);
}
write_com(0xc0+9);
delay(50);
for(a=0;a<13;a++)
{
write_date(table2[a]);
delay(40);
}
}
void shixi()
{EA=0;
echo=1;
trig=1;
delay20us();
for(b=100;b>0;b--);
}
void delay20us()
{ uchar a;
for(a=0;a<100;a++);
}
/*void beer()
{
BEEP=0;
delay2(10);
}*/
void initime0()
{
TMOD=0x01;
TH0=0;
TL0=0;
EA=0;
ET0=0;
西安邮电大学
通信与信息工程学院
课程设计实验报告
专业班级:电科1003班
学生姓名:易海博
学号(班内序号):03102085(13)
2014年3月25日
成绩鉴定表
学生姓名
易海博
班级/学号
电科1003班/03102085
进行时间
2014年3月1日—2014年3月28日
成绩鉴定
学习内容(20分)
与教学任务计划结合程度(10分)
delay(20);
write_com(0x06);
delay(20);
write_com(0x01);
delay(20);
}
void display(distance)
{
uchar a;
cache[1]=distance/1000;
cache[2]=distance%1000/100;
cache[3]=distance%100;
EX0=0;
}
voidestern() interrupt 0
{ timeh=TH0;
timel=TL0;
flag=1;
EX0=0;
TR0=0;
}
void write_com=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
年月日
超声波测距模块设计
一.设计目的
本设计利用超声波传输中距离与时间的关系,采用STC51单片机进行控制和数据处理,设计出能够精确测量两点间距离的超声波测距仪。同时了解单片机各个管脚的功能,工作方式,计数/定时,I/O口相关的原理,并了解学习单片机的相关内容知识。
二.设计要求
设计一个超声波测距仪,能够用1602屏实时显示测量的数据,并要求设定一定距离下提示报警。
测试仪器:数字万用表,直尺。
b.测试方法
超声波测距测距仪的硬件电路制作完成并调试好后,便可将程序编译好下载到单片机试运行。用直尺确定障碍物的距离,数码管显示测量的距离。
c.测试结果分析
测距仪能测的范围为0.03~2.15m,测距仪最大误差不超过1cm。系统调试完后应对测量误差和重复一致性进行多次实验分析,不断优化系统使其达到实际使用的测量要求。由于条件有限,我们忽略温度的影响,不进行温度补偿,声速选取340m/s.
这次课程设计虽然只有短短两周的时间,但却是一次难得的理论与实践相结合的机会,以前只是在书本上学习到单片机可以实现的很多功能,但却没有机会实践,通过本次课程设计我不光复习了模电知识及单片机知识,锻炼了动手能力,同时也熟悉掌握了proteus仿真软件和Protel电路设计软件的使用。
对于我们电科专业的学生来说,Proteus和Protel是必须掌握的电路仿真软件,这次课程设计给我提供了一个很好的机会,让我可以很好地锻炼自己的实践能力。总的来说,此次实习还是收获颇丰的,很感谢学校可以给我们提供这样的一次机会。
当按下按键时P1.0为低电平,单片机通过查询到低电平
开始测量距离,当松开按键,P1.0即为高电平。在软件中通过软
件延时来消除按键的机械抖动。
5.软件程序设计
软件分为两部分,主程序和中断服务程序。主程序完成初始化工作、超声波发射和接收顺序的控制。外部中断服务子程序主要完成时间值的读取、距离计算、结果的输出、数码管显示等工作。
超声波测距的算法设计:超声波在空气中传播速度为每秒钟340米(15℃时),x1是声波返回的时刻,x2是声波发声的时刻,x2-x1得出的是一个时间差的绝对值,则超声波发出遇到反射物返回的距离如下1
相关文档
最新文档