目录
一、传感器原理
超声波传感器发出的啁啾声通常在23 kHz到40 kHz之间,远高于人类听觉在20 kHz时的典型可听范围,因此称为超声波。使用这种啁啾可以测量声音从发出到物体反弹所需的时间,与蝙蝠寻找猎物的回声定位基本原理相同。由于室温下空气中的声速为每秒343米,所以可以利用发射到返回的时间转换为距离值。其中超声波传感器模块实物图如下图所示。
超声波传感器模块的基本工作原理说明如下:
- 采用IO口TRIG触发测距,给至少10us的高电平信号;
- 模块自动发送8个40khz的方波,自动检测是否有信号返回;
- 有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
超声波模块工作示意图如下图所示。
而测试距离可以通过以下公式进行计算:
测试距离 = (高电平时间 * 声速(343m/s)) / 2
二、传感器驱动代码
我们想要实现超声波测距需要按照其时序图进行代码编写,所以需要引入延时函数,如果在裸机上进行开发的话普通的延时没什么大问题;但是如果想要在操作系统上实现的话则需注意延时函数会阻塞系统的正常运行,因此使用定时器可能效果会好一些。这里提供的是基于裸机的代码。
驱动C源代码:
#include "hcsr04.h"
#include "delay.h"
/* ----------------------- 传感器引脚定义 -------------------- */
#define HCSR_Trig_GPIO_CLK RCC_APB2Periph_GPIOC
#define HCSR_Trig_GPIO_PORT GPIOC
#define HCSR_Trig_GPIO_PIN GPIO_Pin_1
#define HCSR_Echo_GPIO_CLK RCC_APB2Periph_GPIOC
#define HCSR_Echo_GPIO_PORT GPIOC
#define HCSR_Echo_GPIO_PIN GPIO_Pin_2
#define HCSR_Trig(x) x ? (HCSR_Trig_GPIO_PORT->BSRR = HCSR_Trig_GPIO_PIN) : (HCSR_Trig_GPIO_PORT->BSRR = HCSR_Trig_GPIO_PIN << 16)
#define HCSR_Echo GPIO_ReadInputDataBit(HCSR_Echo_GPIO_PORT, HCSR_Echo_GPIO_PIN)
/* 超声波模块 引脚初始化 */
void ultrasonic_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(HCSR_Trig_GPIO_CLK | HCSR_Echo_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = HCSR_Trig_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 时钟频率 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */
GPIO_Init(HCSR_Trig_GPIO_PORT, &GPIO_InitStructure); /* 根据设定参数初始化 */
GPIO_InitStructure.GPIO_Pin = HCSR_Echo_GPIO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* 时钟频率 */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /* 浮空输入 */
GPIO_Init(HCSR_Echo_GPIO_PORT, &GPIO_InitStructure); /* 根据设定参数初始化 */
}
/* 超声波测距 若为负数代表测距失败 */
short ultrasonic_GetDistance(void)
{
u16 distance = 0; //距离设置
u16 t = 0; //计数器
HCSR_Trig(1); //触发端(Trig)置1
delay_us(13); //延时10us以上
HCSR_Trig(0); //触发端(Trig)置0
//等待回响信号(Echo)信号拉低
while(HCSR_Echo == 0) {
t++;
delay_us(1);
if (t >= 100000) //大于100ms认为通讯失败
return -1;
}
t = 0;
//等待回响信号(Echo)出现高电平
while(HCSR_Echo == 1) {
t++;
/*
超声波模块的测量精度:3mm
声速:(340m)/s = 340000mm/1000ms = 340mm/ms = 0.34mm/us
单位延时时间t0 = 3/0.34 = 8.823us ≈ 9us
*/
delay_us(9);
if (t >= 100000) //大于100ms认为通讯失败
return -2;
}
t = t / 2; //时间t为发送+接收两段 需要/2
distance = 3 * t; //距离=测量精度*持续时间
return distance;
}
驱动H源代码:
#ifndef _HCSR04_H
#define _HCSR04_H
#include "stm32f10x.h"
/* ---------------------------- 函数清单 -------------------------- */
void ultrasonic_init (void);
short ultrasonic_GetDistance (void);
#endif