超声波模块详细介绍(stm32循迹小车中超声波的介绍)

超声波模块详细介绍(stm32循迹小车中超声波的介绍)

超声波模块是非常重要的一个模块,今天给大家全面介绍一下超声波模块的原理以及用法,代码的编写。

1 超声波模块的认识

首先,市面上的常见超声波模块主要分为以下几种:

  1. HC-SR04超音波模块
    在这里插入图片描述
  2. US-100超声波模块
    在这里插入图片描述
  3. US-015超声波模块

在这里插入图片描述
4. HY-SRF05超声波模块
在这里插入图片描述
5. HC-SR04超声波测距模块
在这里插入图片描述

2 超声波模块使用方法

我们主要讲解一下stm32寻迹小车最常用的HC-SR04模块。
从上图,我们可以看到HC-SR04超声波模块有四个引脚,分别为VCC、Trig(控制端)、Echo(发送回响信号)、GND。
硬件连接图
在这里插入图片描述

HC-SR04基本工作原理:
(1)采用IO口TRIG触发测距,给最少10us的高电平信号。
(2)模块自动发送8个40khz周期电平并检测回波,一旦检测到有回波信号则输出回响信号。
(3)回响信号: 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2 或者 us/58 =厘米 或者 us/148=英寸。
时序图如下:
在这里插入图片描述
总的来说,给控制口Trig发一个 10us以上的高电平,就可以在接收口等待高电平输出,一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,就可以达到你移动测量的值了。

流程图
请添加图片描述

3 模块源码(stm32c8t6)

根据上述了解,我们可以知道,超声波的变成主要配置两个引脚,分别为控制端Trig以及可以发出回响信号的Echo。控制端Trig是需要一个10us的高电平触发,所以这里的GPIO模式时推挽输出。而Echo引脚需要作为输入捕获通道,则模式为浮空输入。

#include "delay.h"
#include "sys.h"

硬件连接
串口1:RX PA10  TX PA9
超声波:Trig PB11    ECHG PB9
备注:以下代码非原创,只是经过修改适配成C8T6
若侵权,请告知。

//超声波硬件接口定义
#define HCSR04_PORT     GPIOB
#define HCSR04_CLK      RCC_APB2Periph_GPIOB
#define HCSR04_TRIG     GPIO_Pin_11
#define HCSR04_ECHO     GPIO_Pin_9
#define TRIG_Send PBout(11)
#define ECHO_Reci PBin(9)

//超声波计数
u16 msHcCount = 0;

//定时器4设置
void hcsr04_NVIC()
{
    
    
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;             
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;       
NVIC_Init(&NVIC_InitStructure);
}


//IO口初始化 及其他初始化
void Hcsr04Init()
{
    
      
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;   
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
   
    GPIO_InitStructure.GPIO_Pin =HCSR04_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;     
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
    GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);    
     
          
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);   
     
    TIM_DeInit(TIM4);
    TIM_TimeBaseStructure.TIM_Period = (1000-1); 
    TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);          
        
    TIM_ClearFlag(TIM4, TIM_FLAG_Update);  
    TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    
    hcsr04_NVIC();
    TIM_Cmd(TIM4,DISABLE);     
}




//打开定时器4
static void OpenTimerForHc()  
{
    
    
   TIM_SetCounter(TIM4,0);
   msHcCount = 0;
   TIM_Cmd(TIM4, ENABLE); 
}

//关闭定时器4
static void CloseTimerForHc()    
{
    
    
   TIM_Cmd(TIM4, DISABLE); 
}

//定时器4终中断
void TIM4_IRQHandler(void)  
{
    
    
   if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  
   {
    
    
       TIM_ClearITPendingBit(TIM4, TIM_IT_Update  ); 
       msHcCount++; //计数器开始加
   }
}
 

//获取定时器4计数器值
u32 GetEchoTimer(void)
{
    
    
   u32 t = 0;
   t = msHcCount*1000;
   t += TIM_GetCounter(TIM4);
   TIM3->CNT = 0;  //计数器归零
   delay_ms(50);
   return t;
}
 
//通过定时器4计数器值推算距离
float Hcsr04GetLength(void )
{
    
    
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)  //测量五次取平均
   {
    
    
      TRIG_Send = 1;   //给控制端高电平
      delay_us(20);
      TRIG_Send = 0;  //超声波模块已开始发送8个40khz脉冲
      while(ECHO_Reci == 0);   //若ECHO_Reci为低电平,则一直循环,直到为高电平。  
      OpenTimerForHc();  //此时说明检测到高电平,开启定时器,开始计时。       
      i = i + 1;
      while(ECHO_Reci == 1); //若ECHO_Reci为高电平,则一直循环,直到为低电平。 
      CloseTimerForHc();   //此时说明检测到低电平,关闭定时器,停止计时     
      t = GetEchoTimer();        //获取定时器时间
      lengthTemp = ((float)t/58.0); //数据处理,转换成cm
      sum = lengthTemp + sum ;  //五次测得数据累加
        
    }
    lengthTemp = sum/5.0; //取平均
    return lengthTemp;
}

stm32循迹小车系列文章:
1.stm32循迹小车详细制作过程(附加完全版代码)
2.L298n电机驱动详细介绍(stm32循迹小车中L298n的用法)
3.超声波模块详细介绍(stm32循迹小车中超声波的介绍)

此博客收录在stm32循迹小车教程专栏中。
stm32交流群在下方,寻迹程序在群资料,超声波马上补上,有问题可以直接在群里问,互相交流学习。

猜你喜欢

转载自blog.csdn.net/m0_51951121/article/details/125849125