学习笔记13-HC-SR04超声波模块

一、基本介绍

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

电气参数

电路图
两个压电陶瓷超声传感器,一个用于发出超声波信号,一个用于接收反射回来的超声波信号。由于发出信号和接收信号都比较微弱,所以需要通过外围信号放大器提高发出信号的功率,和将反射回来信号进行放大,以能更稳定地将信号传输给单片机。
在这里插入图片描述

二、工作原理

  1. 采用IO口TRIG触发测距,给最少10us的高电平信呈;
  2. 模块自动发送8个40khz的方波,自动检测是否有信号返回;
  3. 有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。

测试距离=(高电平时间*声速(340M/S))/2;
在这里插入图片描述
时序图
在这里插入图片描述

一点小Tips
1、Echo引脚0—>1启动定时器计时;1—>0结束定时器计时。
2、公式:uS/58=厘米或者uS/148=英寸;或距离=高电平时间*声速(340M/S)/2;
3、建议测量周期为60ms 以上,以防止发射信号对回响信号的影响。

三、代码段

hcsr04.c

#include "hcsr04.h"

extern char value[];    //存储转换后的值
extern int Length;
int Val=0;

void hcsr04Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB2PeriphClockCmd(HCSR04_CLK,ENABLE);
	RCC_APB1PeriphClockCmd(HCSR04_TIM_CLK,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=HCSR04_TRIG;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;  		//推挽输出
	GPIO_Init(HCSR04_PORT,&GPIO_InitStructure);
	GPIO_ResetBits(HCSR04_PORT, HCSR04_TRIG);    
	
	GPIO_InitStructure.GPIO_Pin=HCSR04_ECHO;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;	//浮空输入
	GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  

	TIM_DeInit(TIM4);
	TIM_TimeBaseStructure.TIM_Period = 999; 
	TIM_TimeBaseStructure.TIM_Prescaler =71; 
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //初始化 

	TIM_ClearFlag(TIM4, TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断
 	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);    //打开定时器更新中断
	TIM_Cmd(TIM4,DISABLE);
}


float UltraSonic_valuetance(void)   //测量超声波距离
{
	float length=0;
	GPIO_SetBits(HCSR04_PORT, HCSR04_TRIG);   //拉高电平信号
	DelayUs(20);   //高电平至少10uS
	GPIO_ResetBits(HCSR04_PORT, HCSR04_TRIG); //拉低电平信号    
	/*等待回响信号*/
	while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==0);  //接收到信号ECHO为高电平
	TIM_Cmd(TIM4,ENABLE);        //使能TIM4定时器
	while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==1);  //直到回响信号消失
	TIM_Cmd(TIM4,DISABLE);       //失能TIM4定时器
	length=TIM_GetCounter(TIM4)/58;
	if(length<=0){
	length=0;
	}
	TIM_SetCounter(TIM4,0);  //取出TIM4的counter寄存器里的值
	DelayMs(200);  
	return length;
}

hcsr04.h

#ifndef __HCSR04_H
#define	__HCSR04_H

#include "stm32f10x.h"
#include "delay.h"

#define HCSR04_PORT    		 GPIOB
#define HCSR04_CLK    	   RCC_APB2Periph_GPIOB
#define HCSR04_TIM_CLK     RCC_APB1Periph_TIM4
#define HCSR04_TRIG   	   GPIO_Pin_7
#define HCSR04_ECHO        GPIO_Pin_6

void hcsr04Init(void);
float UltraSonic_valuetance(void);

#endif /*__HCSR04_H */

还有TIM4的中断

void TIM4_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
	{
		TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
		
	}
}

余震处理

以上代码确实可以测到距离,但是总有时数据会跟实际偏差很大。这是因为超声波测量一次的时间很短,测量一次有可能出错。

关于余震原因

  1. 探头的余震。发射头发射完还会震一会,这种震动信号也会向外传播。如果发射完立刻切换为接收状态,检测会被这余震波干扰到。
  2. 壳体的余震。发射头发射完壳体余震会传导到接收头,造成检测时的干扰。
  3. 电路串扰。超声波发射时的瞬间电流很大,会对电源有一定影响,并干扰接收电路。

我们稍微修改一下代码,通过多测几次求平均值来进行消抖。

float UltraSonic_valuetance(void)   //测量超声波距离
{
		float length=0,sum=0;
		int i=0;uint16_t time;
		while(i!=5){		
		GPIO_SetBits(HCSR04_PORT, HCSR04_TRIG);   //拉高电平信号
		DelayUs(20);   //高电平至少10uS
		GPIO_ResetBits(HCSR04_PORT, HCSR04_TRIG); //拉低电平信号    
		/*等待回响信号*/
		while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==0);  //接收到信号ECHO为高电平
		TIM_Cmd(TIM4,ENABLE);        //使能TIM4定时器
		i+=1;				
		while(GPIO_ReadInputDataBit(HCSR04_PORT,HCSR04_ECHO)==1);  //直到回响信号消失
		TIM_Cmd(TIM4,DISABLE);       //失能TIM4定时器
		time=TIM_GetCounter(TIM4);
		length=(time+count*1000)/58.0;
		if(length<=0){
			length=0;
		}
		sum+=length;
		DelayMs(10);
		TIM4->CNT=0;
		count=0;
		}	
		length=sum/5.0;
		return length;
}

关于测量问题应该是本人代码缺陷。如能更好的实现还请多多指教。

参考自:
1、STM32与HC-SR04超声波测距
2、基于STM32的超声波HC-SR04历程


  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ChristianLuu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值