单片机超声波测距模块
- 格式:doc
- 大小:272.50 KB
- 文档页数:15
51入门系列教程超声波测距模块编程Revision0.01(2011-10-18)刚好这次做机器人用到了超声波,才开始看它的工作原理,感觉还很简单,但是调试到最后,发现了很多问题,该碰到的都碰到了,趁着写单片机入门教程的机会,写出来分享给大家。
先把超声波的工作原理贴出来:从超声波的工作原理可以知道,其实只要单片机的两个引脚就足够,一个引脚接发送端,一个引脚接接收端即可。
工作时,发送端引脚置高电平10us时间的脉冲,这将激发超声波模块发送8个40khz周期的电平信号,然后模块的收端开始检测回波(实际上,两个眼睛,一个是发送的,一个是用来接收的)。
一旦发现有回波信号,就会输出一个响应给接收端引脚,这个响应是一个高电平脉冲。
所以,我们只要在接收端去检测是否有高电平脉冲即可。
但从程序编写与调试的过程来看,并没有那么简单。
因为超声波第一次发送40KHZ的信号出去后反射回来,有可能又被反弹回去,这样以来,相当于超声波在两个障碍物之间不断地来回反弹,导致接收端不断地收到”回波信号“——实际上第一次反弹回来的才是回波信号,其他的都是二次、三次...的反弹回波信号。
如果每次检测到回波就让蜂鸣器响一次,那么,我们程序运行时,可能会听到蜂鸣器不断地响,可能就是这个原因。
另外,需要关注的是,超声波如果前面没有障碍物,也会在接收端引脚上故意输出140us的电平,以”防止发射信号对回响信号的影响“。
从上面的分析看来,不管超声波前面有无障碍物,接收端引脚肯定都会出现高电平脉冲。
所以我们在编程时,必须过滤掉这140us。
讲完超声波的工作原理,我们来看下编写程序的思路。
由于超声波可能会连续收到回响信号,导致接收端不断出现高电平脉冲,而实际上,我们有用的仅仅是第一次反射回来的回响信号,因此,使用”查询接收端引脚是否出现高电平“的方法行不通。
可以使用外部中断,只检测第一次反射回来的信号,后续的反射信号全部丢弃不管。
下面看下140us的处理。
超声波模块原理图:发射接收原理图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超声波测距模块实验硬件环境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单片机的超声波测距模块设计年级: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程序(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报:西安邮电大学通信与信息工程学院课程设计实验报告装订线————————————————————————————————1003班专业班级:电科易海博学生姓名: 13 ()(学号班内序号): 03102085 25 月 3 2014 年日成绩鉴定表超声波测距模块设计一.设计目的本设计利用超声波传输中距离与时间的关系,采用STC51单片机进行控制和数据处理,设计出能够精确测量两点间距离的超声波测距仪。
同时了解单片机各个管脚的功能,工作方式,计数/定时,I/O口相关的原理,并了解学习单片机的相关内容知识。
二.设计要求设计一个超声波测距仪,能够用1602屏实时显示测量的数据,并要求设定一定距离下提示报警。
三.设计器材元器件数量电阻 2个HC-SR04(超声波测距模块) 1片HJ1602A(液晶显示模块) 1片单片机最小系统板 1个四.超声波测距原理在超声探测电路中,发射端得到输出脉冲为一系列方波,其宽度为发射超声的时间间隔,被测物距离越大,脉冲宽度越大,输出脉冲个数与被测距离成正比。
超声测距有以下方法:?取输出脉冲的平均值电压,该电压(其幅值基本固定)与距离成正比,测量电压即可测得距离;?测量输出脉冲的宽度,即发射超声波与接收超声波的时间间隔t,故被测距离为S=1/2vt。
本测量电路采用第二种方则可认为声速基本不变。
如果温度变化不大,由于超声波的声速与温度有关,案。
.如果测距精度要求很高,则应通过温度补偿的方法加以校正。
超声波在标准空气中的传播速度为331.45m/s,由单片机负责计时,单片机使用12.0M晶振。
超声波测距的算法设计:超声波在空气中传播速度为每秒钟340米(15℃时),x1是声波返回的时刻,x2是声波发声的时刻,x2-x1得出的是一个时间差的绝对值,则超声波发出遇到反射物返回的距离如下1超声波测距器的系统框图如下2图1图2 系统框图五、设计方案及分析(包含设计电路图)硬件电路设计1.单片机最小系统控制模块设计与比较采用STC51单片机控制。
基于51单片机的超声波测距模块By 黄阿阿阿厉第1章HC-SR04超声波测距模块说明1.1 产品特点HC-SR04超声波测距模块能提供2~400cm的非接触式距离感测功能,测量精度可以达到3mm;该模块包括超声波发射器、接收器与控制电路。
1.2 产品介绍HC-SR04模块实物如图1.1所示,引脚如图所示,从上到下分别为VCC,Trig,Echo和GND。
VCC,GND连接电源,Echo和Trig连接51单片机的引脚。
图1.1 HC-SR04模块实物图HC-SR04超声波电气参数如表1.1所示。
表1.1 HC-SRO4电气参数HC-SRO4超声波模块的时序图如图1.2所示。
图1.2 HC-SRO4的时序图HC-SR04的实物规格如图1.3所示。
图1.3 模块尺寸1.3 注意事项HC-SR04超声波模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。
使用该模块测距时,被测物体的面积不少于0.5平方米平面。
且平面要求尽量平整,否则会影响测量的结果。
1.4 模块分析根据时序图可以知道,只需通过单片机向模块的Trig端提供一个10us以上的脉冲出发信号,该模块内部将会发出8个40KHz的脉冲,并开始检测回波。
一旦检测到有回波信号则输出回响信号。
回响信号的脉冲宽度与所测的距离成正比。
通过检测开始发射信号到收到回响信号的时间间隔,就可以计算得到距离。
根据时序图,这样的方式可能会存在误差,即误差是声音在空气的传播速度并不固定,虽然有一个标准的声速值V=340m/s,但是实际的声速并不固定,所以计算出来的数值在不同的地区会存在差异。
因为资料不足,这里我有一个猜测。
Echo输出电平置零的时刻应该是模块不再接受到回波信号的那一刻,这样,官方提供的计算方法才能说得通。
第2章程序和说明2.1 硬件平台说明本次测试使用的硬件平台,是手创科技提供的51单片机开发板,使用的单片机型号是STC89C52RC。