51单片机超声波测距C程序、proteus仿真、报告! 支持按键设置报警距离值、当测的距离低于设置值时、声光报警

咱们今天来玩点实用的——用51单片机搞个带报警功能的超声波测距仪。别看原理简单,实际调试起来那叫一个酸爽,特别是当代码死活不认回波信号的时候(别问我怎么知道的)...

先上硬件方案:STC89C52主控,HC-SR04超声波模块,1602液晶显示,外加三个按键和报警用的LED、蜂鸣器。Proteus仿真里记得给Trig和Echo脚接上示波器探头,方便观察波形。

测距原理其实不复杂:给Trig脚发个10us以上的高电平,模块自动发射8个40kHz脉冲,Echo脚高电平持续时间就是超声波往返时间。关键代码长这样:

void MeasureDistance() {
    Trig = 1;
    Delay12us();  //实测12us刚好满足要求
    Trig = 0;
    
    while(!Echo);  //等待回波信号
    TR0 = 1;       //启动定时器
    while(Echo);
    TR0 = 1;       //停止定时器
    
    distance = (TH0<<8 | TL0)*0.017; //0.017cm/us
    TH0 = TL0 = 0;
}

这里有个坑爹点:不同型号晶振要重新校准时间系数。之前用12MHz晶振死活测不准,后来发现得把定时器模式改成1T模式才搞定。

51单片机超声波测距C程序、proteus仿真、报告! 支持按键设置报警距离值、当测的距离低于设置值时、声光报警

报警阈值设置功能主要靠按键扫描:

if(setKeyPressed){
    currentSetting = !currentSetting;  //切换设置模式
    lcdShowCursor();                  //显示光标提示
    while(setKeyHolding);             //等待松手
}

//在设置模式下调节阈值
if(currentSetting){
    if(upKeyPressed) threshold++;
    if(downKeyPressed) threshold--;
}

实际调试发现必须加按键消抖,否则数值会乱跳。我直接用20ms延时搞定,虽然土但有效:

#define Debounce() {DelayMs(20);if(P3_0==0) return;}

报警触发逻辑简单粗暴:

if(distance < threshold && distance > 2){
    Buzzer = 0;   //低电平触发蜂鸣器
    LED = 0;      //报警灯亮
    DelayMs(300); //响0.3秒
    Buzzer = 1;   //关闭
    LED = 1;
}
else{
    Buzzer = 1;
    LED = 1;
}

Proteus仿真时注意:超声波模块的回波信号要手动模拟。右键Echo脚选择"Digital Stimulator",设置高低电平持续时间来模拟不同距离。实测发现当设置阈值为20cm时,模拟距离低于这个值就会触发警报,LED开始狂闪。

完整工程里还有个彩蛋:超过量程显示"--",低于2cm显示"Err"。这需要处理超声波模块的测量极限,毕竟实际使用中太近的距离测量会抽风。

最后说个血泪教训:调试时务必先接GND再上电!有次偷懒没接地线,烧了个蜂鸣器不说,1602液晶直接表演"字符消失术",那叫一个惨烈...

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐