11.11大促主会场
新人页面
精选商品
首月0月租体验,领12个月京东PLUS
自营热卖

(STM32CubeMX)超声波模块测距传感器学习笔记

冷月寒光 6月前   阅读数 100 0

一、简介

1.概念

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

2.电路连接

在这里插入图片描述

3.工作原理

在这里插入图片描述
以上时序图表明你只需要提供一个10uS 以上脉冲触发信号,该模块内部将发出8个40kHz周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。
公式:距离=高电平时间*声速(340M/S)/2;
建议测量周期为60ms 以上,以防止发射信号对回响信号的影响。
注:
1.此模块不宜带电连接,若要带电连接,则先让模块的GND端先连接,否则会影响模块的正常工作。
2.测距时,被测物体的面积不少于0.5平方米且平面尽量要求平整,否则影响测量的结果
3.VCC3.3V高电平可能无法使模块工作,建议使用5V

二、STM32CubeMX配置步骤

首先创建一个空文件夹,用来存放项目。项目的文件路径中不能含有中文,项目名称也尽量使用英文

1.芯片选择

1.打开STM32CubeMX软件,选择File→New Project,在Part Number中输入自己的单片机型号,之后点击Start Project。我选择的是STM32F103C8T6,可根据自己的需求进行选择。
在这里插入图片描述

2.引脚配置

我使用的是J-Link下载器,因此除了配置超声波模块的引脚外,还需要配置下载代码所需的串口。
a.串口配置
根据查询芯片手册,可知串口1的引脚。
在这里插入图片描述

点击PA9,选择USART1_RX
点击PA10,选择USART1_TX
在这里插入图片描述
引脚为黄色,点击Connectivity→USART1,选择模式为异步通信,引脚变为正常绿色。
在这里插入图片描述
b.超声波模块引脚配置
在配置超声波模块引脚时,只需配置它的发射和接收引脚,一般不使用且没有特殊功能的引脚都可以进行配置,我使用的是PA6和PA7。
将PA6设置为输入模式,作为回响信号Echo
在这里插入图片描述
将PA7设置为输出模式,作为触发信号Tring
在这里插入图片描述
PA6和PA7的具体配置如下图
在这里插入图片描述

3.时钟配置

a.系统时钟配置
点击Clock Configuration,进入时钟配置,此时需要查看芯片具体手册,可知工作频率为72MHz
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
b.精准延时定时器配置
点击TIM1也可根据需要选择不同的定时器,定时事件为1us
在这里插入图片描述
在这里插入图片描述
TIM1挂载在APB2上,通过时钟查询最高为72MHz

分频计算:
在这里插入图片描述
因此Prescaler (PsC-16 bits value)=72-1
在这里插入图片描述
启用NVIC
在这里插入图片描述

4.其他配置

在这里插入图片描述
在这里插入图片描述
做完以上步骤就可以生成代码了,之后打开项目。
在这里插入图片描述

三、keil5代码

1.串口重定向

在以下位置编写重定向函数
在这里插入图片描述

//printf函数重定向
int fputc(int ch,FILE *f)
{
     
    uint8_t temp[1]={
     ch};
    HAL_UART_Transmit(&huart1,temp,1,2);
	return 0;
}

注意头文件的引用

/* USER CODE BEGIN 0 */
#include "stdio.h"
#include <string.h>
/* USER CODE END 0 */

2.超声波模块编写

在main.c中/* USER CODE BEGIN 4 /与/ USER CODE END 4 */间编写超声波监测代码及精准延时
a.超声波监测

//获取超声波模块的检测距离
uint32_t csb_get_distance(void)
{
     
    uint32_t CSB_value = 0 ;
	//给发射引脚一个高电平
	HAL_GPIO_WritePin(CSB_Trig_GPIO_Port, CSB_Trig_Pin, GPIO_PIN_SET);
	//延时10us以上
	TIM1_Delay_us(20);
	//给发射引脚一个低电平
	HAL_GPIO_WritePin(CSB_Trig_GPIO_Port, CSB_Trig_Pin, GPIO_PIN_RESET);
	//等待接收引脚变成高电平
	while( HAL_GPIO_ReadPin(CSB_Echo_GPIO_Port,CSB_Echo_Pin) == 0);
	//设置定时器初始值为0
	__HAL_TIM_SetCounter(&htim1, 0);
	//开始计时
	__HAL_TIM_ENABLE(&htim1);
	//接收完全后不再为高电平,即当接收引脚变成低电平后,停止计时,获取计数时间
    while( HAL_GPIO_ReadPin(CSB_Echo_GPIO_Port,CSB_Echo_Pin) == 1);  
	//获取定时器的计数值,赋值操作 a = b;
	CSB_value = __HAL_TIM_GetCounter(&htim1);
	//停止计时
	__HAL_TIM_DISABLE(&htim1);
	//已知高电平总时间,即可利用公式( 测试距离= (高电平时间*声速(340M/S))/2 ),计算超声波模块距离障碍物的单程距离;
	//如果需要返回 毫米级别距离,公式为( 测试距离= (高电平时间*声速(340M/1000mS))/2 )
	return ( CSB_value*340/1000/2);
}

b.精准延时1us

//使用TIM1来做us级延时函数,此函数为1us
void TIM1_Delay_us(uint16_t n_us)
{
     
	__HAL_TIM_SetCounter(&htim1, 0);//htim1

	/* 开启定时器1计数 */
	__HAL_TIM_ENABLE(&htim1);

	//获取定时器的计数值!!!再判断计数值,但是计数值不得大于定时器配置的重装载值。\
	假如:定时器设定的重装载值为65536-1, 比较值需小于重装载值,即(计数1* n_us)-1) 小于(65536-1)\
																	  即传进来的参数n_us需要小于65536-1while(__HAL_TIM_GetCounter(&htim1) < ((1 * n_us)-1) );
	/* Disable the Peripheral */
	__HAL_TIM_DISABLE(&htim1);
}

在主函数/* USER CODE BEGIN 3 /与/ USER CODE END 3 */间编写读取超声波监测距离。

  /* USER CODE BEGIN 2 */
  int distance;
  /* USER CODE END 2 */
 distance = csb_get_distance();	
  printf("超声波检测到的距离为:%dcm\n",	distance/10);

之后进行编译下载即可。
结果
在这里插入图片描述
项目工程及源代码🔗


注意:本文归作者所有,未经作者允许,不得转载

全部评论: 0

    我有话说: