使用CubeMX配置STM32驱动HC-SR04超声波模块

news2024/12/23 23:26:07

文章目录

  • 前言
  • 1 使用STM32CubeMX初始化代码
    • 1.1 时钟配置
    • 1.2 设置定时器
    • 1.3 触发引脚
    • 1.4 串口配置
  • 2 代码编写
    • 2.1 添加驱动文件
    • 2.2 修改main.c
  • 3 实现效果
  • 参考

前言

硬件选择

  • stm32f103c8t6(最小板)
  • hc-sr04超声波模块

软件环境

  • stm32cubeIDE 1.12.1

hc-sr04模块超声波测距的原理,在上一篇博客已经提到,这里不在解释说明,详见:https://blog.csdn.net/apple_52030329/article/details/131021811

1 使用STM32CubeMX初始化代码

1.1 时钟配置

时钟配置如下图,我用了8MHz的HSE,HCLK调到了最大值72MHz

在这里插入图片描述

1.2 设置定时器

设置定时器TIM2每1us向上计数一次,通道4为上升沿捕获并连接到超声波模块的ECHO引脚,记得开启定时器中断(涉及到捕获中断+定时器溢出中断)。

在这里插入图片描述

连接ECHO引脚

在这里插入图片描述

1.3 触发引脚

PB10接到了HC-SR04的TIRG触发引脚,默认输出低电平

在这里插入图片描述

1.4 串口配置

配置usart1

在这里插入图片描述

2 代码编写

2.1 添加驱动文件

hc-sr04.h

#ifndef HCSR04_H_
#define HCSR04_H_

#include "main.h"

typedef struct
{
	uint8_t  edge_state;
	uint16_t tim_overflow_counter;
	uint32_t prescaler;
	uint32_t period;
	uint32_t t1;	//	上升沿时间
	uint32_t t2;	//	下降沿时间
	uint32_t high_level_us;	//	高电平持续时间
	float    distance;
	TIM_TypeDef* instance;
  uint32_t ic_tim_ch;
	HAL_TIM_ActiveChannel active_channel;
}Hcsr04InfoTypeDef;

extern Hcsr04InfoTypeDef Hcsr04Info;

/**
 * @description: 超声波模块的输入捕获定时器通道初始化
 * @param {TIM_HandleTypeDef} *htim
 * @param {uint32_t} Channel
 * @return {*}
 */
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel);

/**
 * @description: HC-SR04触发
 * @param {*}
 * @return {*}
 */
void Hcsr04Start(void);

/**
 * @description: 定时器计数溢出中断处理函数
 * @param {*}    main.c中重定义void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
 * @return {*}
 */
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim);

/**
 * @description: 输入捕获计算高电平时间->距离
 * @param {*}    main.c中重定义void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
 * @return {*}
 */
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim);

/**
 * @description: 读取距离
 * @param {*}
 * @return {*}
 */
float Hcsr04Read(void);

#endif /* HCSR04_H_ */

hc-sr04.c

#include "hc-sr04.h"

Hcsr04InfoTypeDef Hcsr04Info;

/**
 * @description: 超声波模块的输入捕获定时器通道初始化
 * @param {TIM_HandleTypeDef} *htim
 * @param {uint32_t} Channel
 * @return {*}
 */
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel)
{
  /*--------[ Configure The HCSR04 IC Timer Channel ] */
  // MX_TIM2_Init();  // cubemx中配置
  Hcsr04Info.prescaler = htim->Init.Prescaler; //  72-1
  Hcsr04Info.period = htim->Init.Period;       //  65535

  Hcsr04Info.instance = htim->Instance;
  if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_1)
  {
    Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_1;             //  TIM_CHANNEL_1
  }
  else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_2)
  {
    Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_2;             //  TIM_CHANNEL_2
  }
  else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_3)
  {
    Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_3;             //  TIM_CHANNEL_3
  }
  else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4)
  {
    Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4;             //  TIM_CHANNEL_4
  }
  /*--------[ Start The ICU Channel ]-------*/
  HAL_TIM_Base_Start_IT(htim);
  HAL_TIM_IC_Start_IT(htim, Channel);
}

/**
 * @description: HC-SR04触发
 * @param {*}
 * @return {*}
 */
void Hcsr04Start(void)
{
  HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_SET);
  HAL_Delay(1);  //  10us以上
  HAL_GPIO_WritePin(TRIG_GPIO_Port, TRIG_Pin, GPIO_PIN_RESET);
}

/**
 * @description: 定时器计数溢出中断处理函数
 * @param {*}    main.c中重定义void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
 * @return {*}
 */
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == Hcsr04Info.instance) //
  {
    Hcsr04Info.tim_overflow_counter++;
  }
}

/**
 * @description: 输入捕获计算高电平时间->距离
 * @param {*}    main.c中重定义void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
 * @return {*}
 */
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim)
{
  if((htim->Instance == Hcsr04Info.instance) && (htim->Channel == Hcsr04Info.active_channel))
  {
    if(Hcsr04Info.edge_state == 0)      //  捕获上升沿
    {
      // 得到上升沿开始时间T1,并更改输入捕获为下降沿
      Hcsr04Info.t1 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);
      __HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_FALLING);
      Hcsr04Info.tim_overflow_counter = 0;  //  定时器溢出计数器清零
      Hcsr04Info.edge_state = 1;        //  上升沿、下降沿捕获标志位
    }
    else if(Hcsr04Info.edge_state == 1) //  捕获下降沿
    {
      // 捕获下降沿时间T2,并计算高电平时间
      Hcsr04Info.t2 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);
      Hcsr04Info.t2 += Hcsr04Info.tim_overflow_counter * Hcsr04Info.period; //  需要考虑定时器溢出中断
      Hcsr04Info.high_level_us = Hcsr04Info.t2 - Hcsr04Info.t1; //  高电平持续时间 = 下降沿时间点 - 上升沿时间点
      // 计算距离
      Hcsr04Info.distance = (Hcsr04Info.high_level_us / 1000000.0) * 340.0 / 2.0 * 100.0;
      // 重新开启上升沿捕获
      Hcsr04Info.edge_state = 0;  //  一次采集完毕,清零
      __HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_RISING);
    }
  }
}

/**
 * @description: 读取距离
 * @param {*}
 * @return {*}
 */
float Hcsr04Read(void)
{
  // 测距结果限幅
  if(Hcsr04Info.distance >= 450)
  {
    Hcsr04Info.distance = 450;
  }
  return Hcsr04Info.distance;
}

2.2 修改main.c

  1. 引用对应的头文件
/* USER CODE BEGIN Includes */
#include "hc-sr04.h"
/* USER CODE END Includes */
  1. 200ms测距一次
/**
  * @brief  The application entry point.
  * @retval int
  */
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_TIM2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  Hcsr04Init(&htim2, TIM_CHANNEL_4);  //  超声波模块初始化
  Hcsr04Start();  //  开启超声波模块测距
  printf("hc-sr04 start!\r\n");
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    // 打印测距结果
    printf("distance:%.1f cm\r\n", Hcsr04Read());
    Hcsr04Start();
    HAL_Delay(200); //  测距周期200ms
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
  1. 重定义定时器的中断服务函数
/* USER CODE BEGIN 4 */
/**
 * @description: 定时器输出捕获中断
 * @param {TIM_HandleTypeDef} *htim
 * @return {*}
 */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
  Hcsr04TimIcIsr(htim);
}

/**
 * @description: 定时器溢出中断
 * @param {*}
 * @return {*}
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
{
  Hcsr04TimOverflowIsr(htim);
}
/* USER CODE END 4 */

3 实现效果

串口打印结果如下:
在这里插入图片描述

实际效果:
在这里插入图片描述

参考

https://blog.csdn.net/qq_57709749/article/details/127163487
https://www.bilibili.com/video/av466707130/?vd_source=c1eec1c601c91b92514190b3c15a337b
http://www.taodudu.cc/news/show-5933197.html?action=onClick

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/612987.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】TCP网络套接字编程+协议定制+序列化和反序列化

悟已往之不谏,知来者之可追。抓不住的就放手,属于你的都在路上…… 文章目录 一、TCP网络套接字编程1.日志等级分类的日志输出API2.单进程版本的服务器客户端通信3.多进程版本和多线程版本4.线程池版本5.守护进程化的线程池服务器6.三次握手和四次挥手的…

python编程——pycharm的安装与使用

作者:Insist-- 个人主页:insist--个人主页 本文专栏:python专栏 专栏介绍:本专栏为免费专栏,并且会持续更新python基础知识,欢迎各位订阅关注。 目录 一、python IDLE的使用 二、pycharm的安装与使用 1、…

十分钟带你看懂——Python测试框架之pytest最全讲

pytest特短 pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点: 简单灵活,容易上手 支持参数化 能够支持简单的单元测试和复杂的功能测试,还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08…

重磅版本发布|三大关键特性带你认识 Milvus 2.2.9 :JSON、PartitionKey、Dynamic Schema

亮点颇多、精彩程度堪比大版本的 Milvus 2.2.9 来啦! 随着 LLM 的持续火爆,众多应用开发者将目光投向了向量数据库领域,而作为开源向量数据库的领先者,Milvus 也充分吸收了大量来自社区、用户、AI 从业者的建议,把重心…

非常简单就能理解的 链表带环问题 你也能轻松学会!

文章目录 判断链表是否带环若链表带环找出环的入口其他高频的面试问题 判断链表是否带环 题目描述: 给定一个链表,判断链表中是否有环。 思路: 可以明确的是:若一个链表带环,那么用指针一直顺着链表遍历&#xff0c…

《嵌入式系统》知识总结10:使用位带操作操纵GPIO

位操作 汇编层面 外设控制常要针对字中某个位(Bit)操作 以字节编址的存储器地址空间中,需要3步骤(读出-修改-写回) 1.(从外设)读取包含该位的字节数据 2. 设置该位为0或1、同时屏蔽其他位&am…

微信小程序 <view></view>容器嵌套,wxss样式修改内部内部样式不产生效果

网上关于”微信小程序讲的知识很少“&#xff0c;微信开发文档对于新手不是很友好&#xff0c;但是建议一定要学会看文档。 问题如下&#xff1a; 我写了好几个<view></view> 容器嵌套&#xff0c;我在对内部容器包括的内容做修改时&#xff0c;不产生效果&#…

apache RocketMQ远程代码执行(CVE-2023-33246)

RocketMQ是阿里巴巴在2012年开发的分布式消息中间件&#xff0c;专为万亿级超大规模的消息处理而设计&#xff0c;具有高吞吐量、低延迟、海量堆积、顺序收发等特点。它是阿里巴巴双十一购物狂欢节和众多大规模互联网业务场景的必备基础设施。 RocketMQ的NameServer、Broker、…

【计算机网络之HTTP篇】Cookie与Session的区别

目录 Cookie 原理 缺点 Session 原理 区别 Cookie cookie是浏览器在本地存储数据的一种机制。 原理 当浏览器向服务器第一次发送请求时&#xff0c;服务器会向浏览器返回一个Cookie&#xff0c;此时 cookie记录着浏览器访问服务器的用户登录状态。 后续浏览器再次访问服…

[深度学习入门案例1]基于Keras的手写数字图像识别

文章目录 一、工具与环境 二、深度学习环境的搭建 1.安装Anaconda 2.创建虚拟环境 第1步&#xff1a;打开Anaconda的命令窗口&#xff0c;即Anaconda Prompt 第2步&#xff1a;使用命令创建指定版本的python环境&#xff08;这里以py36命令环境名称举例&#xff09; 3.切换…

深度解析MethodHandle方法句柄之findspecial方法的原理

网上看过太多关于MethodHandle方法句柄的文章&#xff0c;但是基本上没有人能把其中的findspecial方法讲清楚&#xff0c;特别是findspecial的第四个参数specialCaller, 相信大家都不明白是干嘛用的&#xff0c;网上给出的水文是很多都是说&#xff1a; 执行到specialCaller的父…

kafka二

练一练 需求&#xff1a;写一个生产者&#xff0c;不断的去生产用户行为数据&#xff0c;写入到kafka的一个topic中 生产的数据格式&#xff1a; 造数据 {"guid":1,"eventId":"pageview","timestamp":1637868346789} isNew 1 {&quo…

面了一个32岁的程序员,只因这一点,一眼看穿是培训班出来的,简历都是假的.....

首先&#xff0c;我说一句&#xff1a;培训出来的&#xff0c;优秀学员大有人在&#xff0c;我不希望因为带着培训的标签而无法达到用人单位和候选人的双向匹配&#xff0c;是非常遗憾的事情。 最近&#xff0c;在网上看到这样一个留言&#xff0c;引发了程序员这个圈子不少的…

Kafka安装及架构

kafka的特点 高吞吐量、低延迟&#xff1a;kafka每秒可以处理几十万条消息&#xff0c;它的延迟最低只有几毫秒&#xff0c;每个topic可以分多个partition, 由多个consumer group 对partition进行consume操作。可扩展性&#xff1a;kafka集群支持热扩展持久性、可靠性&#xf…

机智云的离线语音识别模组,让家电变得更加智能和便捷

随着人们对智能化生活的需求不断增加&#xff0c;离线语音模组越来越受到欢迎。它可以为家庭、工作和娱乐提供更加智能和便捷的服务&#xff0c;例如通过语音指令控制家居设备、查询天气信息、播放音乐等。 “小智同学&#xff0c;打开灯光” “调到最亮” “正转一档” 人工智…

Golden Gate (GGX) ZK 预编译: 彻底改变游戏玩法,成本降低千倍

Golden Gate (GGX) 作为一种新型跨链基础设施协议&#xff0c;解决了困扰 Web3.0 Layer1 和 Layer2 的跨链通信和流动性转换难题。 其解决方案主要涉及两个核心: 1) 与协议无关的通信&#xff0c;可以实现主流标准消息的传递&#xff0c;包括 IBC、XCMP 和 LayerZero 等标准。 …

2023 华为 Datacom-HCIE 真题题库 10/12--含解析

单项选择题 1.[试题编号&#xff1a;190585] &#xff08;单选题&#xff09;华为SD-WAN解决方案中&#xff0c;当CPE位 于NAT设备后的私网时&#xff0c;特别是两个站点的CPE同时位于NAT设备后的私网时&#xff0c;CPE之 间需要使用NAT穿越技术。华为SD-WAN解决方案中使用以下…

驱动开发--根文件系统

1、单片机开发属于嵌入式开发吗&#xff1f; 广义&#xff1a;单片机开发属于嵌入式开发---&#xff08;嵌入式微处理器开发&#xff09; 一般不带mmu&#xff08;地址映射&#xff09; 狭义&#xff1a;单片机开发不属于嵌入式 ---&#xff08;Linux嵌入式开发&#xff09;一…

python数据分析学习笔记之matplotlib、numpy、pandas

为了学习机器学习&#xff0c;在此先学习以下数据分析的matplotlib&#xff0c;numpy&#xff0c;pandas&#xff0c;主要是为自己的学习做个记录&#xff0c;如有不会的可以随时查阅。希望大家可以一起学习共同进步&#xff0c;我们最终都可以说&#xff1a;功不唐捐&#xff…

刷完这套八股文,15K不能再少了...

前言 大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;得准备面试了&#xff0c;又不知道从何下手&#xff01;为了帮大家节约时间&#xff0c;特意准备了一份面试相关的资料&#xff0c;内容非常的全面&#xff0c;真的可以好好补一补&#xff0c;希望大家在都能拿…