stm32f1驱动HC-SR04超声波测距模块

2023-10-31 13:58

本文主要是介绍stm32f1驱动HC-SR04超声波测距模块,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这段时间算是比较系统的学习了一点stm32相关的东西,驱动超声波测距模块这个简单的小任务综合了定时器,中断,串口三个知识点,拿来练手还是挺不错的

首先先介绍一下HC-SR04模块:

 

以上是该模块原理的简介,就我个人体验而言,实际使用中,HC-SR04的稳定性可以说是很不错的, 测距的精度与范围基本上可以满足大部分小型项目的需求,最关键的一点,它的驱动非常的简单(虽然这并不影响菜鸡的我搞了3天才弄成)

那么简单说一下驱动的注意事项,由于模块所需要的供电是5V,而板子能直接供的电压只有3V3,因此我拿了个充电宝来当电源,当然,如果有锂电池啥的就更好了

其次,引脚设置时不要弄反,TRIG引脚作为输出,而ECHO引脚作为输入

我所实现的功能是超声波模块用来读取距离数据,用串口将数据打印到屏幕上

那么废话完毕,开始上图上代码:

cubemx内部的设置如图所示

这是引脚的设置,我启用了定时器TIM2用来记时,以及它的2通道用来做输入捕获,顺便启用了一下串口

中断的设置如图所示,使能了定时器中断和串口中断(其实串口中断不需要使能,我只是随手点了而已) 

定时器2的设置如图所示,分频设为80,重载值设为10000 ,捕获触发设为下降沿

 

 然后就可以愉快的生成工程文件了

关于具体的测距程序,只能说一切都要跟着原理走,我就很想不开的脱离原理写了一天程序,然后发现自己写得东西一点鬼用没有,于是重新上网去各种借鉴,终于搞清楚自己是哪里出了问题,希望大家以后驱动别的模块时

一    定    要    先     看     懂     原     理!

不然会出各种各样神奇的bug还不知道怎么搞,超声波测距的程序如下,我放在了一个自己创建的soner.c文件里面:

#include "main.h"
#include "stm32f1xx_hal.h"
#include "stm32f1xx_it.h"static float distance_temp=0;
static float distance_last=0;
static float distance_result;
/*
*********************************************************
函数原型:void Delay_us(uint16_t time)
函数输入:无符号整形
函数输出:无
函数功能:延时,与HAL_Delay类似,但是使用了定时器,Delay_us的单位是1*e-5s
*********************************************************
*/
void Delay_us(uint16_t time)
{uint16_t a1=TIM2->CNT;while(TIM2->CNT-a1<time);
}
/*
*********************************************************
函数原型:void soner_startrange(void)
函数输入:无
函数输出:无
函数功能:从trig引脚生成一个宽度为20个单位的方波
*********************************************************
*/
void soner_startrange(void)
{HAL_GPIO_WritePin(SONER_PORT,SONER_TRIG_PIN,GPIO_PIN_SET);Delay_us(20);HAL_GPIO_WritePin(SONER_PORT,SONER_TRIG_PIN,GPIO_PIN_RESET);}
/*
*********************************************************
函数原型:uint16_t soner_gettime(void)
函数输入:无
函数输出:无符号整型
函数功能:通过定时器获取当前时间
*********************************************************
*/
uint16_t soner_gettime(void)
{uint32_t a;a=TIM2->CNT;return a;
}
/*
*********************************************************
函数原型:float soner_getdistance(void)
函数输入:无
函数输出:浮点型
函数功能:获取与目标之间的距离
*********************************************************
*/
float soner_getdistance(void)
{   uint16_t time_node1;uint16_t time_node2;uint16_t measure;soner_startrange();while(HAL_GPIO_ReadPin(SONER_PORT,SONER_ECHO_PIN)==RESET);time_node1=soner_gettime();while(HAL_GPIO_ReadPin(SONER_PORT,SONER_ECHO_PIN)==SET);time_node2=soner_gettime();measure=time_node2-time_node1;distance_temp = measure * 17.0/100;
//由于模块本身的问题,数据可能存在噪声,因此添加一个限幅滤波,具体原理在此处不加以赘述if(distance_last==0)distance_last = distance_temp;if(distance_last-distance_temp>100 || distance_temp-distance_last>100){distance_result =distance_last;distance_last=distance_temp;}else{distance_result=distance_temp;distance_last=distance_temp;}return distance_result;
}

然后是头文件soner.h

#ifndef _SONER_H_
#define _SONER_H_
void Delay_us(uint16_t time);
void soner_startrange(void);
float soner_getdistance(void);
uint16_t soner_gettime(void);
#endif

 

最后在main.c里面调用以上函数就行了,简简单单轻轻松松

#include "main.h"
#include "stm32f1xx_hal.h"/* USER CODE BEGIN Includes */
#include <soner.h>
/* USER CODE END Includes *//* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;UART_HandleTypeDef huart1;/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
static float distance=0;
/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_TIM2_Init(void);/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
#undef __GNUC__
#ifdef __GNUC__#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else#define PUTCHAR_PROTOTYPE int fputc(int ch,FILE *f)
#endifPUTCHAR_PROTOTYPE{HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,0xffff);return ch;}
/* USER CODE END PFP *//* USER CODE BEGIN 0 *//* USER CODE END 0 *//*** @brief  The application entry point.** @retval None*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();MX_TIM2_Init();/* USER CODE BEGIN 2 */HAL_TIM_Base_Start_IT(&htim2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){distance=soner_getdistance();printf("%.2f\n",distance);HAL_Delay(50);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */}

 

 另外专门需要提一句的是,我在main.h内定义了引脚SONER_PORT,SONER_ECHO_PIN和SONER_TRIG_PIN,代码如下:

#ifndef __MAIN_H__
#define __MAIN_H__/* Includes ------------------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private define ------------------------------------------------------------*/
#define SONER_PORT GPIOA
#define SONER_ECHO_PIN GPIO_PIN_1
#define SONER_TRIG_PIN GPIO_PIN_0

 

 初次搞这个东西会是一个漫长的写bug,debug的过程,希望大家一切顺利,我在上一篇文章里提到了一些我自己遇到的比较坑的error,大家有兴趣可以看一下

以上

p.s以上代码的具体原理,大家可以自己去搜索stm32的定时器,中断,输入捕获,串口等关键词去找教程,当然,说不定某一天我这只鸽子会开个视频详细一点讲讲这边的东西

咕咕咕,咕咕咕

以及一张实际的接线图

这篇关于stm32f1驱动HC-SR04超声波测距模块的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315830

相关文章

Python中logging模块用法示例总结

《Python中logging模块用法示例总结》在Python中logging模块是一个强大的日志记录工具,它允许用户将程序运行期间产生的日志信息输出到控制台或者写入到文件中,:本文主要介绍Pyt... 目录前言一. 基本使用1. 五种日志等级2.  设置报告等级3. 自定义格式4. C语言风格的格式化方法

Python 基于http.server模块实现简单http服务的代码举例

《Python基于http.server模块实现简单http服务的代码举例》Pythonhttp.server模块通过继承BaseHTTPRequestHandler处理HTTP请求,使用Threa... 目录测试环境代码实现相关介绍模块简介类及相关函数简介参考链接测试环境win11专业版python

Java+AI驱动实现PDF文件数据提取与解析

《Java+AI驱动实现PDF文件数据提取与解析》本文将和大家分享一套基于AI的体检报告智能评估方案,详细介绍从PDF上传、内容提取到AI分析、数据存储的全流程自动化实现方法,感兴趣的可以了解下... 目录一、核心流程:从上传到评估的完整链路二、第一步:解析 PDF,提取体检报告内容1. 引入依赖2. 封装

Nginx添加内置模块过程

《Nginx添加内置模块过程》文章指导如何检查并添加Nginx的with-http_gzip_static模块:确认该模块未默认安装后,需下载同版本源码重新编译,备份替换原有二进制文件,最后重启服务验... 目录1、查看Nginx已编辑的模块2、Nginx官网查看内置模块3、停止Nginx服务4、Nginx

python urllib模块使用操作方法

《pythonurllib模块使用操作方法》Python提供了多个库用于处理URL,常用的有urllib、requests和urlparse(Python3中为urllib.parse),下面是这些... 目录URL 处理库urllib 模块requests 库urlparse 和 urljoin编码和解码

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录

idea Maven Springboot多模块项目打包时90%的问题及解决方案

《ideaMavenSpringboot多模块项目打包时90%的问题及解决方案》:本文主要介绍ideaMavenSpringboot多模块项目打包时90%的问题及解决方案,具有很好的参考价值,... 目录1. 前言2. 问题3. 解决办法4. jar 包冲突总结1. 前言之所以写这篇文章是因为在使用Mav

Python标准库datetime模块日期和时间数据类型解读

《Python标准库datetime模块日期和时间数据类型解读》文章介绍Python中datetime模块的date、time、datetime类,用于处理日期、时间及日期时间结合体,通过属性获取时间... 目录Datetime常用类日期date类型使用时间 time 类型使用日期和时间的结合体–日期时间(

Linux之platform平台设备驱动详解

《Linux之platform平台设备驱动详解》Linux设备驱动模型中,Platform总线作为虚拟总线统一管理无物理总线依赖的嵌入式设备,通过platform_driver和platform_de... 目录platform驱动注册platform设备注册设备树Platform驱动和设备的关系总结在 l

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数