基于STM32 HAL库实现HC-SR04超声波测距模块

文章目录

  • 一·、HC-SR04模块介绍
  • 二、创建工程
  • 1.选择芯片
  • 2.配置RCC、SY![在这里插入图片描述](https://i3.wp.com/img-blog.csdnimg.cn/direct/9d2a5b883f0e409eabb804e6da861277.png)
  • 3.配置串口1
  • 4.配置定时器
  • 5.配置GPIO
  • 三、Keil代码
  • 1.勾选Use MicroLIB
  • 2.创建SR04.c和SR04.h文件
  • 3.其他代码
  • 四、效果
  • 五、参考资料:
  • 一·、HC-SR04模块介绍

    ​ 超声波是振动频率高于20kHz的机械波。它具有频率高、波长短、绕射现象小、方向性好、能够成为射线而定向传播等特点。HC-SRO4是一款尺寸完全兼容老版本,增加UART和IIC功能的开放式超声波测距模块,默认条件下,软件与硬件完全兼容老版本HC-SRO4;可以通过电阻设置成UART或IIC模式。2CM盲区,4.5M典型最远测距,2.2mA作电流。采用升级解调芯片RCWL-9206,带UART与IIC功能MCU:使其外围更加简洁,工作电压更宽(3-5.5V),接口功能更多。

  • 模块参数:
    ①专业解调测距芯片RCWL-9206
    ②支持GPIO,UART与IIC三种模式接口
    ③2.2mA工作电流
    ④2cm最小盲区
    ⑤2cm-450cm的超宽测量范围
    ⑥工作温度:-10°C-70°c
    ⑦3V-5.5V宽电压供电

  • 注:0~40℃声速误差7%左右,实际应用时需要考虑温度影响

  • 实验步骤

    1.配置GPIO引脚结构体(Trig,Echo)
    2.配置定时器结构体
    3.配置定时器中断结构体
    4.开启时钟(定时器、GPIO)
    5.Trig引脚输出高电平(10us以上),然后关闭
    6.等待Echo引脚输出高电平开始,定时器打开->开启计数器计数
    7.等待Echo引脚输出高电平结束,定时器关闭->停止计数器计数


  • 二、创建工程

    1.选择芯片

    打开STM32CubuMax,新建一个项目,选择芯片

    2.配置RCC、SY

    S、时钟树

    rcc

    sys

    时钟树


    3.配置串口1

    4.配置定时器

    5.配置GPIO

    完成后生成keil工程


    三、Keil代码

    1.勾选Use MicroLIB

    2.创建SR04.c和SR04.h文件

    SR04.c

    #include "SR04.h"
     
    float distant;      //测量距离
    uint32_t measure_Buf[3] = {0};   //存放定时器计数值的数组
    uint8_t  measure_Cnt = 0;    //状态标志位
    uint32_t high_time;   //超声波模块返回的高电平时间
     
     
    //===============================================读取距离
    void SR04_GetData(void)
    {
    switch (measure_Cnt){
    	case 0:
             TRIG_H;
             delay_us(30);
             TRIG_L;
        
    		measure_Cnt++;
    		__HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING);
    		HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);	//启动输入捕获       或者: __HAL_TIM_ENABLE(&htim5);                                                                                    		
            break;
    	case 3:
    		high_time = measure_Buf[1]- measure_Buf[0];    //高电平时间
             printf("\r\n----高电平时间-%d-us----\r\n",high_time);							
    		distant=(high_time*0.034)/2;  //单位cm
            printf("\r\n-检测距离为-%.2f-cm-\r\n",distant);          
    		measure_Cnt = 0;  //清空标志位
            TIM2->CNT=0;     //清空计时器计数
    		break;
    				
    	}
    }
     
     
    //===============================================us延时函数
        void delay_us(uint32_t us)//主频72M
    {
        uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
        while (delay--)
    	{
    		;
    	}
    }
     
    //===============================================中断回调函数
    void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//
    {
    	
    	if(TIM2 == htim->Instance)// 判断触发的中断的定时器为TIM2
    	{
    		switch(measure_Cnt){
    			case 1:
    				measure_Buf[0] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
    				__HAL_TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_FALLING);  //设置为下降沿捕获
    				measure_Cnt++;                                            
    				break;              
    			case 2:
    				measure_Buf[1] = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//获取当前的捕获值.
    				HAL_TIM_IC_Stop_IT(&htim2,TIM_CHANNEL_1); //停止捕获   或者: __HAL_TIM_DISABLE(&htim5);
    				measure_Cnt++;  
                             
    		}
    	
    	}
    	
    }
    

    SR04.h

    #ifndef __SR04_H
    #define __SR04_H
    #include "main.h"
    #include "tim.h"
    #include "stdio.h"
     
    #define TRIG_H  HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_SET)
    #define TRIG_L  HAL_GPIO_WritePin(Trig_GPIO_Port,Trig_Pin,GPIO_PIN_RESET)
     
    void delay_us(uint32_t us);
    void SR04_GetData(void);
     
    #endif
    

    添加进工程

    3.其他代码

    usrat.c中添加

    /* USER CODE BEGIN 0 */
    #include "stdio.h"
    /* USER CODE END 0 */
     
     
     
    /* USER CODE BEGIN 1 */
    /*********************************************************
    *
    *重定义 fputc 函数
    *
    *********************************************************/
    int fputc(int ch,FILE *f)
    {
    	HAL_UART_Transmit (&huart1 ,(uint8_t *)&ch,1,HAL_MAX_DELAY );
    	return ch;
    }
    /* USER CODE END 1 */
    

    main函数

    /* USER CODE BEGIN Header */
    /**
      ******************************************************************************
      * @file           : main.c
      * @brief          : Main program body
      ******************************************************************************
      * @attention
      *
      * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
      * All rights reserved.</center></h2>
      *
      * This software component is licensed by ST under BSD 3-Clause license,
      * the "License"; You may not use this file except in compliance with the
      * License. You may obtain a copy of the License at:
      *                        opensource.org/licenses/BSD-3-Clause
      *
      ******************************************************************************
      */
    /* USER CODE END Header */
    /* Includes ------------------------------------------------------------------*/
    #include "main.h"
    #include "tim.h"
    #include "usart.h"
    #include "gpio.h"
    
    /* Private includes ----------------------------------------------------------*/
    /* USER CODE BEGIN Includes */
    #include "SR04.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 */
    
    /* USER CODE END PV */
    
    /* Private function prototypes -----------------------------------------------*/
    void SystemClock_Config(void);
    /* USER CODE BEGIN PFP */
    
    /* 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_TIM2_Init();
      MX_USART1_UART_Init();
      /* USER CODE BEGIN 2 */
    
      /* USER CODE END 2 */
    
      /* Infinite loop */
      /* USER CODE BEGIN WHILE */
      while (1)
      {
          
          SR04_GetData(  );
          HAL_Delay(300);
          
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
      }
      /* 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 */
    
    /* 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 */
    
    /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
    

    四、效果

    HC-SR04模块接线

    VCC接5V
    GND接地
    TRIG接A1
    ECHO接A0

    五、参考资料:

    [1]https://blog.csdn.net/qq_52215423/article/details/131034232?ops_request_misc=&request_id=&biz_id=102&utm_term=stm32%E8%B6%85%E5%A3%B0%E6%B3%A2%E6%B5%8B%E8%B7%9D&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-131034232.142

    [2]https://blog.csdn.net/lwb450921/article/details/123670786?spm=1001.2014.3001.5502

    [3]https://blog.csdn.net/weixin_72921448/article/details/127586521?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171721873616800186519673%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=171721873616800186519673&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-4-127586521-null-null.142

    作者:被迫注册的账号

    物联沃分享整理
    物联沃-IOTWORD物联网 » 基于STM32 HAL库实现HC-SR04超声波测距模块

    发表回复