STM32智能小车------超声波测距模块

文章目录

  • 一、原理讲解
    • 1.实物图
    • 2.工作原理:
    • 3.接线:
  • 二、软件驱动代码
    • 1.接口定义
    • 2.驱动函数
  • 总结
    • 最终效果


  • 大家好哇!我是小光,嵌入式爱好者,一个想要成为系统架构师的普通大学生。
  • 进入正题,最近在做小车,目前已经加入红外避障、超声波测距、红外遥控三个传感器,分别实现遥控切换模式、超声波控制距离、避障功能。
  • 本次文章说说超声波测距的实现。
  • 非常感谢大家的阅读,如果有不对的地方欢迎指正

一、原理讲解

1.实物图

STM32智能小车------超声波测距模块_第1张图片
这种呢是五线的,还有一种是四线的hysrf04,不过都是一样的,就多了一个OUT口(开关量输出)。
HY-SRF05超声波测距模块可测量距离为2cm-450cm,测量精度3mm,模块包括超声波发射器、接收器与控制电路。

2.工作原理:

STM32智能小车------超声波测距模块_第2张图片

  1. 采用IO口TRIG触发测距,给至少10us的高电平信号;
  2. 模块自动发送8个40kHZ的方波,自动检测是否有信号返回;
  3. 有信号返回,通过IO口ECHO输出一个高电平,高电平的持续时间就是超声波从发射到返回的时间。测量距离=(高电平时间*声速)/2;
    计算距离:uS/58 = cm
    uS/148 = 英寸

3.接线:

STM32智能小车------超声波测距模块_第3张图片
VCC————5v
GND————板子GND
Trig————PA6(TIM3_CH1)
Echo————PA7(TIM3_CH2)
注意:1.VCC一定要接5V,不然数据一直都是0.045
2.Trig和Echo可以接其他的定时器,不过初始化得自己改

二、软件驱动代码

1.接口定义

#define ECHO_Reci  PAin(7)
#define TRIG_Send  PAout(6)
//超声波硬件接口定义
//超声波硬件接口定义
//超声波硬件接口定义
#define HCSR04_PORT     GPIOA
#define HCSR04_CLK      RCC_APB2Periph_GPIOA
#define HCSR04_TRIG     GPIO_Pin_6
#define HCSR04_ECHO     GPIO_Pin_7

2.驱动函数

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

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

	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;//TIM3定时器中断
	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初始化
    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);    
     //TIM3时钟使能
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);   
    //设置定时器预分频系数和周期
    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(TIM3, &TIM_TimeBaseStructure);          
    //清除TIM3的待处理标志位
    TIM_ClearFlag(TIM3, TIM_FLAG_Update);  
    //TIM3中断使能
    TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);    
    //定时器中断初始化
    hcsr04_NVIC();
    //TIM3使能
    TIM_Cmd(TIM3,DISABLE);     
}


//打开定时器3
static void OpenTimerForHc()  
{
   TIM_SetCounter(TIM3,0);//定时器从0开始计数
   msHcCount = 0;//计数归零
   TIM_Cmd(TIM3, ENABLE); //使能
}

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

//定时器3终中断
void TIM3_IRQHandler(void)  
{
   //记录返回信号高电平持续的时间
   if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  
   {
       TIM_ClearITPendingBit(TIM3, TIM_IT_Update  ); 
       msHcCount++;//定时器计数
   }
}
 

//获取定时器3计数器值
u32 GetEchoTimer(void)
{
   u32 t = 0;
   t = msHcCount*1000;//将定时器计数转换成时间
   t += TIM_GetCounter(TIM3);//定时器输入捕获
   TIM3->CNT = 0;  //清空定时器计数
   delay_ms(50);//每次测量间隔
   return t;
}
 
//通过定时器3计数器值推算距离
float Hcsr04GetLength(void )
{
   u32 t = 0;
   int i = 0;
   float lengthTemp = 0;
   float sum = 0;
   while(i!=5)//测量五次
   {
      TRIG_Send = 1;      //给TRIG口输出一个高电平,延时20us
      delay_us(20); 
      TRIG_Send = 0;
      while(ECHO_Reci == 0); //等待ECHO口返回高电平信号     
      OpenTimerForHc();        //ECHO输出高电平之后打开定时器
      i = i + 1;               
      while(ECHO_Reci == 1);//用中断接收8个40khz的方波
      CloseTimerForHc();        //接收完成后关闭定时器
      t = GetEchoTimer();        //t就是高电平持续的时间
      lengthTemp = ((float)t/58.0);//lengthTemp = 58*t;
      sum = lengthTemp + sum ;
        
    }
    lengthTemp = sum/5.0;//测量五次取平均值
    return lengthTemp;
}

有了驱动代码,我们就可以直接调用float Hcsr04GetLength(void )来获取超声波测距模块测量的距离了,然后调整电机的转动就可以实现控制距离了。

总结

最终效果

稍后奉上视频(狗头保命)

你见过会说话的小车吗

本文仅仅简单介绍了超声波测距的原理和驱动代码的编写,这样就完成了智能小车的控制距离功能,后面还会有手势识别传感器、红外遥控等等,去实现更多的功能,感谢阅读,如果觉得我的文章对你有帮助的话,就点个赞吧!爱了爱了

你可能感兴趣的:(智能小车,stm32,单片机,自动驾驶)