一、超声波测距模块简介(网络摘取)
HC-sr04是一款典型的超声波测距模块,升级版的程序和04的差别不大,只是测量范围和精度有所不同。
它是如何工作的?
超声波传感器使用声纳来确定到物体的距离。以下是其工作过程:
1. 发射器(触发引脚)发送信号:一段高频声音。
2. 当信号遇到一个物体时,它会被反射;
3. 然后发射器(回声引脚)接收该信号。
信号发送和接收之间的时间可以告知我们到物体的距离。这个是可以实现的,因为我们知道声音在空气中传播的速度。
传感器引脚图
● VCC:+ 5VDC
● Trig:触发(输入)
● Echo:回声(输出)
● GND:GND
二、CubeMX配置
任选两个GPIO,一个作为输入,一个作为输出。
在Project Manager -- Advanced Settings选项栏内,GPIO后面选择LL库。(忽略其他配置)
三、自动生成的代码
void MX_GPIO_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
/**/
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
四、用户代码
1.
/*
* hcsr04.h
*
* Created on: 2020年4月29日
* Author: zateper
*/
#ifndef INC_HCSR04_H_
#define INC_HCSR04_H_
float HCSR04_GetLength(void);
#endif /* INC_HCSR04_H_ */
2.
#include "hcsr04.h"
#include "gpio.h"
#include "delay.h"
#include "usart.h"
#define HCSR04_PORT GPIOB
#define HCSR04_TRIG LL_GPIO_PIN_12
#define ECHO_Reci LL_GPIO_IsInputPinSet(HCSR04_PORT,LL_GPIO_PIN_13)
void TRIG_pulse()
{
LL_GPIO_SetOutputPin(HCSR04_PORT,HCSR04_TRIG);
Delay_us(30);
LL_GPIO_ResetOutputPin(HCSR04_PORT,HCSR04_TRIG);
}
float HCSR04_GetLength(void)
{
uint32_t startval,endval,tickn,ticknend,delayt;
double delays;
uint32_t timeout = 23530;//uS
int i = 0;
float lengthTemp = 0;
float sum = 0;
delays = 0;
while(i!=5)
{
TRIG_pulse();
startval = SysTick->VAL;
tickn = HAL_GetTick();
while(ECHO_Reci == 0) //等待接收口高电平输出
{
endval = SysTick->VAL;//读取系统滴答值
ticknend = HAL_GetTick();
if(ticknend == tickn)
{
if(startval > endval)
{
delayt = (startval - endval);
}
else//系统滴答进入下一毫秒
{
delayt = (startval +72000 - endval);
}
}
else
{
delayt = ((ticknend - tickn) * 72000 + startval - endval);
}
if(delayt > 360000)//时间超时
{
printf("s%d,e%d;t%d,d%drn",startval,endval,tickn,ticknend);
return delayt;
}
}
startval = SysTick->VAL;//跳出上一循环意味着Echo来了上升沿,读取此时滴答(时间)
tickn = HAL_GetTick();
i = i + 1;
while(ECHO_Reci == 1)
{
endval = SysTick->VAL;
ticknend = HAL_GetTick();
if(ticknend == tickn)
{
if(startval > endval)
{
delays = (startval - endval)/72.0;
}
else
{
delays = (startval +72000 - endval)/72.0;
}
}
else
{
delays = ((ticknend - tickn) * 72000 + startval - endval)/72.0;
}
if(delays > timeout)//超时时间
{
printf("s%d,e%d;t%d,d%drn",startval,endval,tickn,ticknend);
return delays;
}
}
endval = SysTick->VAL;//跳出上一循环意味着Echo来了下降沿,读取此时滴答(时间)
ticknend = HAL_GetTick();
delays = ((ticknend - tickn) * 72000 + startval - endval)/72;//计算时间差
lengthTemp = ((float)delays/58.0);//单位cm
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
}
此方法利用现成的SysTick计算时间差而没有使用硬件定时器,精度一样很高,适用于没有中断或者中断响应处理比较快的场景。同时加入了超时处理,避免while()死循环。
3. delay_us()
4. 使用
float length;
length = HCSR04_GetLength();
printf("距离为:%.3frn",length);
一、超声波测距模块简介(网络摘取)
HC-sr04是一款典型的超声波测距模块,升级版的程序和04的差别不大,只是测量范围和精度有所不同。
它是如何工作的?
超声波传感器使用声纳来确定到物体的距离。以下是其工作过程:
1. 发射器(触发引脚)发送信号:一段高频声音。
2. 当信号遇到一个物体时,它会被反射;
3. 然后发射器(回声引脚)接收该信号。
信号发送和接收之间的时间可以告知我们到物体的距离。这个是可以实现的,因为我们知道声音在空气中传播的速度。
传感器引脚图
● VCC:+ 5VDC
● Trig:触发(输入)
● Echo:回声(输出)
● GND:GND
二、CubeMX配置
任选两个GPIO,一个作为输入,一个作为输出。
在Project Manager -- Advanced Settings选项栏内,GPIO后面选择LL库。(忽略其他配置)
三、自动生成的代码
void MX_GPIO_Init(void)
{
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
/**/
LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_12);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_12;
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/**/
GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
四、用户代码
1.
/*
* hcsr04.h
*
* Created on: 2020年4月29日
* Author: zateper
*/
#ifndef INC_HCSR04_H_
#define INC_HCSR04_H_
float HCSR04_GetLength(void);
#endif /* INC_HCSR04_H_ */
2.
#include "hcsr04.h"
#include "gpio.h"
#include "delay.h"
#include "usart.h"
#define HCSR04_PORT GPIOB
#define HCSR04_TRIG LL_GPIO_PIN_12
#define ECHO_Reci LL_GPIO_IsInputPinSet(HCSR04_PORT,LL_GPIO_PIN_13)
void TRIG_pulse()
{
LL_GPIO_SetOutputPin(HCSR04_PORT,HCSR04_TRIG);
Delay_us(30);
LL_GPIO_ResetOutputPin(HCSR04_PORT,HCSR04_TRIG);
}
float HCSR04_GetLength(void)
{
uint32_t startval,endval,tickn,ticknend,delayt;
double delays;
uint32_t timeout = 23530;//uS
int i = 0;
float lengthTemp = 0;
float sum = 0;
delays = 0;
while(i!=5)
{
TRIG_pulse();
startval = SysTick->VAL;
tickn = HAL_GetTick();
while(ECHO_Reci == 0) //等待接收口高电平输出
{
endval = SysTick->VAL;//读取系统滴答值
ticknend = HAL_GetTick();
if(ticknend == tickn)
{
if(startval > endval)
{
delayt = (startval - endval);
}
else//系统滴答进入下一毫秒
{
delayt = (startval +72000 - endval);
}
}
else
{
delayt = ((ticknend - tickn) * 72000 + startval - endval);
}
if(delayt > 360000)//时间超时
{
printf("s%d,e%d;t%d,d%drn",startval,endval,tickn,ticknend);
return delayt;
}
}
startval = SysTick->VAL;//跳出上一循环意味着Echo来了上升沿,读取此时滴答(时间)
tickn = HAL_GetTick();
i = i + 1;
while(ECHO_Reci == 1)
{
endval = SysTick->VAL;
ticknend = HAL_GetTick();
if(ticknend == tickn)
{
if(startval > endval)
{
delays = (startval - endval)/72.0;
}
else
{
delays = (startval +72000 - endval)/72.0;
}
}
else
{
delays = ((ticknend - tickn) * 72000 + startval - endval)/72.0;
}
if(delays > timeout)//超时时间
{
printf("s%d,e%d;t%d,d%drn",startval,endval,tickn,ticknend);
return delays;
}
}
endval = SysTick->VAL;//跳出上一循环意味着Echo来了下降沿,读取此时滴答(时间)
ticknend = HAL_GetTick();
delays = ((ticknend - tickn) * 72000 + startval - endval)/72;//计算时间差
lengthTemp = ((float)delays/58.0);//单位cm
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
}
此方法利用现成的SysTick计算时间差而没有使用硬件定时器,精度一样很高,适用于没有中断或者中断响应处理比较快的场景。同时加入了超时处理,避免while()死循环。
3. delay_us()
4. 使用
float length;
length = HCSR04_GetLength();
printf("距离为:%.3frn",length);
举报