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

devtools/2025/1/7 20:43:00/

一、简介

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:使其读一个数用1ustim2_handle.Init.Period = 65536-1; //ARRtim2_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(); //启动定时器2tim2_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/usdistance = 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.ppmy.cn/devtools/148279.html

相关文章

Spring MVC实战指南:构建高效Web应用的架构与技巧(三)

响应数据和结果视图(7种) 返回值分类 创建web.xml&#xff08;spring、过滤器解决乱码、配置控制器dispatcherServlet、加载springmvc.xml文件、配置启动加载&#xff09;创建springmvc.xml文件 <!--配置了内容&#xff0c;启动Tomcat服务器的时候&#xff0c;就会被加载--…

设计模式之访问者模式:一楼千面 各有玄机

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 一、访问者模式概述 \quad 江湖中有一个传说&#xff1a;在遥远的东方&#xff0c;有一座神秘的玉楼。每当武林中人来访&#xff0c;楼中的各个房…

QML学习(七) 学习QML时,用好Qt设计器的属性

在初步学习QML时&#xff0c;特别建议看看Qt设计器&#xff0c;先利用Qt Quick设计师的使用&#xff0c;快速的对Qt Quick的各个组件及其常用的属性&#xff0c;有个初步的了解和认识。如果初始学习一上来直接以代码形式开干&#xff0c;很容易一头雾水。而设计器以最直白的所见…

.net core强大的列表对比取数

将一个list的中的所有数据在另一个list中找出&#xff0c;并将找到的数据生成一个新的list。 背景&#xff1a; 有一个大的字符串类型的list Alllist&#xff0c;中包含可营销的数据和不可营销的数据&#xff0c;共八千万条 另一个字符串list CanMarkelist中包含不可营销的数据…

除了淘宝、天猫和京东,其他电商平台的按图搜索商品API返回值结构是怎样的?

除了淘宝、天猫和京东&#xff0c;拼多多、抖音等电商平台的按图搜索商品 API 返回值结构如下&#xff1a; 拼多多 拼多多虽然目前暂无公开的按图搜索商品 API&#xff0c;但从其根据关键词取商品列表 API 以及商品详情数据接口的返回值结构可推测&#xff0c;按图搜索商品 API…

今日头条ip属地根据什么显示?不准确怎么办

在今日头条这样的社交媒体平台上&#xff0c;用户的IP属地信息对于维护网络环境的健康与秩序至关重要。然而&#xff0c;不少用户发现自己的IP属地显示与实际位置不符&#xff0c;这引发了广泛的关注和讨论。本文将深入探讨今日头条IP属地的显示依据&#xff0c;并提供解决IP属…

解决Spring boot集成quartz时service注入失败为null的问题

解决Spring boot集成quartz时service注入失败为null的问题 一、报错信息二、代码任务类源代码配置类原代码 三、注入失败原因四、解决的思路11、任务类修改2、配置类修改 五、 解决的思路2 一、报错信息 java.lang.NullPointerException: null at farbun.server.scheduledTask…

数据挖掘——认识数据

数据挖掘——认识数据 数据对象和属性数据对象属性和属性值 数据统计与可视化数据统计汇总离散度度量 数据的相似性和相异性度量数值属性的邻近性度量 数据对象和属性 数据对象 数据集由数据对象组成 一个数据对象代表一个实体 例子 销售数据库&#xff1a;客户&#xff0c;…