基于STM32F407的US-100超声波测距设计

前言:前面介绍了一个数码管的显示超声波测距所测的距离编程和设计,现在介绍一下超声波测距这个模块的设计与编程。

1、US-100超声波的简单描述

来一个简单的原理图:

基于STM32F407的US-100超声波测距设计
通过图片可以看出超声波测距的原理,简单描述一下就是一端发出超声波,另一端接受通过接触到物体反射回来的超声波,然后简单的做一下算术的运算就可以得出一个相对准确的数据。
在一般的超声波测距模块中,这个物体是有一定的要求,比如要求反射物体呈现水平状,不能是斜的或者凹凸不平之类的,要不然会影响数据的精准性。

2、US-100超声波的引脚接线

直接上图:
基于STM32F407的US-100超声波测距设计
如图所示:
1号接电源;
2号在usart模式下接tx发送端在电平触发模式下随便接个IO口就行了;
3号引脚在usaer模式下接rx接受端在电平触发模式随便接个IO口;
4号和5号都是接地,我在触发电平测试的时候只接一个地也是可以工作的;

看到这里大家可能会有一个疑问,就是这个怎么选择工作模式呢?
单单看这面这个图的话确实是不知道怎么设置。是因为这个模块是外有乾坤的,下面直接上图展示:
基于STM32F407的US-100超声波测距设计
哈哈,就是像上图所示,把后面那个跳线帽摘掉是触发电平模式,插上跳线帽就是usart工作模式。

3、程序编写

看了前两节是不是对于怎么编程都有了一定的了解和想法头绪了呢,是不是挺简单的一个模块。
因为我在使用中没有使用到检测温度的功能所以就简单的使用了电平触发工作模式,也就是普通的IO口配置,一个推挽输出,一个输入。
这里说一件和程序无关的事情,如果大家在接触过超声波额就知道,在某宝上面,超声波模块大致上都有两款,一款为HC-SR04,另一款就是这个US-100,其中的价格区别也是挺大的;HC-SR04比US-100便宜了十几元。
这里我为什么不选HC-SR04呢?
当然一开始选择的时候是选择HC-SR04,但是后面使用的时候发现HC-SR04所测的距离它有时候会飘,也就是突然间变化很大,后面经过排查和调试,发现解决不了,这里的排查和调试试对于软件程序方面,硬件没有弄,因为是模块化的。当然,我解决不了也有可能是我的实力还没到达那个地步,哈哈哈。
在解决不了的情况下决定了采用另一款,也就是US-100这款,使用了这款之后才发现差距居然如此之大……所以我这里才会介绍US-100没有说HC-SR04,选择的超声波也是这款比较贵的原因……

哈哈哈,这里废话说多了,下面直接上代码和注释:
超声波初始化:

/**********************************
函数说明:US-100超声波引脚初始化程序
参数:NONE
返回值:NONE
引脚:Trig----PA4
      Echo----PA5
**********************************/
void Us100_Init(void)
{
       GPIO_InitTypeDef GPIO_InitStructure;
   
    //时能时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);  //使能GPIOA时钟
 
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;               //Trig
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;           //输出模式。
    GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;          //推挽输出
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;        //无上,下拉模式
    GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
 
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;               //Echo
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;            //输入模式。
    GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_DOWN;          //无上,下拉模式
    GPIO_Init(GPIOA,&GPIO_InitStructure);
}

这里使用到定时器来计数,得出超声波发出后到接受这个中间的时间。

定时器初始化:

/**********************************
函数说明:定时器3初始化程序
参数:NONE
返回值:NONE
**********************************/
void Tim3_int(void)
{
    RCC->APB1ENR|=1<<1; //TIM3时钟使能    
    TIM3->ARR=49999;     //设定计数器自动重装值  50ms 中断一次 ,1us计一个数
    TIM3->PSC=83;       //预分频器   
    TIM3->DIER|=1<<0;    //允许更新中断
}

这里初始化都完成了后开始应用程序了。

应用程序:

/**********************************
函数说明:获取超声波侧得到的距离
参数:NONE
返回值:距离
**********************************/
uint16_t Get_DistanceData(void)
{
     uint16_t dis;
     uint16_t Distance;
     
     TIM3 -> CR1 |= (1<<0);
     Trig(1);
     delay_us(14);                 //这里的延时可以是12us--20us   测试可行通过,具体多少看那你项目要求
     Trig(0);
     while(!Echo);                 //等待等待回响信号变为高电平
     TIM3 -> CNT = 0;              //让cnt的值变为0,开始计算
     while(Echo);                  //等待等待回响信号变为低电平
     TIM3 -> CR1 &=~ (1<<0);       //停止计数
     dis = TIM3 -> CNT;            //获取中间时间
     //printf("%d\n",dis);
     Distance = dis/58;            //算出距离
     
     return Distance;              //返回距离
}

头文件:

#ifndef US100_H
#define US100_H

#include "stm32f4xx.h"

#define Trig(x)  (x? GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_SET):GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_RESET))
#define Echo     (GPIOA -> IDR & (1<<5))

void Us100_Init(void);
void Tim3_int(void);
uint16_t Get_DistanceData(void);

#endif

这里已经介绍完毕,大家有什么疑问的话可以在评论区评论,觉得不错的话可以点个赞!

上一篇:C++11新特性之 explict


下一篇:Linux-安装-首次登录-命令行使用-帮助使用-关机