FPGA设计里MMCM和PLL到底选哪个?结合7系列时钟架构聊聊选型与避坑
2026/4/23 18:09:43
超声波测距技术因其非接触、低成本和高可靠性,在工业检测、智能家居和机器人导航等领域广泛应用。HC-SR04作为典型的超声波测距模块,其核心原理是通过计算声波发射与回波接收的时间差来确定距离。
声波在空气中的传播速度约为343m/s(25℃时),距离计算公式为:
距离(cm) = (时间(μs) × 0.0343) / 2HC-SR04模块主要参数:
注意:实际测量时需考虑温度补偿,声速随温度变化约为0.6m/s/℃
| 组件 | 型号 | 数量 | 备注 |
|---|---|---|---|
| 单片机 | STC89C52 | 1 | 兼容AT89系列 |
| 超声波模块 | HC-SR04 | 1 | 需5V供电 |
| 显示设备 | LCD1602 | 1 | 可选数码管 |
| 晶振 | 11.0592MHz | 1 | 确保定时精度 |
| 电阻 | 10KΩ | 2 | 上拉电阻 |
| 电容 | 22pF | 2 | 晶振负载电容 |
+------------+ +------------+ +------------+ | STC89C52 | | HC-SR04 | | LCD1602 | | | | | | | | P1.0(TX)---+-------+ TRIG | | | | P1.1(RX)---+-------+ ECHO | | | | P0.0-P0.7 +-------+ D0-D7 | | | | P2.0-P2.2 +-------+ RS,RW,E | | | +------------+ +------------+ +------------+提示:ECHO引脚建议接10K上拉电阻,避免信号不稳定
#include <reg52.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int sbit TRIG = P1^0; // 触发引脚 sbit ECHO = P1^1; // 回波引脚 uint distance = 0; // 测量距离 bit measure_flag = 0; // 测量标志位 /* 定时器0初始化 */ void Timer0_Init() { TMOD |= 0x01; // 模式1,16位定时器 TH0 = 0; TL0 = 0; ET0 = 1; // 允许中断 EA = 1; // 开总中断 } /* 超声波触发函数 */ void Trigger() { TRIG = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); TRIG = 0; } /* 距离计算函数 */ uint Calculate_Distance() { uint time_us; time_us = TH0 * 256 + TL0; // 计算总时间 TH0 = 0; TL0 = 0; // 定时器清零 return (time_us * 0.017); // 计算距离(cm) } /* 主程序 */ void main() { Timer0_Init(); while(1) { Trigger(); // 发送触发信号 while(!ECHO); // 等待回波开始 TR0 = 1; // 启动定时器 while(ECHO); // 等待回波结束 TR0 = 0; // 停止定时器 distance = Calculate_Distance(); // 显示处理代码... Delay_ms(100); // 测量间隔 } }定时器配置:
中断处理逻辑:
void Timer0_ISR() interrupt 1 { measure_flag = 1; // 超时标志 }温度补偿算法:
float temp_compensation(float distance, float temperature) { float speed = 331.4 + 0.6 * temperature; // 声速公式 return distance * 343 / speed; // 补偿后距离 }测量值跳动大:
超范围测量失败:
if(measure_flag) { distance = 999; // 超范围标志 measure_flag = 0; }硬件优化:
软件优化:
滤波算法示例:
#define FILTER_LEN 5 uint median_filter(uint new_val) { static uint buffer[FILTER_LEN] = {0}; static uint index = 0; buffer[index++] = new_val; if(index >= FILTER_LEN) index = 0; // 排序取中值(省略排序代码) return buffer[FILTER_LEN/2]; }结合SG90舵机实现360°环境扫描:
void Servo_Rotate(uchar angle) { uint pulse = 500 + angle * 2000 / 180; // 产生PWM信号控制舵机 } void Radar_Scan() { for(int i=0; i<180; i+=10) { Servo_Rotate(i); Delay_ms(200); uint dist = Get_Distance(); Send_To_PC(i, dist); // 发送到上位机 } }结合红外传感器提升可靠性:
检测流程: 1. 超声波初步测距(2-400cm) 2. 红外精确测距(0-80cm) 3. 数据融合算法处理融合算法伪代码:
if(超声距离 < 50cm && 红外有效) { 最终距离 = 红外距离; } else { 最终距离 = 超声距离; }系统架构:
超声波模块 → 51单片机 → 电机驱动 → 直流电机 ↓ LCD显示核心逻辑:
void Avoid_Obstacle() { uint dist = Get_Distance(); if(dist < 20) { Stop_Motor(); Reverse(500); Turn_Random(); } else { Forward(); } }定制化方案要点:
校准程序:
void Calibration() { // 空罐校准 Save_Reference(0, Get_Raw_Value()); // 满罐校准 Wait_For_User_Input(); Save_Reference(100, Get_Raw_Value()); }实际部署中发现,在狭小空间测量时,适当降低触发频率(如500ms一次)能显著提高稳定性。对于需要快速响应的场景,可以优化中断处理流程,将测量时间缩短至50ms以内。