STM32
直播中

陈敏

7年用户 1294经验值
私信 关注
[问答]

有哪几种方法去实现HC-SR04超声波测距呢

HC-SR04超声波测距模块的原理是什么?
有哪几种方法去实现HC-SR04超声波测距呢?

回帖(1)

史岩超

2021-12-1 09:48:45
HC-SR04 超声波测距模块

超声波测距原理及方法一
方法二
方法三:

在向Trig控制端发送触发信号后,一直等待到Echo引脚的响应后(变为高电平)并打开定时器计数直到Echo引脚变为低电平,关闭定时器,记录下计时时间,通过公式进行计算具体的距离。
程序:

定时器初始化
tim.c

#include "tim.h"
#include "delay.h"
#include "Printf.h"


/*2020.11.16*/




//通用定时器 3 初始化
void TIM3_Int_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟 TIM3 使能
        //中断优先级 NVIC 设置
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;       //TIM3 中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;     //先占优先级 0 级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;     //从优先级 0 级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;     //IRQ 通道被使能
        NVIC_Init(&NVIC_InitStructure);     //初始化 NVIC 寄存器
        //定时器 TIM3 初始化
        TIM_DeInit(TIM3);
        TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM 向上计数
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);       //初始化 TIM3
        //TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );       //允许更新中断
        TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE );       //不允许更新中断
        TIM_Cmd(TIM3, DISABLE);     //关闭 TIM3


}


tim.h


#include "sys.h"




//通用定时器 3 初始化
void TIM3_Int_Init(u16 arr,u16 psc);


//通用定时器 5 初始化
void TIM5_Int_Init(u16 arr,u16 psc);


超声波引脚配置
hc-sr04.c


#include "hc-sr04.h"
#include "tim.h"
#include "delay.h"
#include "Printf.h"


/*2020.11.16
* HC-SR04超声波测距模块
* 基本工作原理:* 给TRIG引脚至少10us的高电平信号触发测距
                                                         * 模块自动发送8个40KHz的方波,自动检测是否有信号返回
                                                         * 有信号返回,通过Echo引脚输出一个高电平,高电平的持续时间就是超声波从发射到返回的时间
                                                         * 测量距离 = (高电平的持续时间 * 声速(340m/s))/ 2
*/


#define HC_SR04_TRIG_CLK   RCC_APB2Periph_GPIOA   //脉冲触发TRIG端口
#define HC_SR04_TRIG_PORT  GPIOA
#define HC_SR04_TRIG_PIN   GPIO_Pin_11     //11


#define HC_SR04_ECHO_CLK   RCC_APB2Periph_GPIOA   //回波接收ECHO端口
#define HC_SR04_ECHO_PORT  GPIOA
#define HC_SR04_ECHO_PIN   GPIO_Pin_12   //12






//HC_SR04超声波初始化
void HC_SR04_Init(void)
{
        GPIO_InitTypeDef  GPIO_InitStructure;
       
        RCC_APB2PeriphClockCmd(HC_SR04_TRIG_CLK, ENABLE);         //使能PA端口时钟
       
        GPIO_InitStructure.GPIO_Pin = HC_SR04_TRIG_PIN;                                 // 脉冲触发端口(Trig)配置PA4
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                  //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_Init(HC_SR04_TRIG_PORT, &GPIO_InitStructure);                                         //根据设定参数初始化端口


        GPIO_InitStructure.GPIO_Pin = HC_SR04_ECHO_PIN;                                 // 回波接收端口(Echo)配置PA5
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;                  //上拉输入
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 //IO口速度为50MHz
        GPIO_Init(HC_SR04_ECHO_PORT, &GPIO_InitStructure);                                         //根据设定参数初始化端口


}




//发送20us的脉冲触发信号
void HC_SR04_start(void)
{
        GPIO_SetBits(HC_SR04_TRIG_PORT,HC_SR04_TRIG_PIN);    //TRIG置高
        delay_us(20);
        GPIO_ResetBits(HC_SR04_TRIG_PORT,HC_SR04_TRIG_PIN);  //TRIG置低
        delay_ms(10);
}


hc-sr04.h


#include "sys.h"








//HC_SR04超声波初始化
void HC_SR04_Init(void);
//发送20us的脉冲触发信号
void HC_SR04_start(void);


float Senor_Using(void);


main.c


#include "sys.h"
#include "delay.h"
#include "hc-sr04.h"
#include "usart.h"
#include "Printf.h"
#include "tim.h"






int main(void)
{
        float Distance;
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);        //系统时钟设置PLL作为系统时钟
        delay_init();                        //初始化延时函数
               
        uart_init(115200);


        printf("开始测量距离rn");
       
        /*在发送触发信号后一直等待Echo引脚的响应(变为高电平)并
        打开定时器计时直到Echo变为低电平,关闭定时器记录下计时时间*/
        HC_SR04_Init();      //HC_SR04超声波初始化配置
        TIM3_Int_Init(49999,7199);
       
        GPIO_SetBits(GPIOA,GPIO_Pin_11);    //TRIG置高
        delay_us(20);
        GPIO_ResetBits(GPIOA,GPIO_Pin_11);  //TRIG置低
               
        //等待回响信号
        while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12) == RESET);
        TIM_Cmd(TIM3,ENABLE);  //使能TIM3定时器
        while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12) == SET);  //回响信号消失
        TIM_Cmd(TIM3,DISABLE); //关闭定时器
        //获取TIM3计数器的值
        Distance = TIM_GetCounter(TIM3)* 340/200.0;  //计算距离:cnt * 1/10000 * 340 / 2(单位:m)
               
        TIM_SetCounter(TIM3,0);  //计数清零
        delay_ms(100);
        printf("测的距离 = %.2f cm rn",Distance);
       


       
        //while(1);


}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分