> 文档中心 > 基于Proteus的51单片机超声波测距

基于Proteus的51单片机超声波测距

        之前发过一期使用51单片机开发板完成的超声波测距。今天再发一个基于Proteus仿真的超声波测距。Proteus8.0之前的版本中都没有超声波测距这个模块,所以在Proteus7的软件中大部分超声波测距仿真都是采用的网友自制的超声波测距模块,自制的模块在仿真时交互性不是很友好,所以今天分享的仿真是基于Proteus8.8版本。文章的最后会告知如何仿真和软件的下载方式。

超声波测距模块SRF04

        超声波测距模块在Proteus中的名称叫做SRF04,它的工作原理与之前文章中介绍的超声波模块工作原理一致,都是通过一个IO控制超声波模块的发射,通过另外一个IO对超声波接收端的信号进行检测,计算出超声波信号的运动时间,进而计算出模块与障碍物之间的距离。

测距原理

        原理方面就不在多说了,贴一下仿真图。

Proteus仿真图

        今天分享的超声波测距仿真如图所示,显示部分使用的是LCD1602,由于声波在不同温度下的传播速度不同,所以仿真中使用DS18B20对环境温度进行采集,以便实现超声波的温度补偿。

 

部分程序截图

        检测部分程序如上图所示,程序的大致流程为显示初始化->外设初始化->检测DS18B20温度->发送超声波并启动定时器->等待声波信号返回->计算距离->判断距离是否在范围内->更新显示->进入下一个循环。

程序流程

        仿真运行图

仿真运行时效果如图所示。在该仿真的基础上增加按键、蜂鸣器等外设就可以实现倒车雷达的功能。有兴趣的小伙伴可以自行下载研究。

        Proteus8.8软件可以在公众号主页发送”Proteus”,系统即可自动回复对应的下载链接。

        本文分享的仿真及程序可以在公众号发送”超声波测距仿真”获取相应的下载链接。

下面贴一下主程序。

#include "reg51.h"#include #include "LCD.H"#include "18B20.H"#include "delay.h"sbit csb=P2^5; //超声波发送引脚sbit csbint=P3^2; //超声波接收引脚unsigned char aa[]={' ',' ','D','i','s','t','a','n','c','e',':'};    //Distanceunsigned char bb[11]={' ',' ',' ',' ','.',' ',' ',' ',' ',' ',};unsigned char cc[]={'A','.','A','A','m'};unsigned char zf;     //zf 温度正负标志位                                              unsigned int s,j,bgz,k;int temp;float temperature,csbc,wdz;   //温度及温度补偿变量void main(void){TH0=0;TL0=0; //定时器0计数器清0TMOD=0X11; //T1,T0为16位定时器EA=0; //关闭总中断  init(); //初始化Init_DS18B20(); //DS18B20初始化bb[6]=0xdf; //显示摄氏度符号bb[7]=0x43;LCD_Write_String(0,0,aa); //对数据进行显示while(1){temp=ReadTemperature(); //读取DS18B20温度数据DelayMs(100); //延时100毫秒if(temp=2500) //如果达到一定时间没有收到回波,则将csbint置零,退出接收回波处理程序csbint=0;}TR0=0; //关闭定时器0s=TH0*256+TL0; //读取时间数据TH0=0; //定时器清0TL0=0;wdz=0.00000607*temp;    //计算温度补偿值if(zf==0){   csbc=0.03315+wdz; //对超声波速度进行温度补偿,温度为正值时+,温度为负值时-}else csbc=0.03315-wdz;csbc=csbc/2; //s=s*csbc-4; //速度*时间=位移if(s500) //测量值大于上限{cc[0]='C';cc[2]='C'; //测量距离大于上限值,显示CCCcc[3]='C';}else{cc[0]=s/100+'0';cc[2]=s/10%10+'0'; //距离在范围内,显示距离数值cc[3]=s%10+'0';}//显示测量的温度bb[1]=temp/1000+0x30;bb[2]=temp/100%10+0x30; //显示十位bb[3]=temp%100/10+0x30; //显示个位bb[5]=temp%10+0x30; //小数      if(zf==0)   {if(temp<1000){    bb[1]=' ';    if(temp<100)    {       bb[2]=' ';}}}else{if(temp<1000){    bb[1]='-';    bb[0]=' ';    if(temp<100)    {bb[0]=' ';    bb[1]=' ';       bb[2]='-';}}}LCD_Write_String(4,1,bb);LCD_Write_String(11,0,cc);}}