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: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

Jenkins构建Maven聚合工程,指定构建子模块

一、设置单独编译构建子模块 配置: 1、Root POM指向父pom.xml 2、Goals and options指定构建模块的参数: mvn -pl project1/project1-son -am clean package 单独构建project1-son项目以及它所依赖的其它项目。 说明: mvn clean package -pl 父级模块名/子模块名 -am参数

寻迹模块TCRT5000的应用原理和功能实现(基于STM32)

目录 概述 1 认识TCRT5000 1.1 模块介绍 1.2 电气特性 2 系统应用 2.1 系统架构 2.2 STM32Cube创建工程 3 功能实现 3.1 代码实现 3.2 源代码文件 4 功能测试 4.1 检测黑线状态 4.2 未检测黑线状态 概述 本文主要介绍TCRT5000模块的使用原理,包括该模块的硬件实现方式,电路实现原理,还使用STM32类

python内置模块datetime.time类详细介绍

​​​​​​​Python的datetime模块是一个强大的日期和时间处理库,它提供了多个类来处理日期和时间。主要包括几个功能类datetime.date、datetime.time、datetime.datetime、datetime.timedelta,datetime.timezone等。 ----------动动小手,非常感谢各位的点赞收藏和关注。----------- 使用datet

C8T6超绝模块--EXTI

C8T6超绝模块–EXTI 大纲 控制流程结构体分析EXTI实现按键 具体案例 控制流程 这里是流程框图,具体可以去看我STM32专栏的EXTI的具体分析 结构体分析 typedef struct {uint32_t EXTI_Line; // 中断/事件线EXTIMode_TypeDef EXTI_Mode; // EXTI 模式EXTITrigger_TypeDef EXTI_

1、创建多模块的maven springboot项目

现在的java的项目都是多模块的,这次也跟个风。 目标:实现下述结构 项目AcedBoot, 子模块:         aced-api 对外提供接口,         aced-web 给前端提供接口,         aced-service 服务层,         aced-dao 数据底层,包含数据库mapper和实体类entity,         aced-commo

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl