1. 短距离版本
适用于短距离测量(例如15cm以内)。代码如下:
#include "A_include.h"
#include "HC_SR04.h"
double getShortDistance(void)
{
double distance;
uint16_t start_time, end_time;
uint16_t timeout = 0;
// 发送超声波脉冲
TRIG_1_High();
delay_ms(10);
TRIG_1_Low();
// 等待ECHO变高,超时保护
while(!ECHO && (timeout++ < 15000));
start_time = DL_TimerG_getTimerCount(TIMER_0_INST); // 记录开始时间
timeout = 0;
// 等待ECHO变低,超时保护
while(ECHO && (timeout++ < 15000));
end_time = DL_TimerG_getTimerCount(TIMER_0_INST); // 记录结束时间
// 计算距离
distance = (end_time - start_time);
if(distance < 0) {
distance = -distance; // 取绝对值
}
distance /= 5; // 转换为厘米
// 去除长距离的影响
if(distance <= 250) {
return distance / 33 * 9.8; // 转换为实际距离
} else {
return -1; // 超出测量范围
}
}
2. 长距离版本
适用于长距离测量,加入了溢出处理机制。代码如下:
#include "A_include.h"
#include "HC_SR04.h"
#define MAX_DISTANCE_CM 100 // 最大测量距离(单位:厘米)
#define TIMEOUT 30000 // 超时时间(单位:计时器计数)
double getLongDistance(void)
{
double distance;
uint16_t start_time, end_time;
uint16_t timeout = 0;
uint16_t overflow_count = 0; // 溢出计数器
// 发送超声波脉冲
TRIG_1_High();
delay_ms(10);
TRIG_1_Low();
// 等待ECHO变高,超时保护
while(!ECHO && (timeout++ < TIMEOUT)) {
if(timeout == TIMEOUT) {
overflow_count++; // 溢出计数
timeout = 0; // 重置超时计数器
}
}
start_time = DL_TimerG_getTimerCount(TIMER_0_INST); // 记录开始时间
timeout = 0; // 重置超时计数器
// 等待ECHO变低,超时保护
while(ECHO && (timeout++ < TIMEOUT)) {
if(timeout == TIMEOUT) {
overflow_count++; // 溢出计数
timeout = 0; // 重置超时计数器
}
}
end_time = DL_TimerG_getTimerCount(TIMER_0_INST); // 记录结束时间
// 计算总时间(包括溢出时间)
uint32_t total_time = (end_time - start_time) + (overflow_count * TIMEOUT);
// 计算距离
distance = total_time / 5; // 转换为厘米
// 检查是否超出测量范围
if(distance > MAX_DISTANCE_CM) {
return -1; // 超出测量范围
} else {
return distance / 33 * 9.8; // 转换为实际距离
}
}
代码说明
-
短距离版本:
- 使用简单的计时器计数来测量超声波脉冲的往返时间。
- 通过超时保护机制防止程序卡死。
- 适用于短距离测量(例如15cm以内)。
-
长距离版本:
- 加入了溢出处理机制,通过
overflow_count
变量记录计时器溢出的次数。 - 使用
uint32_t
类型来存储总时间,以支持更长的测量距离。 - 适用于长距离测量(例如1m以内)。
- 加入了溢出处理机制,通过
- 使用
start_time
和end_time
来记录超声波脉冲的开始和结束时间。 - 使用
overflow_count
来记录计时器溢出的次数。
配置
- ECHO引脚
- TRIG引脚
- 定时器(TIMER)