基于51单片机的三路超声波避障程序(HC-SR04)

简介: 基于STC89C52RC单片机(12MHz晶振),实现三路超声波避障功能。通过HC-SR04超声波模块检测前、左、右三方向障碍物距离,结合L298N电机驱动模块控制小车转向/停止,实现自主避障。核心功能包括:三路超声波分时测距、距离阈值判断、电机PWM调速与转向控制。

一、系统概述

基于STC89C52RC单片机(12MHz晶振),实现三路超声波避障功能。通过HC-SR04超声波模块检测前、左、右三方向障碍物距离,结合L298N电机驱动模块控制小车转向/停止,实现自主避障。核心功能包括:三路超声波分时测距、距离阈值判断、电机PWM调速与转向控制。

二、硬件设计

2.1 核心组件

模块 型号/参数 功能说明
主控 STC89C52RC(8位,12MHz) 三路测距控制、避障逻辑、电机驱动
超声波 3×HC-SR04 前(Trig→P1.0,Echo→P1.1)、左(Trig→P1.2,Echo→P1.3)、右(Trig→P1.4,Echo→P1.5)
电机驱动 L298N 驱动2路直流电机(正转/反转/调速)
电机 2×直流减速电机(6V) 小车动力(左/右轮)
电源 7.4V锂电池+LM7805(5V) 为单片机、超声波、L298N供电

2.2 硬件连接

模块 引脚(STC89C52RC) 说明
超声波前 Trig→P1.0,Echo→P1.1 检测正前方障碍物
超声波左 Trig→P1.2,Echo→P1.3 检测左侧障碍物
超声波右 Trig→P1.4,Echo→P1.5 检测右侧障碍物
L298N IN1→P2.0,IN2→P2.1 左电机正转/反转控制
IN3→P2.2,IN4→P2.3 右电机正转/反转控制
ENA→P2.4(PWM),ENB→P2.5(PWM) 电机调速(PWM占空比控制)

三、软件设计(Keil C51)

3.1 核心原理

  1. 超声波测距

    • Trig引脚发送10us高电平触发测距;

    • Echo引脚接收高电平,用定时器计数高电平持续时间t(单位:us);

    • 距离d = (t × 0.034) / 2(声速340m/s=0.034cm/us,往返距离÷2)。

  2. 避障逻辑(三路阈值):

    • 前方(Trig1/Echo1):d < 20cm停止,20~50cm减速,>50cm前进;

    • 左侧(Trig2/Echo2):d > 30cm可左转;

    • 右侧(Trig3/Echo3):d > 30cm可右转;

    • 综合判断:前方障碍→优先右转(若右侧空旷)→否则左转→仍不行则后退。

3.2 核心代码实现

3.2.1 头文件与宏定义

#include <reg52.h>
#include <intrins.h>

// ==================== 引脚定义(三路超声波) ====================
#define TRIG1 P1_0  // 前超声波Trig
#define ECHO1 P1_1  // 前超声波Echo
#define TRIG2 P1_2  // 左超声波Trig
#define ECHO2 P1_3  // 左超声波Echo
#define TRIG3 P1_4  // 右超声波Trig
#define ECHO3 P1_5  // 右超声波Echo

// ==================== 电机驱动引脚(L298N) ====================
#define IN1 P2_0    // 左电机正转
#define IN2 P2_1    // 左电机反转
#define IN3 P2_2    // 右电机正转
#define IN4 P2_3    // 右电机反转
#define ENA P2_4    // 左电机PWM(PWM占空比控制)
#define ENB P2_5    // 右电机PWM

// ==================== 宏定义 ====================
#define uchar unsigned char
#define uint unsigned int
#define THRESHOLD_FRONT_NEAR 20   // 前方近距离阈值(cm)
#define THRESHOLD_FRONT_FAR  50   // 前方远距离阈值(cm)
#define THRESHOLD_SIDE       30   // 侧向安全距离(cm)
#define PWM_DUTY_MAX         80   // PWM最大占空比(80%)

3.2.2 延时函数(微秒/毫秒级)

// 微秒延时(12MHz晶振,1us≈12周期,误差±1us)
void DelayUs(uint us) {
   
    while (us--) {
   
        _nop_(); _nop_(); _nop_(); _nop_();  // 4个_nop_≈1us
        _nop_(); _nop_(); _nop_(); _nop_();
    }
}

// 毫秒延时
void DelayMs(uint ms) {
   
    uint i, j;
    for (i=0; i<ms; i++)
        for (j=0; j<110; j++);  // 110次循环≈1ms
}

3.2.3 定时器初始化(用于Echo高电平计时)

// 定时器0初始化(16位模式,用于计时Echo高电平时间)
void Timer0_Init() {
   
    TMOD |= 0x01;  // T0模式1(16位计数)
    TH0 = 0; TL0 = 0;  // 初始值0
    ET0 = 0;  // 关闭T0中断(查询模式)
    TR0 = 0;  // 初始停止计数
}

3.2.4 单路超声波测距函数

// 测量单路超声波距离(返回cm,-1表示超时)
uint Measure_Distance(uchar trig_pin, uchar echo_pin) {
   
    uint time = 0;
    uint timeout = 25000;  // 超时阈值(25000us=25ms,对应4m距离)

    // 1. 触发测距(Trig发送10us高电平)
    trig_pin = 1;
    DelayUs(15);  // 15us(>10us即可)
    trig_pin = 0;

    // 2. 等待Echo变高(启动计时)
    while (echo_pin == 0 && timeout--);  // 等待Echo变高
    if (timeout == 0) return 0xFFFF;  // 超时返回错误

    // 3. 启动定时器计数Echo高电平时间
    TR0 = 1;  // 启动T0计数
    TH0 = 0; TL0 = 0;
    timeout = 25000;
    while (echo_pin == 1 && timeout--);  // 等待Echo变低
    TR0 = 0;  // 停止计数

    if (timeout == 0) return 0xFFFF;  // 超时返回错误

    // 4. 计算时间(us)= TH0<<8 | TL0
    time = (TH0 << 8) | TL0;
    // 距离(cm) = (time × 0.034) / 2 ≈ time × 0.017
    return (uint)(time * 0.017);  // 简化计算(0.034/2=0.017)
}

3.2.5 电机控制函数

// 电机停止
void Motor_Stop() {
   
    IN1 = 0; IN2 = 0; IN3 = 0; IN4 = 0;
    ENA = 0; ENB = 0;
}

// 电机前进(PWM调速)
void Motor_Forward(uchar duty) {
   
    IN1 = 1; IN2 = 0; IN3 = 1; IN4 = 0;  // 正转
    ENA = (duty > PWM_DUTY_MAX) ? PWM_DUTY_MAX : duty;  // 限幅
    ENB = ENA;  // 左右电机同速
}

// 电机左转(右轮前进,左轮停止)
void Motor_TurnLeft(uchar duty) {
   
    IN1 = 0; IN2 = 0; IN3 = 1; IN4 = 0;  // 左轮停,右轮转
    ENA = 0; ENB = (duty > PWM_DUTY_MAX) ? PWM_DUTY_MAX : duty;
}

// 电机右转(左轮前进,右轮停止)
void Motor_TurnRight(uchar duty) {
   
    IN1 = 1; IN2 = 0; IN3 = 0; IN4 = 0;  // 左轮转,右轮停
    ENA = (duty > PWM_DUTY_MAX) ? PWM_DUTY_MAX : duty;
    ENB = 0;
}

// 电机后退
void Motor_Backward(uchar duty) {
   
    IN1 = 0; IN2 = 1; IN3 = 0; IN4 = 1;  // 反转
    ENA = (duty > PWM_DUTY_MAX) ? PWM_DUTY_MAX : duty;
    ENB = ENA;
}

3.2.6 避障逻辑主函数

void Obstacle_Avoidance() {
   
    uint dist_front, dist_left, dist_right;

    // 1. 分时测量三路距离(避免干扰)
    dist_front = Measure_Distance(TRIG1, ECHO1);  // 前
    DelayMs(50);  // 间隔50ms
    dist_left = Measure_Distance(TRIG2, ECHO2);    // 左
    DelayMs(50);
    dist_right = Measure_Distance(TRIG3, ECHO3);  // 右

    // 2. 异常处理(超时视为无障碍)
    if (dist_front == 0xFFFF) dist_front = 100;
    if (dist_left == 0xFFFF) dist_left = 100;
    if (dist_right == 0xFFFF) dist_right = 100;

    // 3. 避障决策
    if (dist_front > THRESHOLD_FRONT_FAR) {
   
        // 前方安全(>50cm):前进(70%速度)
        Motor_Forward(70);
    } else if (dist_front > THRESHOLD_FRONT_NEAR) {
   
        // 前方中等距离(20~50cm):减速前进(50%速度)
        Motor_Forward(50);
    } else {
   
        // 前方近距离(<20cm):停止并转向
        Motor_Stop();
        DelayMs(200);

        // 优先右转(右侧空旷)
        if (dist_right > THRESHOLD_SIDE) {
   
            Motor_TurnRight(60);  // 右转(60%速度)
            DelayMs(300);  // 转300ms
        } 
        // 其次左转(左侧空旷)
        else if (dist_left > THRESHOLD_SIDE) {
   
            Motor_TurnLeft(60);   // 左转(60%速度)
            DelayMs(300);
        } 
        // 两侧均障碍:后退(50%速度)
        else {
   
            Motor_Backward(50);
            DelayMs(500);  // 退500ms
        }
    }
}

3.2.7 主函数

void main() {
   
    Timer0_Init();  // 初始化定时器0(计时用)
    EA = 1;         // 开总中断(如需中断可启用)

    while (1) {
   
        Obstacle_Avoidance();  // 循环执行避障逻辑
        DelayMs(100);          // 每100ms检测一次
    }
}

参考代码 基于51单片机超声波避障程序(三路) www.youwenfan.com/contentali/182711.html

四、关键问题与解决方案

4.1 三路干扰问题

  • 原因:同时触发三路超声波会导致信号串扰。

  • 解决:分时触发(每路间隔50ms),确保前一路线束Echo处理完毕再触发下一路线束。

4.2 测距误差大

  • 原因:定时器精度不足(12MHz晶振下,16位定时器最大计时65ms,对应11m距离)。

  • 解决:HC-SR04量程仅4m(约23ms),超时阈值设为25ms足够,误差主要来自声速温度补偿(常温下0.034cm/us可接受)。

4.3 电机抖动

  • 原因:PWM占空比突变或电源不稳。

  • 解决:PWM占空比渐变过渡(如每次增减10%),电源端并联100μF电容滤波。

五、测试与验证

  1. 硬件连接:按2.2节连接三路超声波与电机驱动,确保Trig/Echo引脚无虚焊。

  2. 功能测试

  • 前方无障碍物(>50cm):小车前进;

  • 前方放置障碍物(<20cm):小车停止→右转→前进;

  • 单侧有障碍(如左侧<30cm):小车优先右转避开。

六、总结

基于51单片机实现了三路超声波避障,核心是分时测距、定时器计时与电机联动控制。通过模块化设计(测距、电机、逻辑分离),可扩展为多路检测或加入红外传感器融合避障。

相关文章
|
5天前
|
机器学习/深度学习 人工智能 监控
人体姿态检测数据集分享(适用于YOLO系列深度学习检测任务)
本数据集含6000张高质量标注图像,覆盖站着、摔倒、坐、深蹲、跑5类人体姿态,按5:1划分训练集与验证集,采用YOLO格式标注,结构清晰,开箱即用,适用于YOLOv8等目标检测模型训练,助力跌倒监测、智能健身、安防监控等应用。
228 3
|
5天前
|
IDE 网络安全 开发工具
【全网最详细】TortoiseGit安装汉化和配置保姆级教程(附安装包+汉化包)
TortoiseGit是Windows平台开源免费的Git图形化客户端,集成于资源管理器右键菜单,零命令操作。支持图标覆盖层直观显示文件状态,无需记忆git命令,兼容所有IDE,学习成本低,适合个人及团队版本管理。(239字)
|
5天前
|
机器学习/深度学习 缓存 自然语言处理
多语言文本嵌入模型解析:paraphrase-multilingual-MiniLM 与 all-MiniLM深度对比.123
本文深度对比all-MiniLM-L6-v2与paraphrase-multilingual-MiniLM-L12-v2:前者轻快高效,专精英文;后者12层多语言支持,中英文语义区分更优。实践表明,意图识别等任务中,多语言模型显著提升准确率,虽稍慢但泛化更强。
238 3
|
5天前
|
缓存 人工智能 安全
90% 的人不知道 Claude Code 还有插件系统!官方从未公开的 6 大组件深度拆解
本文深度拆解 Claude Code 插件系统的 6 大核心组件:Skills、Hooks、Agents、MCP、规则文件与配置系统,帮你快速上手插件开发与管理。
320 1
|
5天前
|
机器学习/深度学习 监控 安全
人群计数行人检测数据集分享(适用于YOLO系列深度学习检测任务)
本数据集含9000张行人图像(7200训练+1800验证),覆盖街道、商场、地铁等多场景,已精准标注YOLO格式,支持YOLOv8/RT-DETR等框架直接训练,适用于人群计数、智慧安防与流量分析。
206 0
|
5天前
|
人工智能 监控 前端开发
学习AI Agent编程-第二天-LangGraph ReAct模式实现
本文介绍了LangChain中ReAct(推理-行动)模式的实践应用:通过“会议室申请”流程,演示LLM如何循环执行“决策→调用工具→评估结果→调整策略”,实现多步任务自动化。代码涵盖流程定义、工具函数与多轮会话测试,验证了其在空闲检查、报备审批、异常处理等场景的可靠性。(239字)
212 7
学习AI Agent编程-第二天-LangGraph ReAct模式实现
|
5天前
|
人工智能 机器人 Shell
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
龙虾本地化AI(Lobster AI)是一款完全离线、零成本、零隐私泄露的开源机器人系统,支持文本推理(Gemma4)、多模态视觉理解(桌面/摄像头)、语音识别与合成(Sherpa-ONNX),纯本地运行,不依赖任何云服务。
251 2
【开源】龙虾人工智能 —— 完全本地化的机器人大脑!不联网、不付 API 费、能看能说能理解!
|
5天前
|
存储 人工智能 弹性计算
基于阿里Qoder的实训案例荣获2026全国高校程序设计教育大会特等奖
复旦大学赵卫东老师主持的“基于阿里Qoder开发个人博客系统”实训案例,获2026全国高校程序设计教育大会特等奖。案例融合通义灵码与千问API,覆盖AI写作、分析、部署全流程, exemplifies AI时代产教融合新范式。(239字)
195 3
|
5天前
Trae关闭后,自动重新安装问题解决
本方案指导用户将Trae更新模式设为手动:进入设置→Editor设置→应用程序→更新,选择Manual模式。配图清晰展示各操作步骤界面,助您轻松完成配置
393 3
|
5天前
|
Web App开发 开发工具 iOS开发
小书匠:一款本地优先、去中心化的全能笔记软件
小书匠是一款**本地优先、去中心化、支持选择性同步**的全平台笔记软件。它不依赖任何中心服务器,所有数据都保存在用户本地,真正做到了"我的数据我做主"。
167 6
小书匠:一款本地优先、去中心化的全能笔记软件