加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

超声波测距仪仿真

(2017-05-29 13:10:39)
标签:

超声波测距仪仿真

超声波测距

仿真

    超声波测距仪仿真,这个问题困扰着很多单片机毕业设计的人员,现在,做超声波测距仪毕业设计的课题,指导教师都要求进行超声波测距仪仿真,通过PROTEUS软件对所设计的超声波测距仪程序进行仿真,有没有软件的情况下,检验所设计的超声波测距仪功能及正确性进行检验。对于超声波测距仪仿真这个要求,真是难住了做超声波测距仪的人员。有没有解决超声波测距仪仿真这个问题的方法,回答是肯定的,有。具体是什么样的呢?这要从超声波测距仪的工作原理说起,超声波测距仪的工作过程是(这里用HC-SR04模块为例进行说明):先由单片机产生测距控制HC-SR04模块触发信号,送HC-SR04超声波模块,收到触发高电平信号后,HC-SR04模块产生超声波信号由超声波发射头发射出去,经过一段时间碰到物体之后,产生反射回波,回波经过一段时间后,被超声波接收头接收到并送回单片机中进行处理。单片机得到一个时间数值,之后换算成距离值进行显示。知道这一原理后,解决超声波测距仪仿真这一问题时,就好办了。由于仿真软件中没有超声波发射、接收头的仿真模型,这给单片机超声波测距仿真带来困难,为验证单片机超声波测距系统单片机部分及相应程序的正确与否,我想出来的个办法,在单片机发出超声波信号后,用555时基电路产生一个延时信号,模拟超声波头发送后遇到回波返射回来的这阶段时间,来对单片机超声波测距仪仿真进行模拟。踏实证明,用这一方法,能较为完美的实现超声波测距仪仿真,实际使用下来,仿真效果良好,可用这一方法来验证超声波测距仪的单片机程序的功能及正确性,实现单片机超声波测距仪仿真
    下面附上由 电子乐屋 设计制作的超声波测距仪的程序及仿真图。


#include "REGX52.H"
#include "intrins.h"
#define uint unsigned int
#define uchar unsigned char
sbit rs=P2^0;      //液晶显示屏1602的数据/指令选择控制线
sbit rw=P2^1;      //液晶显示屏1602的读写控制线
sbit en=P2^2;      //液晶显示屏1602的使能控制线
sbit trig=P2^5;    //hc-sr04超声波测距模块Trig
sbit echo=P3^2;    //hc-sr04超声波测距模块Echo
bit flag1;         //hc-sr04触发信号标志位//
uchar count;           //单片机中断累加变量
long int distance;    //超声波测距仪测量所得到的距离值
unsigned char code table[ ]={"0123456789"}; //定义1602液晶显示屏字符数组显示数字
 
void delay(uint n)       //延时程序                   
{
    uint x,y;            //延时程序的延时变量
    for(x=n;x>0;x--)     //延时程序的延时循环
    for(y=110;y>0;y--);  //延时程序的延时循环
}
 
void delayt(uint x)//延时程序
{
    uchar j;         //延时程序的延时变量
    while(x-- > 0)   //延时程序的延时循环
    {
              for(j = 0;j < 125;j++)
        {
          ;
        }
    }
}
 
void lcd_wcom(uchar com)           
{
    rs=0;                //1602液晶显示屏选择指令寄存器
    rw=0;               //1602液晶显示屏选择写
    P0=com;            //1602液晶显示屏把命令字送入P0
    delay(5);         //1602液晶显示屏延时一小会儿,让1602准备接收数据
    en=1;            //1602液晶显示屏使能线电平变化,命令送入1602的8位数据口,这点非常重要
    en=0;
 }
 
void lcd_wdat(uchar dat)       
{
    rs=1;             //1602液晶显示屏选择数据寄存器
    rw=0;            //1602液晶显示屏选择写
    P0=dat;         //1602液晶显示屏把要显示的数据送入P0
    delay(5);      //1602液晶显示屏延时一小会儿,让1602准备接收数据,也就是检测忙信号,这点非

常重要。
    en=1;         //1602液晶显示屏使能线电平变化,数据送入1602的8位数据口
    en=0;
  }
 
void lcd_init()             
{
    lcd_wcom(0x38);       //1602液晶显示屏8位数据,双列,5*7字形  ,用到功能设定指令    
    lcd_wcom(0x0c);      //1602液晶显示屏开启显示屏,关光标,光标不闪烁,用到显示开关控制指令
    lcd_wcom(0x06);     //1602液晶显示屏显示地址递增,即写一个数据后,显示位置右移一位,用到

了写入模式设置指令
    lcd_wcom(0x01);    //1602液晶显示屏清屏,用到了清屏指令
}
 
void lcd_xianshi()             
{
    lcd_wcom(0x80+0x40);   //1602液晶显示屏第二行显示
        lcd_wdat('D');     //1602液晶显示屏显示D
        lcd_wdat('i');    //1602液晶显示屏显示i
        lcd_wdat('s');    //1602液晶显示屏显示s
        lcd_wdat('t');    //1602液晶显示屏显示t
        lcd_wdat('a');    //1602液晶显示屏显示a
           lcd_wdat('n');    //1602液晶显示屏显示n
        lcd_wdat('c');    //1602液晶显示屏显示c
        lcd_wdat('e');    //1602液晶显示屏显示 e
        lcd_wdat(':');    //1602液晶显示屏显示 :
        lcd_wcom(0x80+0x4c);
        lcd_wdat('.');
        lcd_wcom(0x80+0x4e);//602液晶显示屏显示单位 厘米//
        lcd_wdat('c');     //602液晶显示屏显示c
        lcd_wdat('m');//602液晶显示屏显示m
}
 
void init_t0()         //单片机中断处理程序
{
        TMOD=0x01;        
         TL0=0x66;
        TH0=0xfc;              //1ms
    ET0=1;            
        EA=1;                      
}
 
void trigger()              //单片机发出控制HC-SR04模块的控制信号
{
    trig=1;                 //送HC-SR04控制端高电平
               _nop_();        //单片机延时1微秒
               _nop_();      //单片机延时1微秒
               _nop_();      //单片机延时1微秒
               _nop_();     //单片机延时1微秒
               _nop_();//单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
                  _nop_();    //单片机延时1微秒
               _nop_();    //单片机延时1微秒
     trig=0;      //送HC-SR04控制端低电平
}
 
void init_measuring() 
{
        trig=0;
        echo=1;
        count=0;
}
 
void measuring()       //获取距离函数
{
        uchar l;
        uint h;
        TR0 = 1;
        while(echo==1)
        {
           ;
        }       
        TR0 = 0;
        l = TL0;
        h = TH0;
        distance =h*256+l;//  计算总时间,单位是微秒
        TL0 =0;
        TH0 =0;
        delayt(30);
        distance = 3400* distance / 20000;//    单位原始为:(0.34毫米/us)*时间/2//       
}
 
void display(uint x)
{
        uchar qian,bai,shi,ge;
        qian=x/1000;
        bai=(x/100);
        shi=(x/10);
        ge=x;
        lcd_wcom(0x80+0x49);//    距离单位是厘米//
        lcd_wdat(table[qian]);
        lcd_wdat(table[bai]);
        lcd_wdat(table[shi]);
        lcd_wcom(0x80+0x4d);
        lcd_wdat(table[ge]);
}
 
void main()           
{   lcd_init();          //1602液晶显示屏液晶初始化       
    init_t0();          //定时器0初始化  
        init_measuring();  //超声波相应端口初始化
        while(1)
        {
          lcd_xianshi();   //液晶显示特定字符
          trigger();      //触发超声波启动
                  while(echo==0)          //等待回声
                  {
                         ;
                  }
            measuring();           //  进行距离测量
            display(distance);    //  对测量结果进行显示
            init_measuring();    //  超声波相应端口初始化
            delayt(600);        //  每次测量间隔60ms
        }
}
//////////////////////////////////////中断服务函数/////////////////////
void T_0()interrupt 1
{
        TF0 = 0;
        TL0 = 0x66;
        TH0 = 0xfc;
        count++;
        if(count==18)
        {
          TR0 =0;
          TL0 = 0x66;
          TH0 = 0xfc;
          count = 0;
        }
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有