找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机hc-sr04超声波测距(脉宽测量)DEMO程序

[复制链接]
跳转到指定楼层
#

单片机源程序如下:
  1. /***********************************************************************************************************/
  2. //hc-sr04 超声波测距模块DEMO程序
  3. //晶振:11。0592
  4. //接线:模块TRIG接 P0.2  ECH0 接P0.1
  5. //数码管:共阳数码管P1接数据口,P2.5 P2.4 P2.3接选通数码管
  6. /***********************************************************************************************************/            
  7.                      #include <reg51.h>                //器件配置文件
  8.                          #include <intrins.h>
  9.                          #define uchar unsigned char
  10.              #define uint unsigned int
  11.                          unsigned int  time=0;
  12.                          unsigned int  timer=0;
  13.                          unsigned char posit=0;
  14.                          unsigned long S=0,S1,S2;
  15.                          bit      flag =0;
  16.              sbit  TX123=P3^4;   //T
  17.                          sbit  RX123=P3^5;   //E
  18.              sbit  KJA=P3^6;     //近距离存储按钮
  19.                          sbit  KJAN=P3^7;    //远距离存储按钮
  20.              sbit  S1J=P3^3;     //近距离动作继电器
  21.                          sbit  S2J=P3^2;     //远距离动作继电器
  22.          
  23.                          unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
  24.                          unsigned char const positon[3]={ 0xdf,0xef,0xf7};
  25.                     unsigned char disbuff[4]={ 0,0,0,0,};

  26. /******************定义命令字节******************/     
  27. #define Read_COM    0x01                     //字节读数据命令   
  28. #define Prog_COM    0x02                    //字节编程数据命令   
  29. #define Erase_COM    0x03                   //扇区擦除数据命令   
  30. #define En_Wait_TIME    0x81                //设置等待时间 ,并使能ISP/IAP      
  31. #define Start_ADDRH 0x20                    //扇区地址高位   
  32. #define Start_ADDRL 0x00                    //扇区地址低位
  33. /****************特殊功能寄存器声明****************/
  34. sfr ISP_DATA = 0xe2;
  35. sfr ISP_ADDRH = 0xe3;   
  36. sfr ISP_ADDRL = 0xe4;
  37. sfr ISP_CMD = 0xe5;
  38. sfr ISP_TRIG = 0xe6;   
  39. sfr ISP_CONTR = 0xe7;

  40. /*****************关闭ISP&IAP功能*****************/   
  41. void ISP_IAP_disable(void)   
  42. {   
  43.     ISP_CONTR = 0x00;   
  44.     ISP_CMD = 0x00;   
  45.     ISP_TRIG = 0x00;   
  46. }   
  47. /*********************字节读**********************/     
  48. uchar Byte_read(uint byte_addr)   
  49. {   
  50.     EA = 0;                                        //关中断   
  51.     ISP_CONTR = En_Wait_TIME;                   //开启ISP&IAP,并送等待时间   
  52.     ISP_CMD = Read_COM;                         //送字节读命令字      
  53.     ISP_ADDRH = (uchar)(byte_addr >> 8);          //送地址高字节   
  54.     ISP_ADDRL = (uchar)(byte_addr & 0x00ff);    //送地址低字节        
  55.     ISP_TRIG = 0x46;                            //送触发命令字0x46   
  56.     ISP_TRIG = 0xB9;                            //送触发命令字0xB9   
  57.     _nop_();   
  58.     ISP_IAP_disable();                          //关闭ISP&IAP功能   
  59.     EA = 1;                                     //开中断   
  60.     return (ISP_DATA);   
  61. }     
  62. /*********************字节编程*********************/   
  63. void Byte_program(uint byte_addr,uchar isp_iap_data)   
  64. {   
  65.     EA = 0;                                     //关中断   
  66.     ISP_CONTR = En_Wait_TIME;                   //开启ISP&IAP,并送等待时间   
  67.     ISP_CMD = Prog_COM;                         //送字节编程命令字      
  68.     ISP_ADDRH = (uchar)(byte_addr >> 8);          //送地址高字节   
  69.     ISP_ADDRL = (uchar)(byte_addr & 0x00ff);    //送地址低字节        
  70.     ISP_DATA = isp_iap_data;                    //送数据进ISP_DATA   
  71.     ISP_TRIG = 0x46;                            //送触发命令字0x46   
  72.     ISP_TRIG = 0xB9;                            //送触发命令字0xB9   
  73.     _nop_();   
  74.     ISP_IAP_disable();                          //关闭ISP&IAP功能   
  75.     EA = 1;                                     //开中断      
  76. }   
  77.    
  78. /*********************扇区擦除*********************/   
  79. void Sector_erase(uint sector_addr)   
  80. {   
  81.     EA = 0;                                     //关中断   
  82.     ISP_CONTR = En_Wait_TIME;                   //开启ISP&IAP;并送等待时间   
  83.     ISP_CMD = Erase_COM;                        //送扇区擦除命令字      
  84.     ISP_ADDRH = (uchar)(sector_addr >> 8);       //送地址高字节   
  85.     ISP_ADDRL = (uchar)(sector_addr & 0X00FF);    //送地址低字节        
  86.     ISP_TRIG = 0X46;                            //送触发命令字0x46  
  87.     ISP_TRIG = 0XB9;                            //送触发命令字0xB9   
  88.     _nop_();   
  89.     ISP_IAP_disable();                          //关闭ISP&IAP功能   
  90.     EA = 1;   
  91. }  

  92. /********************************************************/
  93.     void Display(void)                                 //扫描数码管
  94.         {
  95.          if(posit==0)
  96.          {P1=(discode[disbuff[posit]])&0x7f;}
  97.          else
  98.          {P2=discode[disbuff[2]];
  99.           P0=discode[disbuff[1]];}
  100.           if(++posit>=3)
  101.           posit=0;
  102.         }
  103. /********************************************************/
  104.     void Conut(void)
  105.         {
  106.          time=TH0*256+TL0;
  107.          TH0=0;
  108.          TL0=0;
  109.         
  110.          S=(time*1.7)/100;     //算出来是CM
  111.          if((S>=250)||flag==1) //超出测量范围显示“-”
  112.          {         
  113.           flag=0;
  114.      S=250;
  115.          }
  116.          else
  117.          {
  118.           disbuff[0]=S%1000/100;
  119.           disbuff[1]=S%1000%100/10;
  120.           disbuff[2]=S%1000%10 %10;
  121.          }
  122.         }
  123. /********************************************************/
  124.      void zd0() interrupt 1                  //T0中断用来计数器溢出,超过测距范围
  125.   {
  126.     flag=1;                                                         //中断溢出标志
  127.   }
  128. /********************************************************/
  129.    void  zd3()  interrupt 3                  //T1中断用来扫描数码管和计800MS启动模块
  130.   {
  131.          TH1=0xfc;
  132.          TL1=0x30;
  133.          Display();
  134.          timer++;
  135.          if(timer>=400)          //调节测速频率
  136. {
  137.           timer=0;
  138.           TX123=1;                                        //800MS  启动一次模块
  139.           _nop_();
  140.           _nop_();
  141.           _nop_();
  142.           _nop_();
  143.           _nop_();
  144.           _nop_();
  145.           _nop_();
  146.           _nop_();
  147.           _nop_();
  148.           _nop_();
  149.           _nop_();
  150.           _nop_();
  151.           _nop_();
  152.           _nop_();
  153.           _nop_();
  154.           _nop_();
  155.           _nop_();
  156.           _nop_();
  157.           _nop_();
  158.           _nop_();
  159.           _nop_();
  160.      _nop_();
  161.           TX123=0;
  162.          }
  163.   }

  164. /*****************************************************************************
  165. *  延时子程序                                                                                                                             *
  166. *                                                                                                                                                         *
  167. ******************************************************************************/
  168. void delay(unsigned int ms)
  169. {
  170.         unsigned char i;
  171.         while(ms--)
  172.         {
  173.         for(i = 0; i < 120; i++);
  174.         }
  175. }
  176. /*********************************************************/

  177.         void  main(  void  )

  178.   {
  179.    S1J=0;
  180.    delay(1000);
  181.    S1J=1;
  182.    TMOD=0x11;                   //设T0为方式1,GATE=1;
  183.         TH0=0;
  184.         TL0=0;         
  185.         TH1=0xf8;                   //2MS定时
  186.         TL1=0x30;
  187.         ET0=1;             //允许T0中断
  188.         ET1=1;                           //允许T1中断
  189.         TR1=1;                           //开启定时器
  190.         EA=1;                           //开启总中断  
  191.    
  192.    S1=Byte_read(0x2000);   
  193.    S2=Byte_read(0x2200);   //读EEPROM
  194.    disbuff[0]=S1%1000/100;
  195.         disbuff[1]=S1%1000%100/10;
  196.         disbuff[2]=S1%1000%10 %10;
  197.    Display();
  198.    delay(1000);
  199.    disbuff[0]=S2%1000/100;
  200.         disbuff[1]=S2%1000%100/10;
  201.         disbuff[2]=S2%1000%10 %10;
  202.    Display();
  203.    delay(1000);
  204.         while(1)
  205.         {
  206.          while(!RX123);                //当RX为零时等待
  207.          TR0=1;                            //开启计数
  208.          while(RX123);                        //当RX为1计数并等待
  209.          TR0=0;                                //关闭计数
  210.     Conut();                        //计算
  211.     if(!KJA){Sector_erase(0x2000);                       //扇区擦除   
  212.     Byte_program(0x2000,S);                     //写EEPROM   
  213.     _nop_();   
  214.     _nop_();   
  215.     _nop_();
  216.     _nop_();   
  217.     _nop_();   
  218.     _nop_();
  219.     S1=Byte_read(0x2000); }
  220.     if(!KJAN){Sector_erase(0x2200);                       //扇区擦除   
  221.     Byte_program(0x2200,S);                     //写EEPROM   
  222.     _nop_();   
  223.     _nop_();   
  224.     _nop_();
  225.     _nop_();   
  226.     _nop_();   
  227.     _nop_();
  228.     S2=Byte_read(0x2200); }
  229.     if(S>=S1)S1J=0;
  230.     else S1J=1;
  231.         }

  232.   }
复制代码

所有资料51hei提供下载:


此商品已被删除

超声波测距工程用.rar

131.29 KB, 下载次数: , 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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