打印
[STM32F0]

【转】HCSR04超声波传感器驱动

[复制链接]
854|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
风萧寒|  楼主 | 2016-12-4 00:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

HC_SR04是一款使用较为广泛的超声波测距模块,模块图如下


该模块具有四个引脚,分别为VCC GND TRIG ECHO,其中VCC GND为供电脚

TRIG为测距触发引脚,ECHO为测距输入引脚

该模块的驱动模式为

控制口发一个 10US 以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,就可以达到你移动测量的值了

模块工作原理如下

(1)采用 IO 触发测距,给至少 10us 的高电平信号;

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

(3)有信号返回,通过 IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间

(4计算测试距离测试距离=(高电平时间*声速(340M/S))/2;

根据工作原理,我们可以选择两种模式驱动

1.       采用中断+定时器方式,将ECHO定义为上升沿下降沿都能触发中断,trig触发之后,echo高电平进中断打开定时器,echo低电平关闭定时器并统计定时器计数值

2.       采用普通IO+定时器模式,触发之后等待echo响应,响应时打开定时器,直到echo恢复低关闭定时器,获取时间

1:此模块不宜带电连接,如果要带电连接,则先让模块的 Gnd 端先连接。否则会影响

模块工作。

2:测距时,被测物体的面积不少于0.5平方米且要尽量平整。否则会影响测试结果。


沙发
风萧寒|  楼主 | 2016-12-4 00:30 | 只看该作者

详细驱动代码如下所示

Hcsr04.c

[cpp] view plain copy


  • #include "hcsr04.h"  
  •   
  •   
  • #define HCSR04_PORT     GPIOB  
  • #define HCSR04_CLK      RCC_APB2Periph_GPIOB  
  • #define HCSR04_TRIG     GPIO_Pin_5  
  • #define HCSR04_ECHO     GPIO_Pin_6  
  •   
  • #define TRIG_Send  PBout(5)  
  • #define ECHO_Reci  PBin(6)  
  •   
  • u16 msHcCount = 0;//ms计数  
  •   
  • void Hcsr04Init(u32 NVIC_PriorityGroup,u32 PreemptionPriority,u32 SubPriority)  
  • {  
  •     u32 NVICtemp    = 0;        //用于NVIC控制器的变量  
  •     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     //生成用于定时器设置的结构体  
  •     GPIO_InitTypeDef GPIO_InitStructure;  
  •     RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);  
  •       
  •     NVICtemp = NVIC_EncodePriority(NVIC_PriorityGroup , PreemptionPriority , SubPriority);    //中断优先级变量解码  
  •       
  •     //IO初始化  
  •     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_Speed = GPIO_Speed_50MHz;  
  •     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;//下拉输入  
  •     GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);      
  •     //定时器初始化 使用基本定时器TIM6  
  •       
  •     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);   //使能对应RCC时钟  
  •     //配置定时器基础结构体  
  •     TIM_TimeBaseStructure.TIM_Period = 1000; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值   计数到1000为1ms  
  •     TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值  1M的计数频率 1US计数  
  •     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式  
  •     TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位  
  •       
  •     TIM_ClearFlag(TIM6, TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断  
  •     TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);    //打开定时器更新中断  
  •     NVIC_SetPriority(TIM6_IRQn,NVICtemp);          //设置中断优先级  
  •     NVIC_EnableIRQ(TIM6_IRQn);                     //使能对应中断  
  •       
  • }  
  • static void OpenTimerForHc()    //打开定时器  
  • {  
  •     TIM_SetCounter(TIM6,0);//清除计数  
  •     msHcCount = 0;  
  •     TIM_Cmd(TIM6, ENABLE);  //使能TIMx外设  
  • }  
  •   
  • static void CloseTimerForHc()   //关闭定时器  
  • {  
  •     TIM_Cmd(TIM6, DISABLE);  //使能TIMx外设  
  • }  
  •   
  •   
  • //定时器6中断服务程序  
  • void TIM6_IRQHandler(void)   //TIM3中断  
  • {  
  •     if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否  
  •     {  
  •         TIM_ClearITPendingBit(TIM6, TIM_IT_Update  );  //清除TIMx更新中断标志   
  •         msHcCount++;  
  •     }  
  • }  
  •   
  • u32 GetEchoTimer(void)  
  • {  
  •     u32 t = 0;  
  •     t = msHcCount*1000;//得到MS  
  •     t += TIM_GetCounter(TIM6);//得到US  
  •     return t;  
  • }  
  •   
  • //一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号  
  • void Hcsr04GetLength(u32* length)  
  • {  
  •     u32 t = 0;  
  •     float lengthTemp;  
  •     TRIG_Send = 1;      //发送口高电平输出  
  •     DelayUs(10);  
  •     TRIG_Send = 0;  
  •     while(ECHO_Reci == 0);      //等待接收口高电平输出  
  •     OpenTimerForHc();   //打开定时器  
  •     while(ECHO_Reci == 1);  
  •     CloseTimerForHc();  //关闭定时器  
  •     t = GetEchoTimer(); //获取时间,分辨率为1US  
  •     lengthTemp = ((float)t/58);//cm  
  •     *length = (u32)lengthTemp;   
  • }  




Hcsr04.h

[cpp] view plain copy


  • #ifndef __HCSR04_H  
  • #define __HCSR04_H  
  • #include "stm32f10x.h"  
  • #include "delay.h"  
  • #include "ioremap.h"  
  • #include "common.h"  
  •   
  •   
  •   
  •   
  •   
  • //超声波模块初始化  
  • void Hcsr04Init(u32 NVIC_PriorityGroup,u32 PreemptionPriority,u32 SubPriority);  
  •   
  • //超声波模块一次距离获取  
  • //返回0 成功  
  • //返回1 失败  
  • void Hcsr04GetLength(u32* length);  
  •   
  • #endif  


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

68

主题

134

帖子

3

粉丝