找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 985|回复: 0
打印 上一主题 下一主题
收起左侧

基于51单片机的超声波测距程序 Proteus仿真图

[复制链接]
跳转到指定楼层
楼主
可以设定超声波测距的报警范围,显示超声波距离
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1.     #include <REGX52.H>
  2.     #include "LCD1602.h"                //LCD1602头文件
  3.     #include "Delay.h"                        //延时
  4.     #include "Timer0.h"                        //定时0头文件
  5.     #include "Timer1.h"                        //定时1头文件

  6.     //定义各种参数
  7.     unsigned short Distance;
  8.     unsigned char i;
  9.     unsigned long DisH,DisL;
  10.     unsigned int T0Count;
  11.     unsigned char Time;
  12.     unsigned int a,b;
  13.     sbit Trig = P3^6;                                //定义两个超声波管脚
  14.     sbit Echo = P3^7;

  15.     sbit  set = P3^0;                                //切换模式
  16.     sbit up = P3^1;  //加
  17.     sbit down = P3^2; //减

  18.     sbit  yled = P2^1;                                
  19.     sbit gled = P2^2;  
  20.     sbit rled = P2^3;
  21.     sbit beep = P3^5;

  22.     unsigned char Flag;//测量标志位0.5秒触发一次
  23.     unsigned char nodis;//超出量程

  24.     unsigned int mode;
  25.     unsigned int change;
  26.     unsigned int waring;
  27.     unsigned int upper = 120;//上限
  28.     unsigned int lower = 50;//下限

  29.     //超声波初始化
  30.     void Super_Wave_Init()
  31.     {
  32.             Trig = 0;
  33.             Echo = 0;
  34.     }





  35.     //

  36.     /**************************************************
  37.     距离测量
  38.     **************************************************/
  39.     void Measure(void)
  40.     {
  41.         unsigned char Err; //错误标记
  42.         unsigned long distance,pTime;//距离,时间变量
  43.         Err=0;
  44.         Trig=1;     //TR保持10us高电平触发模块测距
  45.         Delay10Us();
  46.         Trig=0;
  47.         TH0=0;
  48.         TL0=0;
  49.         while(Echo==0);//等待ECHO变为高
  50.         TR0=1;       //启动定时器,外部高电平触发
  51.         while(Echo==1)//等待超声波回应获超时
  52.         {
  53.             pTime=TH0*256+TL0;
  54.             if(pTime>40000)//时间超时
  55.             {
  56.                 Err=1;
  57.                 break;
  58.             }
  59.         }
  60.         TR0=0;//关闭定时器
  61.         pTime=TH0*256+TL0; //获取时间
  62.                   
  63.         if(Err==0)
  64.         {
  65.             
  66.             distance=(pTime*173)/1000;//;pTime*346/1000000/2=pTime*0.0173 仿真的环境温度为25度346m/s
  67.                                     DisH = distance/10;
  68.                                     DisL = distance%10;
  69.                   
  70.                                     if((DisH>170)||(DisH<2))//量程170cm,超过量程显示0;测量距离小?cm,HCSR04最小测算2cm
  71.             {
  72.                Err=1;   
  73.                                                    
  74.             }
  75.                                     else if(DisH>upper)
  76.             {
  77.                gled = 0;
  78.                                                     yled = 1;
  79.                                             rled = 1;
  80.                                             beep = 1;
  81.             }
  82.                                     else if((DisH>=lower)&&(DisH<=upper))
  83.             {
  84.                gled = 1;
  85.                                             yled = 0;
  86.                                             rled = 1;
  87.                                             if(waring == 0)
  88.                                             {
  89.                                                     beep = 1;
  90.                                             }
  91.                                             else
  92.                                             {
  93.                                                     beep = 0;
  94.                                             }
  95.             }
  96.                                     else if(DisH<lower)
  97.             {
  98.                                                    
  99.                gled = 1;
  100.                                                     yled = 1;
  101.                                                     rled = 0;
  102.                                             beep = 0;
  103.                                             if(waring == 0)
  104.                                             {
  105.                                                     LCD_ShowString(2,1,"warning");
  106.                                             }
  107.                                             else
  108.                                             {
  109.                                                             LCD_ShowString(2,1,"                 ");
  110.                                             }
  111.                                           
  112.             }
  113.                                     
  114.                                     
  115.                     }
  116.                     if(Err == 1)
  117.                             {
  118.                                     nodis = 1;
  119.                                             gled = 1;
  120.                                                     yled = 1;
  121.                                             rled = 1;
  122.                                             beep = 1;                        
  123.                     }
  124.             }

  125.     void outkey()
  126.     {
  127.             if(set == 0)
  128.             {
  129.                             //Delay(8);
  130.                     mode++;
  131.                     change = 1;
  132.                     if(mode>2)
  133.                     {
  134.                             mode = 0;
  135.                     }
  136.                     while(set == 0);
  137.             }
  138.             switch(mode)
  139.             {
  140.                     case 0://正常读数模式
  141.                     if(change == 1)
  142.                     {
  143.                             change = 0;
  144.                   
  145.                     LCD_ShowString(1,1,"distance:");
  146.                     LCD_ShowString(1,15,"cm");
  147.                     LCD_ShowString(1,13,".");
  148.                     LCD_ShowString(2,1,"                 ");
  149.                     }
  150.                             if(Flag)//每500ms测量一次
  151.          {
  152.              Flag=0;
  153.              Measure();//测量
  154.                              if(nodis == 0)
  155.                              {
  156.                                     LCD_ShowNum(1,10,DisH,3);
  157.                                     LCD_ShowNum(1,14,DisL,1);
  158.                              }
  159.                              else
  160.                              {
  161.                                             nodis = 0;
  162.                                      LCD_ShowString(1,10,"-");
  163.                                             LCD_ShowString(1,11,"-");
  164.                                             LCD_ShowString(1,12,"-");
  165.                                             LCD_ShowString(1,14,"-");
  166.                              }                        
  167.           }
  168.                      break;
  169.                     case 1://改下限
  170.                             if(change == 1)
  171.                     {
  172.                             change = 0;
  173.                             LCD_ShowString(2,1,"upper:");
  174.                             LCD_ShowNum(2,7,upper,3);
  175.                             LCD_ShowString(2,10,"       ");
  176.                             LCD_ShowString(1,1,"lower:");
  177.                             LCD_ShowNum(1,7,lower,3);
  178.                             LCD_ShowString(1,10,"       ");
  179.                            
  180.                     }
  181.                             if(up == 0)
  182.                             {
  183.                                     lower++;
  184.                                     LCD_ShowNum(1,7,lower,3);
  185.                                     while(up == 0);
  186.                             }
  187.                             if(down == 0)
  188.                             {
  189.                                     lower--;
  190.                                     LCD_ShowNum(1,7,lower,3);
  191.                                     while(down == 0);
  192.                             }
  193.                             break;
  194.                             case 2://改上限
  195.                             if(change == 1)
  196.                     {
  197.                             change = 0;
  198.                             LCD_ShowString(2,1,"upper:");
  199.                             LCD_ShowNum(2,7,upper,3);
  200.                             LCD_ShowString(2,10,"       ");
  201.                             LCD_ShowString(1,1,"lower:");
  202.                             LCD_ShowNum(1,7,lower,3);
  203.                             LCD_ShowString(1,10,"       ");
  204.                            
  205.                     }
  206.                             if(up == 0)
  207.                             {
  208.                                     upper++;
  209.                                     LCD_ShowNum(2,7,upper,3);
  210.                                     while(up == 0);
  211.                             }
  212.                             if(down == 0)
  213.                             {
  214.                                     upper--;
  215.                                     LCD_ShowNum(2,7,upper,3);
  216.                                     while(down == 0);
  217.                             }
  218.                             break;
  219.                             default:break;
  220.                            
  221.             }

  222.     }

  223.     //主函数
  224.     void main()
  225.     {
  226.             LCD_Init();
  227.             Timer0Init();      //该定时器没有写TR0.
  228.             Timer1Init();
  229.             LCD_ShowString(1,1,"distance:");
  230.             LCD_ShowString(1,15,"cm");
  231.             LCD_ShowString(1,13,".");
  232.             while(1)
  233.             {
  234.                   
  235.                     outkey();

  236.                   
  237.             }
  238.     }






  239.     /**************************************************
  240.     定时器1中断服务
  241.     **************************************************/
  242.     void Time1_Isr() interrupt 3
  243.     {        
  244.             static unsigned char value;                         //定时2ms中断一次
  245.             TH1 = (65536-2000)/256;
  246.             TL1 = (65536-2000)%256;     //2ms
  247.     //        smgDis();                //数码管显示函数
  248.             value++;
  249.             if(value >= 250)//250次2ms中断总时间位500ms
  250.             {
  251.                     value = 0;
  252.                     Flag = 1;
  253.                     waring ++;
  254.             }
  255.             if(waring>1)
  256.             {
  257.                     waring = 0;
  258.             }
  259.     }
复制代码

Keil代码与Proteus仿真下载: 超声波.7z (85.15 KB, 下载次数: 75)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶2 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表