找回密码
 立即注册

QQ登录

只需一步,快速开始

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

"盲人眼睛"的小制作 利用超声波测距离 怎么才能让蜂鸣器灵敏一些

[复制链接]
跳转到指定楼层
楼主
    现在我打算做一个利用超声波测距离的东西,现在有一个ii c接口的模块,和开发板一块,希望做一个”盲人眼睛”的小制作,就是利用超声波模块和蜂鸣器两部分,物体离得越近,蜂鸣器可以响的越快,但是测试后总觉得蜂鸣器反应比较迟钝,有物体在前面出现不能立刻察觉到,可是用数码管动态显示就可以察觉到有快速的东西从超声波探头闪过,求大神可以告诉我怎么才能让蜂鸣器灵敏一些!以下是我的程序

  1. #include <reg51.h>
  2. #include <intrins.h>
  3. sbit SDA=P3^6;         // 此引脚须上拉 4.7K 电阻至 VCC
  4. sbit SCL=P3^7;         // 此引脚须上拉 4.7K 电阻至 VCC
  5. sbit beep=P1^5;
  6.       
  7. unsigned int range=0;
  8. //unsigned int range1=0;
  9. //unsigned int range2=0;
  10. //unsigned int range3=0;
  11. //unsigned int min=0;

  12. void delay50us_chengxv(void)   //误差 0us
  13. {
  14.     unsigned char a,b;
  15.     for(b=9;b>0;b--)
  16.         for(a=1;a>0;a--);
  17. }

  18. void delay500ms(void)   //误差 0us
  19. {
  20.     unsigned char a,b,c;
  21.     for(c=205;c>0;c--)
  22.         for(b=116;b>0;b--)
  23.             for(a=9;a>0;a--);
  24. }
  25. void delay300ms(void)   //误差 0us
  26. {
  27.     unsigned char a,b,c;
  28.     for(c=5;c>0;c--)
  29.         for(b=212;b>0;b--)
  30.             for(a=140;a>0;a--);
  31. }
  32.       


  33. void beepcv()
  34. {
  35.         unsigned int a;
  36.         if(range<=1500&&range>=0)
  37.         {
  38.                 if(range<=1500&&range>=900)
  39.                 {
  40.                   for(a=600;a>0;a--)
  41.                   {
  42.                           beep=1;
  43.                           delay1(10);
  44.                           beep=0;
  45.                           delay1(10);
  46.                           delay1(175);
  47.                   }      
  48.             }
  49.         else if(range>=300&&range<900)
  50.         {
  51.           for(a=600;a>0;a--)
  52.           {
  53.                   beep=1;
  54.                   delay1(10);
  55.                   beep=0;
  56.                   delay1(10);
  57.                   delay1(100);
  58.           }
  59.         }
  60.           else if(range>=0&&range<300)
  61.           {
  62.             for(a=600;a>0;a--)
  63.                     {
  64.                                   beep=1;
  65.                                   delay1(10);
  66.                                   beep=0;
  67.                                   delay1(10);
  68.                                   delay1(50);
  69.                     }                                       
  70.       }                    
  71.    }
  72. }
  73. void delay(void)         //short delay 使用速度较快的单片机时,I2C 通讯可能不正常,在此函数中多加 4~8 个_nop_();即可
  74. {
  75.         _nop_(); _nop_(); _nop_(); _nop_();
  76.         _nop_(); _nop_(); _nop_(); _nop_();
  77.         _nop_(); _nop_(); _nop_(); _nop_();
  78.         _nop_(); _nop_(); _nop_(); _nop_();
  79. }
  80. void start(void) //I2C start
  81. {
  82.         SDA = 1;
  83.         delay();
  84.         SCL = 1;
  85.         delay();
  86.         SDA = 0;
  87.         delay();                 
  88. }
  89. void stop(void)         //I2C stop
  90. {      
  91.         SDA = 0;      
  92.         delay();      
  93.         SCL = 1;      
  94.         delay();      
  95.         SDA = 1;      
  96.         delay();      
  97. }
  98. void ack(void)         //ack
  99. {      
  100.     unsigned char i;      
  101.         SCL = 1;      
  102.         delay();      
  103.         while(SDA == 1 && i < 200)      
  104.         {      
  105.                 i++;      
  106.         }      
  107.                 SCL = 0;      
  108.                 delay();      
  109.         }      

  110. void no_ack()         //not ack
  111. {      
  112.         SDA = 1;      
  113.         delay();      
  114.         SCL = 1;      
  115.         delay();      
  116.         SCL = 0;      
  117.         delay();      
  118. }      
  119. void i2c_write_byte(unsigned char dat) //write a byte
  120. {
  121.         unsigned char i;
  122.         SCL = 0;
  123.         for(i = 0; i < 8; i++)
  124.         {
  125.                 if(dat & 0x80)
  126.         {
  127.                 SDA = 1;
  128.         }
  129.         else
  130.         {
  131.                 SDA = 0;
  132.         }
  133.                 dat = dat << 1;
  134.                 delay();
  135.                 SCL = 1;
  136.                 delay();
  137.                 SCL = 0;
  138.                 delay();
  139.         }
  140.         SDA = 1;
  141.         delay();
  142. }
  143. unsigned char i2c_read_byte(void) //read a byte
  144. {
  145.         unsigned char i,dat;
  146.         SCL = 0;
  147.         delay();
  148.         SDA = 1;
  149.         delay();
  150.         for(i = 0; i < 8; i++)
  151.         {
  152.                 SCL = 1;
  153.                 delay();
  154.                 dat = dat << 1;
  155.                 if(SDA == 1)
  156.                 {
  157.                         dat++;
  158.                 }
  159.                 SCL = 0;
  160.                 delay();
  161.         }
  162.                 return dat;
  163. }
  164. void init_i2c(void)         //i2c init
  165. {      
  166.         SDA = 1;      
  167.         SCL = 1;      
  168. }      
  169. void write_byte(unsigned char address,unsigned char reg,unsigned char command) //address+register+command      
  170. {      
  171.         init_i2c();      
  172.         start();      
  173.         i2c_write_byte(address);      
  174.         ack();      
  175.         i2c_write_byte(reg);      
  176.         ack();      
  177.         i2c_write_byte(command);      
  178.         ack();      
  179.         stop();      
  180. }      

  181. unsigned char read_byte(unsigned char address,unsigned char reg) //address(with bit 0 set) + register
  182. {
  183.         unsigned char dat;
  184.         init_i2c();
  185.         start();
  186.         i2c_write_byte(address);
  187.         ack();
  188.         i2c_write_byte(reg);
  189.         ack();
  190.         start();
  191.         i2c_write_byte(address+1);
  192.         ack();
  193.         delay();delay();delay();delay();delay(); //此处延时对于 STC89C 系列单片机,可以删除,如果对于快速单
  194.         //片机,需要加至少 50us 的延时,才可以可靠读到数据
  195.         dat = i2c_read_byte();
  196.         no_ack();
  197.         stop();
  198.         return dat;
  199. }
  200. void delayms(unsigned int ms) //delay ms
  201. {
  202.         unsigned char i;
  203.         unsigned int j;
  204.         for(i=0;i<110;i++)
  205.         for(j=0;j<ms;j++);
  206. }
  207. /*void change_i2c_address(unsigned char addr_old, unsigned char addr_new)
  208. // addr_old is the address now, addr_new will be the new address
  209. { //that you want change to
  210.         delayms(2000);         // Protect the eeprom ,you can delete this sentence
  211.         write_byte(addr_old,2,0x9a);      
  212.         delayms(1);      
  213.         write_byte(addr_old,2,0x92);      
  214.         delayms(1);      
  215.         write_byte(addr_old,2,0x9e);      
  216.         delayms(1);      
  217.         write_byte(addr_old,2, addr_new);      
  218.       
  219.         delayms(500);         //Protect the eeprom, you can delete this sentence
  220. }        
  221. void config_0x71_0x7d(unsigned char addr_old, unsigned char flag)      
  222. //flag will be 0x71,0x72,0x73,0x74,0x7a,0x7b,0x7c,0x7d      
  223. { //that you want change to
  224.         delayms(2000);         // Protect the eeprom ,you can delete this sentence
  225.         write_byte(addr_old,2,0x9c);      
  226.         delayms(1);      
  227.         write_byte(addr_old,2,0x95);      
  228.         delayms(1);      
  229.         write_byte(addr_old,2,0x98);      
  230.         delayms(1);      
  231.         write_byte(addr_old,2, flag);      

  232.         delayms(500);         //Protect the eeprom, you can delete this sentence
  233. }*/      

  234. unsigned int detect(unsigned char address,unsigned char command) //0xe8(address) + 0x30(command)
  235. {
  236.         unsigned int distance,count;
  237.         write_byte(address,2,command); //use command "0x30" to detect the distance
  238.         delayms(1); //安全延时,如果显示不清晰可以将延时调大一些
  239.         //delayms(80); //如果是探测温度此处延时需根据表 1 所列时间相应延长
  240.         count=800;
  241.         while(--count || !SCL)         //等待探测结束,count 值调小将减小探测等待时间
  242.         {      

  243.         ; // 空语句
  244. //        DigDisplay(range);         //显示语句,可根据需要保留或删除
  245.         }      

  246.         // while(!SCL)display(range); //you can delete "display(range)"
  247.         //通过查询 SCL 线来智能识别探测是否结束,使用本语句可删除上条语句(count=800;while…)以节省探测时间
  248.         distance=read_byte(address,2);
  249.         distance <<= 8;
  250.         distance += read_byte(address,3);
  251.         return distance;         //return 16 bit distance in millimeter
  252. }      
  253. void main(void)      
  254. {      
  255.         //change_i2c_address(0xe8,0xfe); //change default address 0xe8 to 0xfe
  256.         while(1)
  257.         {
  258.                 range = detect(0xe8,0x30);
  259.                 //0xe8 is the address; 0x30 is the command.you just need the only one sentence to get the range.
  260.                 beepcv();
  261.         }
  262. }
复制代码









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

使用道具 举报

来自 3#
ID:111517 发表于 2017-8-19 21:45 | 只看该作者
是不是你蜂鸣器那里有问题?如果超声波探测的距离有变化,但是你的蜂鸣器程序当时却刚加入响应之前那个距离的程序,这是不是就相当于延时,此时反应比较慢也就情有可原了。

评分

参与人数 1黑币 +50 收起 理由
admin + 50 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

沙发
ID:123289 发表于 2017-8-18 00:13 | 只看该作者
蜂鸣器由你的程序指挥,程序让它快一些不就行了吗?
回复

使用道具 举报

地板
ID:149043 发表于 2017-8-20 20:22 | 只看该作者
沧浪 发表于 2017-8-19 21:45
是不是你蜂鸣器那里有问题?如果超声波探测的距离有变化,但是你的蜂鸣器程序当时却刚加入响应之前那个距离 ...

是这样的,这个程序目前只能这样了,不是特别灵活

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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