1.硬件原理图
2.传感器参数表
电气参数 | HC-SR04 超声波模块 |
---|---|
工作电压 | DC 5 V |
工作电流 | 15mA |
工作频率 | 40kHz |
最远射程 | 4m |
最近射程 | 2cm |
测量角度 | 15 度 |
输入触发信号 | 10uS 的 TTL 脉冲 |
输出回响信号 | 输出 TTL 电平信号,与射程成比例 |
规格尺寸 | 452015mm |
3.引脚功能表
HC-SR04实物图
HC-SR04功能引脚表
引脚 | 说明 |
---|---|
VCC | 接5V |
GND | 地线 |
TRIG | 触发控制信号输入 |
ECHO | 回响信号输出 |
4.工作原理
(1)给超声波模块接入电源和地
(2)给脉冲触发引脚(trig)输入一个长为20us的高电平方波
(3)输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚echo端的电平会由0变为1;(此时应该启动定时器计时)
(4)当超声波返回被模块接收到时,回波引脚端的电平会由1变为0;(此时应该停止定时器计数),定时器记下的这个时间即为超声波由发射到返回的总时长
(5)根据声音在空气中的速度为344米/秒,即可计算出所测的距离。
超声波时序图
- 以上时序图表明你只需要提供一个 10uS 以上脉冲触发信号,该模块内部将发出 8个 40kHz 周期电平并检测回波。一旦检测到有回波信号则输出回响信号。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离。
- 建议测量周期为 60ms 以上,以防止发射信号对回响信号的影响。
- 公式: uS/58=厘米 uS/148=英寸; 距离= 高电平时间*声速(340M/S)/2
5.流程图
硬件运行流程图
时间的输入捕获流程图
6.注意事项
(1)公式中为什么要除以58?
-
我们作一下单位换算,34,300除以1,000,000厘米/微秒。 即为:0.0343厘米/微秒
-
再换一个角度,1/(0.0343 厘米/微秒) 即:29.15 微秒/厘米。1厘米就29.15微秒。
-
但是发送后到接收到回波,声音走过的是2倍的距离。所以实际距离就是1厘米,对应58.3微秒。
(2)高电平的测量
- 我们使用通用定时器的输入捕获来测量高电平时间,所以使用的过程中要注意结果是否溢出
(3)消抖
- 由于超声波测量一次的时间很短,测量一次很有可能出错,所以我们可以多测几次求平均值来进行消抖。
(4)使用的注意事项
- 此模块不宜带电连接,若要带电连接,则先让模块的 GND 端先连接,否则会影响模块的正常工作。
- 测距时,被测物体的面积不少于 0.5 平方米且平面尽量要求平整,否则影响测量的结果
7.基于stm32-mini的代码模块
Ultrasonic.h模块
#ifndef __ULTRASONIC_H
#define __ULTRASONIC_H
#include "sys.h"
#define trig PBout(2) //超声波输出
#define echo PBin(3) //超声波输入
void TIM3_Int_Init(u16 arr,u16 psc); //计数器使能
void Ultrasonic_Init(void); //超声波初始化
void open_Ultrasonic(void); //打开超声波
void close_Ultrasonic(void); //关闭超声波
int accept_Ultrasonic(void); //计算距离
int get_val(void); //消抖
#endif
Ultrasonic.c模块
#include "Ultrasonic.h"
#include "delay.h"
#include "usart.h"
#include "sys.h"
int flag=0;
void TIM3_IRQHandler(void){
if(TIM3->SR&0X0001)
{
flag++;
}
TIM3->SR&=~(1<<0);
}
void TIM3_Int_Init(u16 arr,u16 psc) //计数器使能
{
RCC->APB1ENR|=1<<1; //TIM3时钟使能
TIM3->ARR=arr; //设定计数器自动重装值
TIM3->PSC=psc; //预分频器设置
TIM3->DIER |= 1<<0;
MY_NVIC_Init(1,3,TIM3_IRQn,2);
}
void Ultrasonic_Init(void){ //超声波初始化
TIM3_Int_Init(5000,71);
RCC->APB2ENR|=1<<3; //时钟使能
GPIOB->CRL&=0XFFFFF0FF; //pb2 trig推挽输出
GPIOB->CRL|=0X00000300;
GPIOB->ODR&=~(1<<2);
GPIOB->CRL&=0XFFFF0FFF; //pb3 echo浮空输入
GPIOB->CRL|=0X00004000;
}
void open_Ultrasonic(void){ //发射超声波
trig=1;
delay_us(20);
trig=0;
flag=0;
}
void close_Ultrasonic(void){ //关闭超声波
TIM3->CR1&=0<<0; //关闭定时器1
TIM3->CNT=0;
}
int accept_Ultrasonic(void){ //计算距离
int val=0;
open_Ultrasonic();
while(echo==0){ }
TIM3->CR1|=0x01; //使能定时器1
TIM3->CNT=0;
while(echo==1){ }
val=(flag*5000+TIM3->CNT)*0.017;
close_Ultrasonic();
return val;
}
int get_val(void){ //消抖
int i;
int val,sum=0;
for(i=0;i<10;i++){
sum += accept_Ultrasonic();
}
val=sum*0.1;
return val;
}