基于STM32F103C8T6和HC-SR04的超声波测距系统,支持实时显示、距离监控、阈值报警等功能。
- ✅ 超声波测距:HC-SR04模块,测量范围2-400cm,精度±3mm
- ✅ 实时显示:4位数码管显示距离/阈值(单位:厘米)
- ✅ 智能报警:距离超出阈值范围时蜂鸣器自动报警
- ✅ 阈值设置:支持距离上限/下限独立设置
- ✅ 按键控制:单击/双击识别,实现菜单切换和参数调节
- ✅ LED指示:指示当前工作模式
- ✅ 串口通信:实时输出距离和系统状态
- ✅ 任务调度:基于时间片的协作式多任务架构
| 组件 | 规格 | 数量 |
|---|---|---|
| MCU | STM32F103C8T6 | 1 |
| 超声波模块 | HC-SR04 | 1 |
| 数码管 | 4位共阴极 | 1 |
| 按键 | 轻触开关 | 4 |
| 蜂鸣器 | 无源蜂鸣器 | 1 |
| LED | 红/绿LED | 2 |
| 电阻 | 10KΩ, 330Ω | 若干 |
HC-SR04:
TRIG: PB8
ECHO: PB9
数码管:
段选: PA0-PA7
位选: PB0, PB1, PB10, PB11
按键: PB12-PB15
LED: PB6, PB7
蜂鸣器: PB5 (TIM3_CH2, 部分重映射)
串口: PA9(TX), PA10(RX)
定时器:
TIM2: 超声波计时(10μs中断)
TIM3: 蜂鸣器PWM(2.7kHz)
TIM4: 系统时基(1ms中断)
触发信号 (TRIG ≥10μs)
↓
发射8个40kHz超声波脉冲
↓
ECHO输出高电平(持续时间 = 超声波往返时间)
↓
距离(cm) = (时间 × 音速) / 2
= (时间 × 0.0346) / 2
测量范围:2-400cm 精度:±3mm 探测角度:15°
超声波/
├── user/
│ └── main.c # 主程序、任务调度器
├── driver/
│ ├── HCSR04.c/h # HC-SR04超声波驱动
│ ├── led.c/h # LED指示灯驱动
│ ├── key.c/h # 按键驱动(支持单击/双击)
│ ├── smg.c/h # 数码管动态扫描驱动
│ ├── beep.c/h # 蜂鸣器PWM驱动
│ └── usart.c/h # 串口通信
├── system/
│ ├── delay.c/h # 微秒级延时
│ ├── timer.c/h # 定时器配置
│ └── sys.c/h # 系统初始化
└── project/
└── LED.uvprojx # Keil工程文件
- Keil uVision5
- STM32F1xx标准外设库
- ST-Link驱动
# 1. 打开工程文件
打开 project/LED.uvprojx
# 2. 编译项目
Project -> Build Target (F7)
# 3. 下载到开发板
Flash -> Download (F8)HC-SR04模块:
VCC -> 5V(推荐使用5V供电)
TRIG -> PB8
ECHO -> PB9
GND -> GND
注意事项:
- HC-SR04推荐5V供电,3.3V可能导致测距不稳定
- ECHO输出的5V高电平可直接连接STM32(内部有保护)
- 模块前方至少2cm内不能有遮挡物
| 按键 | 单击操作 | 双击操作 |
|---|---|---|
| KEY1 | 距离显示 ↔ 阈值设置 | 距离上限 ↔ 距离下限切换 |
| KEY2 | 同KEY1单击 | 同KEY1双击 |
| KEY3 | 阈值+1 (设置模式下) | - |
| KEY4 | 阈值-1 (设置模式下) | - |
Menu 0: 显示当前距离 (默认) - LED1亮
Menu 2: 设置距离上限 - LED2亮
Menu 3: 设置距离下限 - LED2亮
距离上限:100 cm
距离下限:10 cm
采集周期:300 ms- 距离显示模式(Menu 0):距离 > 上限 或 距离 < 下限时报警
- 阈值设置模式(Menu 2/3):关闭报警
task_t sch_task[] = {
{key_proc, 10, 0}, // 按键扫描 - 10ms
{seg_proc, 20, 0}, // 数码管显示 - 20ms
{led_proc, 100, 0}, // LED指示 - 100ms
{ultrasonic_task, 300, 0}, // 超声波采集 - 300ms
{alarm_proc, 100, 0}, // 报警检测 - 100ms
{uart_proc, 500, 0} // 串口回显 - 500ms
};int16_t sonar_mm(void)
{
// 1. 发送10μs触发信号
GPIO_WriteBit(GPIOB, Trig, 1);
delay_us(15);
GPIO_WriteBit(GPIOB, Trig, 0);
// 2. 等待ECHO高电平
while(GPIO_ReadInputDataBit(GPIOB, Echo) == 0);
// 3. 开始TIM2计时
time = 0;
// 4. 等待ECHO低电平
while(GPIO_ReadInputDataBit(GPIOB, Echo) == 1);
// 5. 计算距离
Distance = (time_end * 346) / 2; // time单位:10μs
Distance_mm = Distance / 100;
return Distance_mm;
}// TIM3部分重映射:CH2 -> PB5
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
// PWM频率:72MHz / 72 / 370 ≈ 2.7kHz
TIM_TimeBaseStructure.TIM_Period = 369;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
// 开启报警:50%占空比
TIM_SetCompare2(TIM3, 180);
// 关闭报警
TIM_SetCompare2(TIM3, 0);// 每10μs触发一次中断
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
{
time++;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}| 实际距离 | 测量值 | 误差 | 误差率 |
|---|---|---|---|
| 5 cm | 5 cm | 0 cm | 0% |
| 50 cm | 51 cm | +1 cm | 2% |
| 100 cm | 101 cm | +1 cm | 1% |
| 200 cm | 203 cm | +3 cm | 1.5% |
| 300 cm | 295 cm | -5 cm | 1.7% |
- 采集周期:300ms
- 单次测距:20-30ms
- 报警延迟:<100ms
| 测试条件 | 稳定性 | 备注 |
|---|---|---|
| 室内静止 | 优秀 | 波动±1cm |
| 移动目标 | 良好 | 需要滤波 |
| 软质表面 | 较差 | 反射弱 |
| 倾斜>15° | 不稳定 | 超出探测角 |
复用温湿度采集项目的代码框架:
- ✅ 任务调度器
- ✅ 按键驱动(单击/双击)
- ✅ 数码管驱动
- ✅ LED/串口驱动
- TIM2:10μs精确计时,用于超声波往返时间测量
- TIM3:PWM输出,驱动蜂鸣器
- TIM4:1ms系统时基,任务调度器基准
// TIM3部分重映射配置
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
// 重映射后:TIM3_CH2 从 PA7 -> PB5原因:
- HC-SR04供电电压不足
- 环境噪声干扰
- 测量表面不平整
解决方案:
- 使用5V稳定电源供电
- 添加软件滤波(中值滤波/均值滤波)
- 限幅处理:
if(distance > 400) distance = 400;
检查清单:
- TIM3时钟已使能
- GPIO重映射已配置
- PB5配置为复用推挽输出
- 使用
TIM_SetCompare2(不是Compare1) - 占空比非0
原因:
- HC-SR04盲区(<2cm)
- TRIG/ECHO引脚接反
解决方案:
- 确保测量距离≥2cm
- 检查接线:TRIG->PB8, ECHO->PB9
可以在此基础上实现:
- 非阻塞式测距(外部中断+输入捕获)
- 数字滤波算法(中值/卡尔曼)
- 温度补偿(提高精度)
- LCD显示距离曲线
- 多目标检测
- 语音播报距离
- 低功耗模式
# 波特率:115200
# 输出示例:
Distance: 25 cm, Menu: 0, LED1: 1, LED2: 0, Alarm: OFF
Distance: 102 cm, Menu: 0, LED1: 1, LED2: 0, Alarm: ON抓取TRIG/ECHO波形,验证时序:
- TRIG脉宽:≥10μs
- ECHO高电平时间 = 距离(cm) × 58μs
测量PWM波形:
- 频率:约2.7kHz
- 占空比:0%(静音)/ 50%(报警)
欢迎提交Issue和Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/NewFeature) - 提交更改 (
git commit -m 'Add NewFeature') - 推送到分支 (
git push origin feature/NewFeature) - 打开Pull Request
本项目采用 MIT 许可证 - 详见 LICENSE 文件
- CSDN:详细技术博客
感谢所有为本项目提供帮助的老师和同学!
如果这个项目对你有帮助,请给一个⭐️Star支持一下!
