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的secrets模块

《一文深入详解Python的secrets模块》在构建涉及用户身份认证、权限管理、加密通信等系统时,开发者最不能忽视的一个问题就是“安全性”,Python在3.6版本中引入了专门面向安全用途的secr... 目录引言一、背景与动机:为什么需要 secrets 模块?二、secrets 模块的核心功能1. 基

Python logging模块使用示例详解

《Pythonlogging模块使用示例详解》Python的logging模块是一个灵活且强大的日志记录工具,广泛应用于应用程序的调试、运行监控和问题排查,下面给大家介绍Pythonlogging模... 目录一、为什么使用 logging 模块?二、核心组件三、日志级别四、基本使用步骤五、快速配置(bas

如何在Ubuntu上安装NVIDIA显卡驱动? Ubuntu安装英伟达显卡驱动教程

《如何在Ubuntu上安装NVIDIA显卡驱动?Ubuntu安装英伟达显卡驱动教程》Windows系统不同,Linux系统通常不会自动安装专有显卡驱动,今天我们就来看看Ubuntu系统安装英伟达显卡... 对于使用NVIDIA显卡的Ubuntu用户来说,正确安装显卡驱动是获得最佳图形性能的关键。与Windo

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

Python datetime 模块概述及应用场景

《Pythondatetime模块概述及应用场景》Python的datetime模块是标准库中用于处理日期和时间的核心模块,本文给大家介绍Pythondatetime模块概述及应用场景,感兴趣的朋... 目录一、python datetime 模块概述二、datetime 模块核心类解析三、日期时间格式化与

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

Python如何调用指定路径的模块

《Python如何调用指定路径的模块》要在Python中调用指定路径的模块,可以使用sys.path.append,importlib.util.spec_from_file_location和exe... 目录一、sys.path.append() 方法1. 方法简介2. 使用示例3. 注意事项二、imp

Python中模块graphviz使用入门

《Python中模块graphviz使用入门》graphviz是一个用于创建和操作图形的Python库,本文主要介绍了Python中模块graphviz使用入门,具有一定的参考价值,感兴趣的可以了解一... 目录1.安装2. 基本用法2.1 输出图像格式2.2 图像style设置2.3 属性2.4 子图和聚

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中