打印
[其他ST产品]

STM32小车篇之超声波测距

[复制链接]
1302|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
超声波模块测量距离防碰撞
1.超声波测距:
原理:超声测距其实就是通过单片机控制超声波模块发出一系列超声波,当超声波遇到障碍物时反弹回来,根据声音在空气中的传播速率340m/s,再结合上述所讲的方法求得时间t,应用初高中物理知识,即可求解距离。(驱动超声波模块需要给它一个10-20us高电平)
即 测量距离=(高电平持续时间(340M/S))/2
例子详解:我们算出的高电平时间是以us为单位,因此我们可以把声波传输速度看成大约为340M/S,合34,000CM/S。 即34,000除以1,000,000CM/US。 即为:0.0340CM/US 换种角度:1/(0.0343 CM/US) 即:29.00 US/CM。 这就意味着,每290.0US表示10CM的距离。1厘米就是29.00US。 但是发送后到接收到回波,声音走过的是2倍的距离呀。 所以实际距离就是1厘米,对应58.0US。
即 测量距离=(高电平持续时间/58.0(CM))

使用特权

评论回复
评论
等你下课 2023-8-25 15:32 回复TA
———————————————— 版权声明:本文为CSDN博主「Iron_vik」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/Iron_vik/article/details/119855726 
沙发
等你下课|  楼主 | 2023-8-25 15:32 | 只看该作者
2.输入捕获:
基本原理:定时器的输入捕获模式可以用来测量脉冲宽度或者测量频率。除了基本定时器,通用和高级均有输入捕获功能。如图所示:

使用特权

评论回复
板凳
等你下课|  楼主 | 2023-8-25 15:33 | 只看该作者
  首先,我们设定定时器工作模式为向上计数模式,图中t1-t2时间间隔就是我们需要测量的脉宽时间(即高电平时间)。测量方法如下:
1: 设定定时器某通道为上升沿捕获,这样在t1时刻,就会捕获到当前值CNT值,然后马上清零,同时设置该通道为下降沿捕获,这样到t2时刻,又发生捕获事件,得到此时的CNT值,记为CCRx2。这样,根据定时器的计数频率可以算出t1-t2的时间,从而得到高电平脉宽。
2:在t1-t2的时间段里,有可能发生N次溢出,我们需要对此进一步处理,防止高电平过长,导致数据不准确。因此,CNT计数的次数等于N*ARR+CCRx2,有了这个计数次数,再乘以 CNT 的计数周期,即可得到 t2-t1 的时间长度,即高电平持续时间。

使用特权

评论回复
地板
等你下课|  楼主 | 2023-8-25 15:33 | 只看该作者
3.(超声波模块)HC_SRO4
实验中所实验的 HC-SR04超声波模块主要是由两个通用的压电陶瓷超声传感器,并加外围信号处理电路构成的。
1)引脚和原理:
该模块有VCC、GND、Trig和Echo针脚。TRIG是输出和ECHO是输入。
该模块的工作原理为:模块所需要的供电是5V
1.先向TRIG脚输入至少10us的触发信号
2.该模块内部将发出 8 个 40kHz 周期电平并检测回波。
3.一旦检测到有回波信号则ECHO输出高电平回响信号。回响信号的脉冲宽度与所测的距离成正比
4.由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。公式: 距离=高电平时间*声速(340M/S)/2。

使用特权

评论回复
5
等你下课|  楼主 | 2023-8-25 15:33 | 只看该作者
2)实现功能:通过超声波模块测距离,并将测试距离显示到串口助手上。
根据工作原理,我们可以选择两种模式驱动
1.采用中断+定时器方式,将ECHO定义为上升沿下降沿都能触发中断,trig触发之后,echo高电平进中断打开定时器,echo低电平关闭定时器并统计定时器计数值
2.采用普通IO+定时器模式,触发之后等待echo响应,响应时打开定时器,直到echo恢复低关闭定时器,获取时间

使用特权

评论回复
6
等你下课|  楼主 | 2023-8-25 15:34 | 只看该作者
注1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响模块工作。
注2:测距时,被测物体的面积不少于0.5平方米且要尽量平整。否则会影响测试结果。

使用特权

评论回复
7
等你下课|  楼主 | 2023-8-25 15:34 | 只看该作者
通过上面原理的学习,再通过代码hcsr04.c文件加深理解:

使用特权

评论回复
8
等你下课|  楼主 | 2023-8-25 15:34 | 只看该作者
#define HCSR04_PORT     GPIOA
#define HCSR04_CLK      RCC_APB2Periph_GPIOA
#define HCSR04_TRIG     GPIO_Pin_4
#define HCSR04_ECHO     GPIO_Pin_0

#define TRIG_Send  PAout(4)
#define ECHO_Reci  PAin(0)

u16 msHcCount = 0;//整型变量用于ms计数
extern u16 TIM2CH1_CAPTURE_STA,TIM2CH1_CAPTURE_VAL;
void Hcsr04_Init(u32 arr,u32 psc)
{
          TIM_ICInitTypeDef TIM_ICInitStructure;
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
          GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
   
          //IO初始化
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;       //TRIG输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
   
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;                //ECHO输入
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);       
       
          //初始化定时器TIM2
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   //使能RCC时钟
          TIM_DeInit(TIM2);
          TIM_TimeBaseStructure.TIM_Period = arr; //计数周期为1000/1ms
          TIM_TimeBaseStructure.TIM_Prescaler =psc; //1M的计数频率  1US计数
          TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //不分频
          TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
                TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
               

//          TIM_ICStructInit(&TIM_ICInitStructure);//设置缺省值
          TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
          TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
          TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;          //配置输入分配
          TIM_ICInitStructure.TIM_ICFilter = 0x00;          //IC2F=0000 配置输入滤波器 0 不滤波
          TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //IC1映射到TI1
          TIM_ICInit(TIM2, &TIM_ICInitStructure);
               
               
               
//                TIM_ClearFlag(TIM2, TIM_FLAG_Update);   //清除更新中断
          TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);    //打开定时器更新中断
    TIM_CtrlPWMOutputs(TIM2,ENABLE);        //主输出使能
                Hcsr04_NVIC();
          TIM_Cmd(TIM2, ENABLE);
}
void Hcsr04_NVIC(void)
{  
    NVIC_InitTypeDef NVIC_InitStructure;  
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
      
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;            
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;   
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;           
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        
    NVIC_Init(&NVIC_InitStructure);  
}



//TIM2的中断服务函数
void TIM2_IRQHandler(void)   
{
                  if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
    {      
        if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
         
        {        
            if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平
            {
                if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长
                {
                    TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
                    TIM2CH1_CAPTURE_VAL=0XFFFF;
                }
                                                                else
                                                                        TIM2CH1_CAPTURE_STA++;
            }     
        }
                        }
    if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发送捕获事件
        {   
            if(TIM2CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿      
            {                  
                TIM2CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次上升沿
                TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
                TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
            }else   //还未开始,第一次捕获上升沿
            {
                TIM2CH1_CAPTURE_STA=0;            //清空
                TIM2CH1_CAPTURE_VAL=0;
                TIM_SetCounter(TIM2,0);
                TIM2CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
                TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CCC1P=1 设置为下降沿捕获
            }            
        }                                                


    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清楚中断标志位
    }

使用特权

评论回复
9
songqian17| | 2023-8-25 22:13 | 只看该作者
可以把声波传输速度看成大约为340M/S

使用特权

评论回复
10
daichaodai| | 2023-8-26 15:11 | 只看该作者
一般应用超声波测距传感器还能用

使用特权

评论回复
11
公羊子丹| | 2024-9-11 07:25 | 只看该作者

但是,由于变压器存在漏感,

使用特权

评论回复
12
万图| | 2024-9-11 08:28 | 只看该作者

在此情况下我们通常会用电阻串联在电路中

使用特权

评论回复
13
Uriah| | 2024-9-11 09:31 | 只看该作者

缩合型灌封硅胶由于固化过程有体积收缩一般不使用在模块电源的灌封中

使用特权

评论回复
14
帛灿灿| | 2024-9-11 11:27 | 只看该作者

设备中的ESD静电阻抗器一般都不易老化损坏

使用特权

评论回复
15
Bblythe| | 2024-9-11 12:30 | 只看该作者

通过将各类分立元器件进行整合和封装,模块电源能够实现以最小的体积来实现功率密度更高的效果。

使用特权

评论回复
16
周半梅| | 2024-9-11 14:26 | 只看该作者

可对电路进行一个防护效果

使用特权

评论回复
17
Pulitzer| | 2024-9-11 15:29 | 只看该作者

以保护器件免受ESD的损坏

使用特权

评论回复
18
童雨竹| | 2024-9-11 17:25 | 只看该作者

不会达到该电压

使用特权

评论回复
19
Wordsworth| | 2024-9-11 18:28 | 只看该作者

一端接地,滤去高频

使用特权

评论回复
20
Clyde011| | 2024-9-11 19:31 | 只看该作者

如果防护与热设计欠佳

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

388

帖子

0

粉丝