基于stm32的超声波测距


模块选择:
stm32f103c8芯片
HC-SR04超声波测距模块

一、HC-SR04超声波测距模块说明

1、产品特点

HC-SR04 超声波测距模块可提供 2cm-400cm 的非接触式距离感测功能,测距精度可达高到 3mm;模块包括超声波发射器、接收器与控制电路。

基本工作原理:
(1)采用 IO 口 TRIG 触发测距,给最少 10us 的高电平信呈。
(2)模块自动发送 8 个 40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过 IO 口 ECHO 输出一个高电平,高电平持续的时间就是超声
波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2。

2、电气参数

在这里插入图片描述

3、HC-SR04超声波测距模块

在这里插入图片描述
VCC 供 5V电源,GND 为地线,TRIG 触 发 控 制 信 号 输入,ECHO 回响信号输出等四个接口端。

4、超声波时序图

在这里插入图片描述
以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将
发出 8 个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。
回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号
时间间隔可以计算得到距离。公式:uS/58=厘米或者 uS/148=英寸;或是:距离= 高电平时间*声速(340M/S)/2;建议测量周期为 60ms 以上,以防止发射信号对
回响信号的影响。

注:
1、此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。
2、测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果

二、 CUBEMX配置

配置rcc
在这里插入图片描述

设置时钟为72
在这里插入图片描述

配置串口
在这里插入图片描述
在这里插入图片描述

定时器配置
为了不在重复配置,这里就直接配置成输入捕获模式,开启溢出中断与捕获中断,方法一只需要开启定时器即可。利用TIM1_CH4是因为Echo与TIM1_CH4共用引脚。
在这里插入图片描述
在这里插入图片描述

命名引脚
在这里插入图片描述
在这里插入图片描述

生成项目
在这里插入图片描述
在这里插入图片描述

三、keil配置代码

重定向printf函数,打开 usart.c,在 /* USER CODE BEGIN 0 / 和 / USER CODE END 0 */加入以下代码:

 
#include <stdio.h>
 
#ifdef __GNUC__
	/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
	set to 'Yes') calls __io_putchar() */
	#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
	#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
 
#endif /* __GNUC__ */

在这里插入图片描述

在 /* USER CODE BEGIN 1 / 和 / USER CODE END 1 */ 之间加入以下代码:

 
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
    
    
	/* Place your implementation of fputc here */
	/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
	HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
	return ch;
}

在这里插入图片描述

在tim.c中编写毫秒延时函数

/* USER CODE BEGIN 1 */
 
//使用TIM1来做us级延时函数,此函数为1us
void TIM1_Delay_us(uint16_t n_us)
{
    
    
	/* 使能定时器1计数 */
	__HAL_TIM_ENABLE(&htim1);
	
	__HAL_TIM_SetCounter(&htim1, 0);//htim1
	
	while(__HAL_TIM_GetCounter(&htim1) < ((1 * n_us)-1) );
	
    /* 失能定时器1计数 */
	__HAL_TIM_DISABLE(&htim1);
}
 
 
/* USER CODE END 1 */

在这里插入图片描述

在main.c中编写超声波开始函数

void Start()
{
    
    
	HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_SET);//拉高
		
	TIM1_Delay_us(20);
		
	HAL_GPIO_WritePin(Trig_GPIO_Port, Trig_Pin, GPIO_PIN_RESET);//拉低
}

在这里插入图片描述

在主函数外定义变量

int Cnt;//计数值
float Distance;//距离

在这里插入图片描述
重写主函数

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_TIM1_Init();
  /* USER CODE BEGIN 2 */
	
	HAL_TIM_Base_Start(&htim1);//开启定时器
	
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
 
  while (1{
    
    
		/* 定时器1,通道1,模式随便,主要用于计数,没有使用边沿捕获 */	
		Start();//开启超声波模块
		
		HAL_TIM_Base_Start(&htim1);//开启定时器
 
		//对超声波输入端口操作
		while( HAL_GPIO_ReadPin (Echo_GPIO_Port ,Echo_Pin) == GPIO_PIN_RESET);//等待输入电平拉高
		
		__HAL_TIM_SetCounter(&htim1,0);
		
		//对超声波输入端口操作
		while( HAL_GPIO_ReadPin (Echo_GPIO_Port ,Echo_Pin) == GPIO_PIN_SET);//等待输入电平变低
		
		Cnt = __HAL_TIM_GetCounter(&htim1);
		
		HAL_TIM_Base_Stop(&htim1);
		
		Distance = Cnt*340/2*0.000001*100 ;
		
		printf("Distance=%.1fcm\n",Distance);
		
		HAL_Delay(500);
		
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

硬件连接
trig——PA2;
echo——PA11;
vcc——3.3v;
GND——GND;

烧录运行结果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_53573350/article/details/130928956