stm32f1驱动HC-SR04超声波测距模块

这段时间算是比较系统的学习了一点stm32相关的东西,驱动超声波测距模块这个简单的小任务综合了定时器,中断,串口三个知识点,拿来练手还是挺不错的

首先先介绍一下HC-SR04模块:stm32f1驱动HC-SR04超声波测距模块_第1张图片

stm32f1驱动HC-SR04超声波测距模块_第2张图片 

以上是该模块原理的简介,就我个人体验而言,实际使用中,HC-SR04的稳定性可以说是很不错的, 测距的精度与范围基本上可以满足大部分小型项目的需求,最关键的一点,它的驱动非常的简单(虽然这并不影响菜鸡的我搞了3天才弄成)

那么简单说一下驱动的注意事项,由于模块所需要的供电是5V,而板子能直接供的电压只有3V3,因此我拿了个充电宝来当电源,当然,如果有锂电池啥的就更好了

其次,引脚设置时不要弄反,TRIG引脚作为输出,而ECHO引脚作为输入

我所实现的功能是超声波模块用来读取距离数据,用串口将数据打印到屏幕上

那么废话完毕,开始上图上代码:

cubemx内部的设置如图所示

这是引脚的设置,我启用了定时器TIM2用来记时,以及它的2通道用来做输入捕获,顺便启用了一下串口stm32f1驱动HC-SR04超声波测距模块_第3张图片

中断的设置如图所示,使能了定时器中断和串口中断(其实串口中断不需要使能,我只是随手点了而已) 

stm32f1驱动HC-SR04超声波测距模块_第4张图片

定时器2的设置如图所示,分频设为80,重载值设为10000 ,捕获触发设为下降沿

stm32f1驱动HC-SR04超声波测距模块_第5张图片 

 然后就可以愉快的生成工程文件了

关于具体的测距程序,只能说一切都要跟着原理走,我就很想不开的脱离原理写了一天程序,然后发现自己写得东西一点鬼用没有,于是重新上网去各种借鉴,终于搞清楚自己是哪里出了问题,希望大家以后驱动别的模块时

一    定    要    先     看     懂     原     理!

不然会出各种各样神奇的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-a1CNT;
	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 
/* 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)
#endif
	 
PUTCHAR_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超声波测距模块_第6张图片

你可能感兴趣的:(stm32f1驱动HC-SR04超声波测距模块)