STM32 HAL/STD库驱动HC-SR04测距

news2024/10/7 14:29:24

STM32 HAL/STD库驱动HC-SR04测距


  • ✨说明:本文不介绍HC-SR04原理。
  • 📌相关篇《STM32F103VC+DS18B20温度+hc-sr04超声波测距+I2C OLED显示》

  • 🌿HAL库实现方法比较简易,只需配置2个IO引脚:一个配置为输入,一个配置为输出即可。
    在这里插入图片描述

  • 🌿基于标准库例程,是使用定时器3,输出通道比较模式:TIM_OCMode_PWM1和输入通道捕获上升沿检测实现。

  • 🌼HC-SR04
    在这里插入图片描述

📓标准库驱动函数

  • 👉🏻使用的是正点原子资料中的标准库工程模版
  • 📝stm32f10x_HC-SR04.c
#include "stm32f10x_HC-SR04.h"

extern void EnableHCSR04PeriphClock(void);

static void initMeasureTimer() {
	RCC_ClocksTypeDef RCC_ClocksStatus;
	RCC_GetClocksFreq(&RCC_ClocksStatus);
	uint16_t prescaler = RCC_ClocksStatus.SYSCLK_Frequency / 1000000 - 1; //1 tick = 1us (1 tick = 0.165mm resolution)

	TIM_DeInit(US_TIMER);
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_Prescaler = prescaler;
	TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;
	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInit(US_TIMER, &TIM_TimeBaseInitStruct);

	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse = 15; //us
	TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OC3Init(US_TIMER, &TIM_OCInitStruct);

	TIM_ICInitTypeDef TIM_ICInitStruct;
	TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
	TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TIM_ICInitStruct.TIM_ICFilter = 0;

	TIM_PWMIConfig(US_TIMER, &TIM_ICInitStruct);
	TIM_SelectInputTrigger(US_TIMER, US_TIMER_TRIG_SOURCE);
	TIM_SelectMasterSlaveMode(US_TIMER, TIM_MasterSlaveMode_Enable);

	TIM_CtrlPWMOutputs(US_TIMER, ENABLE);

	TIM_ClearFlag(US_TIMER, TIM_FLAG_Update);
}

static void initPins() {
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = US_TRIG_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(US_TRIG_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = US_ECHO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(US_ECHO_PORT, &GPIO_InitStructure);
}

void InitHCSR04() {
	EnableHCSR04PeriphClock();
	initPins();
	initMeasureTimer();
}

int32_t HCSR04GetDistance() {
	(US_TIMER)->CNT = 0;
	TIM_Cmd(US_TIMER, ENABLE);
	while(!TIM_GetFlagStatus(US_TIMER, TIM_FLAG_Update));
	TIM_Cmd(US_TIMER, DISABLE);
	TIM_ClearFlag(US_TIMER, TIM_FLAG_Update);
	return (TIM_GetCapture2(US_TIMER)-TIM_GetCapture1(US_TIMER))*165/1000;
}

  • 📝stm32f10x_HC-SR04.h
#ifndef __STM32F10X_HC_SR04_H_
#define __STM32F10X_HC_SR04_H_

#include "stm32f10x.h"

#define US_TIMER					TIM3

#define US_TRIG_PORT				GPIOB
#define US_TRIG_PIN					GPIO_Pin_0		//TIM Ch3 (trig output)

#define US_ECHO_PORT				GPIOA
#define US_ECHO_PIN					GPIO_Pin_6		//TIM Ch1 (echo input)
#define US_TIMER_TRIG_SOURCE		TIM_TS_TI1FP1

/**
 *	How to use this driver:
 * 	1. Implement EnableHCSR04PeriphClock function and turn on clock for used peripherals
 * 		ex:
 * 		void EnableHCSR04PeriphClock() {
 *			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
 *			RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
 *			RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
 *		}
 *	2. Call InitHCSR04();
 *	3. Get distance (in mm) using HCSR04GetDistance function.
 *		Value lower than zero means no echo received (distance >3m)
 *		Measuring takes about 65ms
 *
 *	If necessary, change defines above, but be careful, US_ECHO_PIN must be tim ch1
 *	and US_TRIG_PIN must be ch3 or ch4. In case of ch4 change TIM_OC3Init into TIM_OC4Init in stm32f10x_HC-SR04.c file
 */



/**
 * Implement this function. See instruction at the top of this file.
 */
void EnableHCSR04PeriphClock(void);

/**
 * Initialization of HCSR04's peripherals
 */
void InitHCSR04(void);

/**
 * Measure distance and get value in mm. Lower than 0 means no echo signal: distance more than ~3m.
 */
int32_t HCSR04GetDistance(void);

#endif /* STM32F10X_HC_SR04_H_ */

  • 📝main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "stm32f10x_HC-SR04.h"

void EnableHCSR04PeriphClock() {
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
}


int main(void)
{
    u8 t = 0;
    delay_init();	    	 //延时函数初始化
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);	 //串口初始化
		InitHCSR04();
	
    while(1)
    {
			int32_t dist = HCSR04GetDistance();
			printf("dist:%d \n",dist);
        delay_ms(800);

    }
}

HAL库工程

  • GPIO引脚配置函数:
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

  /*Configure GPIO pin : PA1 */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PA2 */
  GPIO_InitStruct.Pin = GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}
  • main.c
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"


/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint32_t sensor_time;
uint16_t distance;


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
void delay_us(uint32_t udelay);
uint32_t Read_HCSR04(void);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */


/* USER CODE END 0 */

/**
  * @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_USART1_UART_Init();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while(1)
    {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        for(uint8_t i = 8; i > 0; i--)
        {
            sensor_time = Read_HCSR04();			// get the high time
            distance += sensor_time * 165 / 1000;
            HAL_Delay(5);
        }
        distance >>= 3;
        HAL_Delay(1000);
        printf("distance:%d \n", distance);
    }
    /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Initializes the RCC Oscillators according to the specified parameters
    * in the RCC_OscInitTypeDef structure.
    */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
    */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */
void delay_us(uint32_t udelay)
{
    uint32_t startval, tickn, delays, wait;

    startval = SysTick->VAL;
    tickn = HAL_GetTick();
    //sysc = 72000;  //SystemCoreClock / (1000U / uwTickFreq);
    delays = udelay * 72; //sysc / 1000 * udelay;
    if(delays > startval)
    {
        while(HAL_GetTick() == tickn)
        {

        }
        wait = 72000 + startval - delays;
        while(wait < SysTick->VAL)
        {

        }
    }
    else
    {
        wait = startval - delays;
        while(wait < SysTick->VAL && HAL_GetTick() == tickn)
        {

        }
    }
}
uint32_t Read_HCSR04(void)
{
    uint32_t local_time = 0;

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);		// pull the trig pin high
    delay_us(10);										// wait for 10 us
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);	// pull the trig pin low

    // wait for the echo pin to go high

    while(!(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2)));

    while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2))				// while the pin is high
    {
        local_time++;										// increment local time
        delay_us(1);									// every 1 us
    }

    return local_time * 2;
}
/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while(1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

在这里插入图片描述

📓工程源码

  • 🌿标准库工程
链接:https://pan.baidu.com/s/1x6Z7IQ_JHMfXKE3z5zFVFQ 
提取码:25q4
  • 🌿HAL工程
链接:https://pan.baidu.com/s/12Lzn7WAtL7vbaWgupCI8jQ 
提取码:no8c

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

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

相关文章

【正点原子STM32连载】第六十四章 UCOSII实验2-信号量和邮箱摘自【正点原子】STM32F103 战舰开发指南V1.2

1&#xff09;实验平台&#xff1a;正点原子stm32f103战舰开发板V4 2&#xff09;平台购买地址&#xff1a;https://detail.tmall.com/item.htm?id609294757420 3&#xff09;全套实验源码手册视频下载地址&#xff1a; http://www.openedv.com/thread-340252-1-1.html# 第六…

【C++】多线程交替打印奇偶数

目录 版本1 双信号量版 版本二 单信号量版 版本三 信号量版 共享资源是100个数字&#xff08;一个计数器的 由两个进程争抢完成&#xff09; 首先访问临界资源&#xff08;对计数器操作&#xff09;是肯定的要加锁的&#xff0c;交替打印肯定要用条件变量来互相唤醒 互相锁死…

计及需求侧响应日前—日内两阶段鲁棒备用优化(matlab代码)

目录 1 主要内容 日前计划模型 日内调整模型 不确定集建模 2 部分代码 3 程序结果 1 主要内容 该程序复现文章《计及需求侧响应日前—日内两阶段鲁棒备用优化》&#xff0c;以6节点系统为例&#xff0c;综合考虑风电出力不确定性与电力设备 N-k强迫停运&#xff0c;增强电…

创建型模式 - 原型模式

概述 用一个已经创建的实例作为原型&#xff0c;通过复制该原型对象来创建一个和原型对象相同的新对象。 结构 原型模式包含如下角色&#xff1a; 抽象原型类&#xff1a;规定了具体原型对象必须实现的的 clone() 方法。 具体原型类&#xff1a;实现抽象原型类的 clone() 方…

如何用3D格式转换工具HOOPS Exchange读取颜色和材料信息?

作为应用程序开发人员&#xff0c;非常希望导入部件的图形表示与它们在创作软件中的外观尽可能接近。外观可以在每个B-Rep面的基础上指定&#xff0c;而且&#xff0c;通过装配层次结构的特定路径可以在视觉外观上赋予父/子覆盖。HOOPS ExchangeHOOPS Exchange可捕获有关来自各…

创建型模式 - 建造者模式

概述 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 分离了部件的构造(由Builder来负责)和装配(由Director负责)。 从而可以构造出复杂的对象。这个模式适用于&#xff1a;某个对象的构建过程复杂的情况。 由于实现了构建和装配的解耦。…

虾皮、Lazada爆款打造计划,自养号测评补单技术成重要的运营手段【无标题】

在如今的电商平台中&#xff0c;虾皮和lazada是东南亚地区主要的电商平台&#xff0c;平台广告是它的主要利润来源之一。然而&#xff0c;随着大量卖家涌入东南亚市场&#xff0c;商家之间的竞争也日益激烈&#xff0c;高额的广告投入并没有带来预期的效果。为了提高产品在平台…

【26】SCI易中期刊推荐——计算机人工智能(中科院4区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

【视频+文字讲解】C++那些事之彻底搞懂STL HashTable

C那些事之彻底搞懂STL HashTable C那些事之彻底搞懂STL HashTable1.常用容器 1.1 接口层2.HashTable原理 2.1 _Hash_node结构2.2 hashtable实现2.3 如何确定桶&#xff1f;2.4 如何确定在桶中的位置&#xff1f;3.Rehash 3.1 计算新桶大小3.2 判断是否需要rehash3.3 rehash 最近…

Github实时数据分析与可视化训练营火热开启!免费领取5000元云上资源

此次训练营内容基于GitHub Archive公开数据集&#xff0c;通过DataWorks将GitHub中的项目、行为等20多种事件类型数据实时采集至Hologres进行分析&#xff0c;同时使用DataV内置模板&#xff0c;快速搭建实时可视化数据大屏&#xff0c;从开发者、项目、编程语言等多个维度了解…

vscode 使用ssh进行远程开发 (remote-ssh)

介绍 visual studio code remote - ssh 可以通过ssh连接远程主机、虚拟机&#xff0c;打开远程文件夹&#xff0c;并利用vscode 的插件优势进行远程开发、调试等。 步骤 一、配置环境 因为remote-ssh 的ssh连接是基于openssh实现的&#xff0c;以及后续我们需要使用生成ss…

手把手教你搭建SpringCloud项目(七)集成Consul服务注册中心

一、了解Consul 这篇文章学习另外一个服务注册中心Consul&#xff0c;那什么是Consul&#xff1f; Consul是一个服务网格&#xff08;微服务间的 TCP/IP&#xff0c;负责服务之间的网络调用、限流、熔断和监控&#xff09;解决方案&#xff0c;它是一个一个分布式的&#xff…

[PCIE体系结构导读]PCIE总结(二)

PMCR&#xff08;Power Management Capabilities Register&#xff09;和PMCSR&#xff08;Power Management Control and Status Register) PMCR寄存器由16位组成&#xff0c;其中所有位和字段都是只读的。该寄存器的主要木得是记录当前PCIe设备的物理属性&#xff0c;系统软件…

vue2的 element 表格单元格合并

<template><div><el-table show-summary :summary-method"getSummaries" :span-method"objectSpanMethod" :data"tableData" row-key"id" ref"tableDom" border><el-table-column label"序号&quo…

10-2. 数组 Array 的实例方法

本文并没有写出数组的全部使用方法&#xff0c;想看全的可以看一下这个 Array - JavaScript | MDN 目录 1 常用内置方法 1.1 合并数组 concat() 1.2 复制元素覆盖到指定位置 copyWithin() 1.3 返回其他变量的数组形式 Array.from() 1.3.1 基本使用 1.3.2 将伪数组…

Hive Metastore、Hive server和Hive thrift服务

Hive Metastore Hive Metastore是Hive的核心元数据管理服务,它提供了元数据的持久化存储和访问控制的能力,使得 Hive 成为一个强大的数据仓库和分析平台,适用于处理大数据和进行复杂的数据查询与分析任务。 Apache Hive是一个建立在 Apache Hadoop 上的数据仓库和分析工具…

java多线程之FutureTask、Future、CompletableFuture

前面已经在多线程创建的时候有提到Future和FutureTask的简单用法&#xff0c;这里详细介绍下FutureTask以及CompletableFuture 一、FutureTask 1、FutureTask简介 FutureTask除了实现Future接口外&#xff0c;还实现了Runnable接口。因此&#xff0c;FutureTask可以交给 Exe…

回溯法实现N皇后问题

题1&#xff1a;&#xff08;需打印矩阵&#xff09; 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#…

命名空间,缺省参数与函数重载

目录 一&#xff0c;命名空间 1.何为命名空间 2.命名空间的使用 ​编辑 4.::作用域限定符 3.命名空间的展开 全局展开&#xff1a; 局部展开&#xff1a; 4.嵌套命名空间 二&#xff0c;缺省参数与函数重载 1.什么是缺省参数 2.什么是函数重载 3.两者的冲突 一&…

内部数据泄露:保护数据安全的挑战与解决方案

导语&#xff1a; 在当今数字化时代&#xff0c;数据是企业的核心资产之一。然而&#xff0c;随着科技的快速发展和信息的日益增长&#xff0c;数据安全问题也日益突出。其中&#xff0c;内部数据泄露成为企业所面临的重大挑战之一。本文将探讨内部数据泄露的危害&#xff0c;…