当前位置: 首页 > article >正文

STM32-笔记23-超声波传感器HC-SR04

一、简介

HC-SR04 工作参数:

• 探测距离:2~600cm

• 探测精度:0.1cm±1%

• 感应角度:<15°

• 输出方式:GPIO

• 工作电压:DC 3~5.5V

• 工作电流:5.3mA

• 工作温度:-40~85℃

 

  •  怎么让它发送波 Trig?

        给Trig端口至少10us的高电平

  • 怎么知道它开始发了波 Echo引脚?

        由低电平跳转到高电平,表示开始发送波

  • 怎么知道接收了返回波 Echo?

        由高电平跳转回低电平,表示波回来了

  • 怎么算时间 ?

        Echo引脚维持高电平的时间,波发出去的那一下,开始启动定时器 波回来的那一下,我们开始停止定时器,计算出中间经过多少时间

  • 怎么算距离?

        距离 = 速度(343m/s) * 时间 / 2

 二、实验前期准备

        因为想把测出来的距离打印在串口上,所以复制项目文件19-串口打印功能,重命名25-超声波传感器,新建文件夹hc-sr04

打开工程文件

加载文件

引脚接线

三、代码:

main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "uart1.h"
#include "hcsr04.h"

int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();//初始化led灯
    hcsr04_init();
    uart1_init(115200);
    while(1)
    { 
        printf("距离是:%.2f\r\n",hcsr04_get_lenght());
        delay_ms(1000);
    }
}

hcsr04.c

#include "hcsr04.h"
#include "delay.h"

TIM_HandleTypeDef tim2_handle = {0};//定义结构体

//定时器初始化函数
void timer_init()//把ARR和PSC当作参数传进来
{
    tim2_handle.Instance = TIM2; //选择使用的定时器
    tim2_handle.Init.Prescaler = 72-1; //PSC:使其读一个数用1us
    tim2_handle.Init.Period = 65536-1; //ARR
    tim2_handle.Init.CounterMode = TIM_COUNTERMODE_UP;//配置成向上的,默认向上的
    tim2_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;  //自动重装载,默认自动重装载
    
    HAL_TIM_Base_Init(&tim2_handle);
//    HAL_TIM_Base_Start_IT(&tim2_handle);//设置使能更新中断,和启动计数器
}

//msp函数
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if(htim->Instance == TIM2)
    {
        __HAL_RCC_TIM2_CLK_ENABLE();
//        HAL_NVIC_SetPriority(TIM2_IRQn,2,2);//设置优先级
//        HAL_NVIC_EnableIRQ(TIM2_IRQn);//设置使能中断
    }
}
//定时器启动的函数
void tim2_start(void) 
{
    HAL_TIM_Base_Start(&tim2_handle);
}
//定时器关闭的函数
void tim2_stop(void) 
{
    HAL_TIM_Base_Stop(&tim2_handle);
}
//读CNT计数器的值
uint16_t tim2_get_cnt(void) 
{
    return __HAL_TIM_GetCounter(&tim2_handle);
}
//将CNT计数器的值传递进来
void tim2_set_cnt(uint16_t val) 
{
    __HAL_TIM_SetCounter(&tim2_handle,val);
}
//初始化gpio口引脚
void hcsr04_gpio_init(void)
{   
    GPIO_InitTypeDef gpio_initstruct;//定义一个结构体gpio_initstruct
    //打开trig和echo时钟
    TRIG_GPIO_CLK_ENABLE();
    ECHO_GPIO_CLK_ENABLE();
    
    //调用TRIG的GPIO初始化函数
    gpio_initstruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出
    gpio_initstruct.Pin = TRIG_PIN;//trig对应的引脚
    gpio_initstruct.Pull = GPIO_NOPULL;//引脚不拉
    gpio_initstruct.Speed = GPIO_SPEED_FREQ_HIGH;//高速
    
    HAL_GPIO_Init(TRIG_PORT,&gpio_initstruct);
    
    //调用echo的GPIO初始化函数
    gpio_initstruct.Mode = GPIO_MODE_INPUT;//作为输入引脚
    gpio_initstruct.Pin = ECHO_PIN;//echo对应的引脚
    
    HAL_GPIO_Init(ECHO_PORT,&gpio_initstruct);
}
//初始化超声波
void hcsr04_init(void)
{
    timer_init();//初始化定时器
    hcsr04_gpio_init();//初始化GPIO引脚
    
}
//读取超声波测出来的距离
float hcsr04_get_lenght(void)
{
    uint16_t total_time = 0;  //定义一个变量用于接收CNT的值
    float distance = 0;
    //1、Trig,给Trig端口至少10us的高电平
    TRIG_HIGH();
    delay_us(15);
    TRIG_LOW();
    
    //2、Echo引脚,由低电平跳转到高电平,表示开始发送波
        //波发出去的那一下,开始启动定时器
    while(ECHO_STATUS() == GPIO_PIN_RESET);//用echo引脚是否从低电平变成高电平来决定波是否发出去了
    tim2_start(); //启动定时器2
    tim2_set_cnt(0);//将定时器初始值置0
    //3、Echo,由高电平跳转回低电平,表示波回来了
        //波回来的那一下,我们开始停止定时器
    while(ECHO_STATUS() == GPIO_PIN_SET);//用echo引脚是否从高电平变成低电平来决定波是否接到
    tim2_stop();//关掉定时器
    
    //4、Echo引脚维持高电平的时间=计算出中间经过多少时间
    total_time = tim2_get_cnt();//用total_time接收CNT定时器里面的值
    
    //距离 = 速度(343m/s) * 时间 / 2
    //343m/s = 34300cm/s,因为距离是一个来回,所以要/2(这里速度除2下面路程就不用除2了)
    // = 34300/2 = 17150cm/s = 0.017150cm/us
    distance = total_time * 0.01715;
    return distance;
}

hcsr04.h

#ifndef __HCSR04_H__
#define __HCSR04_H__

#include "sys.h"

#define TRIG_PORT                 GPIOB                                             //trig对应gpio的哪一组
#define TRIG_PIN                  GPIO_PIN_6                                        //trig对应gpio的哪个引脚
#define TRIG_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()                      //gpio口时钟打开
#define TRIG_HIGH()               HAL_GPIO_WritePin(TRIG_PORT,TRIG_PIN,GPIO_PIN_SET)//trig对应的引脚拉高
#define TRIG_LOW()                HAL_GPIO_WritePin(TRIG_PORT,TRIG_PIN,GPIO_PIN_RESET)//trig对应的引脚拉低

#define ECHO_PORT                 GPIOB                                             //echo对应gpio的哪一组
#define ECHO_PIN                  GPIO_PIN_7                                        //echo对应gpio的哪个引脚
#define ECHO_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()                      //gpio口时钟打开
#define ECHO_STATUS()             HAL_GPIO_ReadPin(ECHO_PORT,ECHO_PIN)              //读取echo对应的引脚电平

void hcsr04_init(void);
float hcsr04_get_lenght(void);

#endif

打开串口助手,每一秒超声波都在测距


http://www.kler.cn/a/467132.html

相关文章:

  • 【CPU】堆栈和堆栈指针(个人草稿)
  • SQL使用游标
  • 【网络协议】IPv4 地址分配 - 第一部分
  • Vue3+Element Plus的表格分页实战
  • 重庆大学软件工程复试怎么准备?
  • 【sql】CAST(GROUP_CONCAT())实现一对多对象json输出
  • kubernets基础入门
  • 基于STM32的热带鱼缸控制系统的设计
  • 大模型数据采集和预处理:把所有数据格式,word、excel、ppt、jpg、pdf、表格等转为数据
  • 高清监控视频的管理与展示:从摄像头到平台的联接过程
  • 呼叫中心中间件实现IVR进入排队,判断排队超时播放提示音
  • Git快速入门(一)·Git软件的安装以及GitHubDesktop客户端的安装
  • 装饰器模式详解
  • clickhouse Cannot execute replicated DDL query, maximum retries exceeded报错解决
  • Android 14.0 系统限制上网系列之iptables用IOemNetd实现app上网黑名单的实现
  • 行为模式4.观察者模式------消息推送
  • LangChain+博查搜索API轻松实现实时信息搜索
  • 【每日学点鸿蒙知识】ASON工具、自定义tabbar、musl、Text异常截断等
  • 【C语言】可移植性陷阱与缺陷(五): 移位运算符
  • 初学stm32 --- 存储器类型
  • 文献阅读 250104-Overconfidence in climate overshoot
  • 文件上传漏洞利用与绕过姿势总结
  • 【大模型】ChatGPT 数据分析与处理使用详解
  • SQL 基础教程 - SQL SELECT 语句
  • 部署项目添加工程名的步骤
  • 哈希算法详解及案例应用