HC-SR04超声波测距模块可提供2cm-400cm的非接触式距离感测功能,测距精度可达3mm; 模块包括超声波发射器、接收器与控制电路。 在智能小车的测距、避障,盲人拐杖,视力保护器(坐姿矫正),倒车雷达等应用中时常使用。 工作原理HC-SR04基本工作原理:
代码实现通过上面的分析,我们知道,获得超声波模块测得的距离的难点就是求得Echo引脚输出脉冲的高电平持续时间。 实现步骤:
//文件'sr04.h'中添加定义 extern u32 msHcCount;
//超声波硬件接口定义 #define HCSR04_PORT GPIOA #define HCSR04_CLK RCC_APB2Periph_GPIOA #define HCSR04_TRIG GPIO_Pin_2 #define HCSR04_ECHO GPIO_Pin_3
#define TRIG_Send PAout(2) #define ECHO_Reci GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_3)
//文件'sr04.c'中 void Hcsr04Init() { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(HCSR04_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); GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_DeInit(TIM4); TIM_TimeBaseStructure.TIM_Period = (1000-1); TIM_TimeBaseStructure.TIM_Prescaler =(72-1); 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); Hcsr04_NVIC(); TIM_Cmd(TIM4,DISABLE); }
当ECHO_Reci引脚的输入电平由低变高时:即while(ECHO_Reci == 0); 循环为假时开始计时:OpenTimerForHc(); 当ECHO_Reci引脚的输入电平由高变低时,即while(ECHO_Reci == 1); 循环为假时结束计时:CloseTimerForHc(); 计时结束,调用GetEchoTimer(void)函数计算总耗时,单位us。
通过定时器4计数器值计算距离的具体实现代码如下所示: float Hcsr04GetLength(void ) { u32 t = 0; int i = 0; float lengthTemp = 0; float sum = 0; while(i<5) { TRIG_Send = 1; delay_us(20); TRIG_Send = 0; while(ECHO_Reci == 0); OpenTimerForHc(); i = i 1; while(ECHO_Reci == 1); CloseTimerForHc(); t = GetEchoTimer(); lengthTemp = ((float)t/58.0); sum = lengthTemp sum ; } lengthTemp = sum/5.0; return lengthTemp; }
也是取五次测量值的平均值作为结果,在计算Echo引脚输出高电平时间的时候,只要while(ECHO_Reci)为真,计时即 10us,直至高电平结束,即可获得高电平持续的总时间。
注意:文中多次使用类似while循环:while(ECHO_Reci),其实这样做容易让单片机陷入死循环,各位可以试着想想有没有好的方式避免。距离换算查看手册,我们会看到,手册上说: 测量距离(cm) = 高电平持续的us数 / 58 为什么us值/58即是以cm为单位的距离值呢? 正常的换算公式为: 测试距离 = (高电平时间*声速(340m/s))/2 除以2的原因是,超声波的信号是往返的耗时等于高电平时间,我们求距离,需要除以2。 上面的测量距离单位为m,高电平时间为s, 如果我们把测量距离的单位换为cm,高电平时间改为us, 则上面的公式就修改为: 测量距离cm = (高电平时间us/1000000) * 340 / 2 * 100 即测量距离cm = 高电平时间us * 17 / 1000; 即测量距离cm = 高电平时间us / (1000/17);而1000/17 ≈ 58.82 所以一般为了方便计算,距离换算就是将求得的高电平时间除以58,即得距离值,单位cm。 硬件连接目前HC-SR04这个模块有很多版本,最好选用3.3V和5V兼容的版本。 我也拿了一个5V的老版本做了一下测试,使用3.3V供电,测量的数据不对,什么也不改变的情况下,将电源引脚供电改为5V供电,返回的数据就正常了。 如果使用5V老版本的HC-SR04模块,为了使系统能够稳定,最好选用5V耐受的IO引脚,诸如带有下面FT标识的引脚。 实际效果图 |
|
来自: 新用户0118F7lQ > 《文件夹1》