基于stm32F407的超声波测距程序及注意事项(HC-SR04)

网上的资料太杂太乱,调这个东西的时候走了不少弯路,现在分享出来,亲测管用!

基本工作原理
(1)采用IO口TRIG触发测距,给至少10us的高电平信号;

(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

(3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间声速(340M/S))/2;
(4)本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以达到你移动测量的值*
5、 操作:初始化时将trig和echo端口都置低,首先向给 trig 发送至少10 us的高电平脉冲(模块自动向外发送8个40K的方波),然后等待,捕捉 echo 端输出上升沿,捕捉到上升沿的同时,打开定时器开始计时,再次等待捕捉echo的下降沿,当捕捉到下降沿,读出计时器的时间,这就是超声波在空气中运行的时间,按照 测试距离=(高电平时间
声速(340M/S))/2 就可以算出超声波到障碍物的距离。

程序

超声波端口初始化:
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOG, ENABLE);//使能GPIO时钟
//trig
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//
//echo
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOG, &GPIO_InitStructure);//¯

定时器初始化:
TIM4_Int_Init(250-1,8400-1);//定时器时钟84M,分频系数8400,所以84M/8400=10KHZ的技术频率,记一次数0.1ms,计数250次为25ms。
/超声波测距最大4米,按声速340M/s计算,超声波测量最大距离4m时所用时间为42/340=23.6ms,这里取中断时间为25ms,完全够用!*/

定时器中断程序:

void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
{
flag=1;//·发生中断代表测量范围超出,使flag为1.
}
TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
}

测距程序:
double s=0;
double l;
double p[5];
int i;

 for(i=1;i<=5;i++)
 {
	//发出方波
		 trig=1;
		 delay_us(20);
		 trig=0;
		 
	//等待echo接收高电平
		 while(echo==0);
		 
	//开启定时器计时
		 TIM_Cmd(TIM4, ENABLE);  //
		 
		 TIM4->CNT=0;
		 
		 while(echo==1);//等待接收完成
		 
		 TIM_Cmd(TIM4, DISABLE);//完全接收后关闭定时器
		 
	//检验接收时是否发生了定时器中断,若发生中断,则超出测量范围,一般这种情况不会发生,空气中杂质粒子会影响声波,超声波测量范围也就1米以内。
		 if(flag==1)
		 {
				p[i]=400;
			 
				flag=0;
			}
				 else
				 {
					 l=TIM_GetCounter(TIM4);//
					 
					 p[i]=l*17/10;//cm  0.1/1000*340/2*100*l
				 }
			s+=p[i];	 
			delay_ms(24);

/* 延时必须要加,否则容易出现声波发生碰撞的问题,产生较大误差,延时根据声波在空气中运行的最大时间计算即可,这里按4米计算,延时24ms.
*/
}
s=s/5;//取平均。

 return s;

}

主程序:

while(1)
 {
	 sum=ceju();
	 printf("%lf   \n",sum);
 }
  • 14
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值