[应用方案] 单片机和超声波模块

[复制链接]
7150|53
 楼主| wengh2016 发表于 2024-8-23 15:16 | 显示全部楼层 |阅读模式
程序的实现思路
    首先单片机给超声波模块的Trig 引脚一个10us的高电平使其发射声波,同时开始打开定时器记录 Echo 引脚高电平的持续时间。因为音速是340m/s,所以 距离 =( (340m/s)*  时间 )  / 2

补充知识:
1、如何计算定时时间
   51单片机的定时器有一个计脉冲数的寄存器,当我们打开定时器时这个寄存器的值就会每过一个机器周期后自加一,直到溢出(值大于65535)时定时器便会产生中断信号。而这个机器周期与使用的晶振频率有关。( 1M=1*10^6 )

一个机器周期的时间为:t=1∗12/fosc (fosc为晶振频率)

2、如何根据定时的时间计算出距离
首先知道速度和运动时间那么,距离 =( 速度*  时间 )  

而我们测量的是声波发射出去后碰撞障碍物反射回来的时间此时声波已经走过了两遍我们要测量的距离,所以要除与2,距离 =( 速度*  时间 )  / 2

然后要做的就是单位换算,1m = 1*10^2cm、1s = 1*10^6us

示例(单位为cm)

S = t * 340*10^2 / 2  cm

  1. #include <reg52.h>

  2. //定义数码管的位选引脚
  3. sbit wei_1 = P1^0;
  4. sbit wei_2 = P1^1;
  5. sbit wei_3 = P1^2;
  6. sbit wei_4 = P1^3;

  7. //定义超声波引脚
  8. sbit Trig = P1^6;//发送波端口
  9. sbit Echo = P1^7;//接收端口


  10. //共阴极数码管段码0~F
  11. unsigned char code smg[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  12.                                   0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};


  13. void smg_saomiao(unsigned char weu,unsigned char dat);//声明数码管扫描函数
  14. void delay_ms(unsigned int i);        //声明延时函数       
  15. void startHC(void); //声明触发超声波传感器函数       


  16. void main(void)
  17. {
  18.         float time=0.0,dis=0.0;
  19.         int  num=0;
  20.        
  21.         //选择定时器0、工作模式为1,初始值设定0开始数数,先不开始数数       
  22.         TMOD &= 0xf0;
  23.         TMOD |= 0x01;        //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响       
  24.        
  25.         TH0=0;              //给定初值,这里使用定时器最大值从0开始计数一直到65535溢出
  26.         TL0=0;
  27.        
  28.         TR0=0;        //关闭定时器
  29.        
  30.        
  31.         while(1)
  32.         {
  33.                 //超声波测距频率约10Hz,既100ms测量一次
  34.                 if(num>14)
  35.                 {
  36.                         startHC();//发射声波
  37.                        
  38.                         while(Echo==0);//等待模块发射声波
  39.                        
  40.                         TR0=1;        //打开定时器开始计时
  41.                        
  42.                         while(Echo==1 && TF0==0);//等待模块接收碰撞障碍物后反射回来的声波

  43.                         TR0=0;        //关闭定时器停止计时
  44.                        
  45.                         //计算出中间经过多少时间(晶振为11.0592Mhz的计数脉冲时间单位为1.085us,12Mhz为1us)
  46.                         time = (float)(TH0 * 256.0 + TL0)*1.085;    //us为单位
  47.                        
  48.                         //距离 = 速度(340m/s)* 时间/2
  49.                         dis = (float)time * 0.017;//计算得出单位为CM
  50.                        
  51.                         num=0;//将计数变量清零
  52.                         TH0=0;//将定时器的计数值清零
  53.             TL0=0;//将定时器的计数值清零
  54.                 }
  55.                
  56.                 num++;
  57.                
  58.                 //扫描一遍数码管约7ms,7*14=98 约100ms
  59.                 smg_saomiao(1,16);
  60.                 smg_saomiao(2,(int)dis/100);
  61.                 smg_saomiao(3,(int)dis%100/10);
  62.                 smg_saomiao(4,(int)dis%10);
  63.         }
  64. }


  65. /****************************************************************
  66. * 函 数 名       : Delay10us
  67. * 函数功能                   : 延迟10us
  68. * 参数           : 无
  69. * 返回值         : 无
  70. ******************************************************************/
  71. void Delay10us(void) //@11.0592MHz
  72. {
  73.    unsigned char i;
  74.     i = 3;
  75.    while (--i);
  76. }

  77. /****************************************************************
  78. * 函 数 名       : startHC
  79. * 函数功能                   : 触发超声波传感器发出声波
  80. * 参数           : 无
  81. * 返回值         : 无
  82. ******************************************************************/
  83. void startHC(void)
  84. {
  85.         //发送触发信号
  86.         Trig = 0;
  87.         Trig = 1;
  88.         Delay10us();
  89.         Trig = 0;
  90. }

  91. /****************************************************************
  92. * 函 数 名       : delay
  93. * 函数功能                   : 延时函数,i=1时,大约延时1ms
  94. *参数i           : 需要延时的毫秒数
  95. *返回值          : 无
  96. ******************************************************************/
  97. void delay_ms(unsigned int i)
  98. {
  99.         unsigned int n;
  100.   while(i--)
  101.   for(n=0;n<110;n++);               
  102. }

  103. /****************************************************************
  104. * 函 数 名       : smg_saomiao
  105. * 函数功能                   : 驱动4位的共阴数码管
  106. *参数wei         : 选择要点亮的那一位数码管(1~4)
  107. *参数dat         : 显示的段码内容( 0~15 ——> 0~F)
  108. *返回值          : 无
  109. ******************************************************************/
  110. void smg_saomiao(unsigned char wei,unsigned char dat)
  111. {
  112.         //判断要点亮哪一位数码管
  113.    if(wei ==1)
  114.          {
  115.                         wei_1 = 0;
  116.                         wei_2 = 1;
  117.                         wei_3 = 1;
  118.                         wei_4 = 1;                 
  119.          }else if(wei ==2)
  120.          {
  121.                         wei_1 = 1;
  122.                         wei_2 = 0;
  123.                         wei_3 = 1;
  124.                         wei_4 = 1;                 
  125.          }else if(wei ==3)
  126.          {
  127.                         wei_1 = 1;
  128.                         wei_2 = 1;
  129.                         wei_3 = 0;
  130.                         wei_4 = 1;                  
  131.          }else if(wei ==4)
  132.    {
  133.                         wei_1 = 1;
  134.                         wei_2 = 1;
  135.                         wei_3 = 1;
  136.                         wei_4 = 0;                 
  137.          }
  138.          
  139.          P0 = smg[dat];//显示该位数码管的段码内容
  140.          delay_ms(3);//延时3-5ms
  141.          P0 = 0;//熄灭所有段码,即消影
  142. }


huquanz711 发表于 2024-8-24 11:10 来自手机 | 显示全部楼层
现在主要是用毫米波雷达
jtracy3 发表于 2024-10-11 09:01 | 显示全部楼层
设置Trig引脚GPIO的输出模式为推挽输出,设置Echo引脚GPIO的输入模式为浮空输入,并打开相应GPIO的时钟。
pmp 发表于 2024-10-11 09:52 | 显示全部楼层
在测量过程中,要注意避免其他超声波信号的干扰。
考虑温度和湿度对声速的影响,并进行必要的校准。
mattlincoln 发表于 2024-10-11 12:13 | 显示全部楼层
接收触发信号:当Trig引脚接收到来自单片机的触发信号时,激活内部电路产生超声波脉冲。
检测回波信号:模块内部的接收器会检测从障碍物反射回来的超声波脉冲,并在Echo引脚上产生高电平信号。
信号持续时间:Echo引脚上的高电平持续时间与超声波往返的时间成正比,即与距离成正比。
chenci2013 发表于 2024-10-11 15:10 | 显示全部楼层
在实际环境中测试程序的功能,并根据测试结果进行必要的调整和优化。
 楼主| wengh2016 发表于 2024-10-11 15:51 | 显示全部楼层
将 Trig 引脚拉高几微秒(一般 10 - 20 微秒即可),然后再拉低。这个操作可以通过直接操作单片机的 I/O 寄存器或者使用相应的库函数来实现。
minzisc 发表于 2024-10-14 12:11 | 显示全部楼层
为了提高程序的稳定性,可以添加一些错误处理机制。例如,如果在一定时间内没有检测到回声信号,可以给出相应的提示或者进行一些默认的处理。
cemaj 发表于 2024-10-14 16:05 | 显示全部楼层
在测量过程中,应尽量避免气流的影响,可以选择在静止或微风条件下进行测量。
beacherblack 发表于 2024-10-14 17:09 | 显示全部楼层
使用定时器捕获,则初始化定时器,设置为捕获模式。
updownq 发表于 2024-10-14 21:51 | 显示全部楼层
向Trig引脚发送一个至少10微秒的高电平信号,以触发超声波模块发送超声波脉冲。

等待回响信号: 等待Echo引脚变为高电平,表示超声波模块已经接收到回响信号。此时开始计时。
wwppd 发表于 2024-10-15 13:03 | 显示全部楼层
在发送脉冲的同时,启动定时器或使能外部中断。
geraldbetty 发表于 2024-10-15 17:12 | 显示全部楼层
对得到的距离数据进行滤波或校准以提高准确性。
可以设置阈值来判断是否检测到障碍物。
hudi008 发表于 2024-10-15 18:54 | 显示全部楼层
超声波模块通常有几个引脚,例如发射引脚(Trig)、接收引脚(Echo)、电源引脚(VCC 和 GND)。
单片机需要通过合适的 I/O 引脚与超声波模块的这些引脚相连。一般将单片机的一个数字输出引脚连接到超声波模块的 Trig 引脚,用于发送触发信号;将一个数字输入引脚连接到 Echo 引脚,用于接收超声波反射回来后的脉冲信号。
i1mcu 发表于 2024-10-15 20:55 | 显示全部楼层
为了提高测量精度,可以采取滤波和阈值判断等方法来减少信号干扰和误判。
pl202 发表于 2024-10-16 10:03 | 显示全部楼层
超声波模块的测量范围通常由制造商指定,一般在几厘米到几米不等。常见的超声波模块测量范围大约在2厘米到15米之间
nomomy 发表于 2024-10-16 10:28 | 显示全部楼层
配置定时器用于捕获超声波模块返回的信号时间。例如,可以使用定时器的输入捕获功能来记录信号的高电平时间。
olivem55arlowe 发表于 2024-10-16 12:52 | 显示全部楼层
根据时间差和超声波在空气中传播的速度(大约为340米/秒),计算出距离。公式为:距离 = 高电平时间 * 声速 / 2。
chenci2013 发表于 2024-10-16 13:15 | 显示全部楼层
GPIO配置:配置用于控制超声波模块的引脚(如Trig和Echo)为输出模式或输入模式。
定时器/计数器设置:配置定时器以测量Echo引脚上的高电平持续时间,从而计算距离。
中断服务程序:如果使用中断方式处理定时器溢出,需编写相应的中断服务程序。
ulystronglll 发表于 2024-10-16 13:44 | 显示全部楼层
对于连接 Trig 引脚的输出引脚,设置为输出模式(例如在 C 语言中使用相应的寄存器配置语句)。对于连接 Echo 引脚的输入引脚,设置为输入模式。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

2932

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部