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

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

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

来一个简单的原理图:

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

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

直接上图:
在这里插入图片描述
如图所示:
1号接电源;
2号在usart模式下接tx发送端在电平触发模式下随便接个IO口就行了;
3号引脚在usaer模式下接rx接受端在电平触发模式随便接个IO口;
4号和5号都是接地,我在触发电平测试的时候只接一个地也是可以工作的;

看到这里大家可能会有一个疑问,就是这个怎么选择工作模式呢?
单单看这面这个图的话确实是不知道怎么设置。是因为这个模块是外有乾坤的,下面直接上图展示:
在这里插入图片描述
哈哈,就是像上图所示,把后面那个跳线帽摘掉是触发电平模式,插上跳线帽就是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

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

  • 6
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
以下是基于STM32的hc-sr04超声波测距模块的代码示例: ```c #include "stm32f10x.h" #define Trig_Pin GPIO_Pin_0 #define Echo_Pin GPIO_Pin_1 #define Trig_Port GPIOC #define Echo_Port GPIOC void TIM2_Configuration(void); float ultrasonic_measure(void); int main(void) { float distance; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = Trig_Pin; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(Trig_Port, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = Echo_Pin; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(Echo_Port, &GPIO_InitStruct); TIM2_Configuration(); while(1) { distance = ultrasonic_measure(); } } void TIM2_Configuration(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; TIM_TimeBaseInitStruct.TIM_Prescaler = 72 - 1; TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF; TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_OCInitTypeDef TIM_OCInitStruct; TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStruct.TIM_Pulse = 0; TIM_OC1Init(TIM2, &TIM_OCInitStruct); TIM_Cmd(TIM2, ENABLE); } float ultrasonic_measure(void) { uint16_t TIM2_CountStart, TIM2_CountEnd; float Distance; GPIO_ResetBits(Trig_Port, Trig_Pin); TIM_SetCounter(TIM2, 0); while(TIM_GetCounter(TIM2) < 10); // delay 10us GPIO_SetBits(Trig_Port, Trig_Pin); while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == RESET); TIM_Cmd(TIM2, ENABLE); while(GPIO_ReadInputDataBit(Echo_Port, Echo_Pin) == SET); TIM_Cmd(TIM2, DISABLE); TIM2_CountStart = TIM2->CCR1; TIM2_CountEnd = TIM_GetCapture1(TIM2); Distance = (float)(TIM2_CountEnd - TIM2_CountStart) * 0.01715f; // Distance = (High level time * sound velocity (340M/S) / 2) return Distance; } ``` 代码中使用了STM32的定时器TIM2进行计时,测量距离的原理是通过发送一个10us的高电平脉冲触发hc-sr04模块,然后接收返回的超声波信号并测量高电平持续时间,最后通过公式计算出距离。需要注意的是,本示例中使用的是72MHz的系统时钟,如果系统时钟不同,需要相应地修改计时器的预分频值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值