当前位置: 首页 > news >正文

用STM32F103C8T6最小系统板驱动HC-SR04超声波模块,手把手教你做个简易测距仪(附完整代码)

基于STM32F103C8T6与HC-SR04的智能测距系统开发实战

在电子设计竞赛和创客项目中,低成本高性能的解决方案总是备受青睐。STM32F103C8T6最小系统板以其出色的性价比成为学生和爱好者的首选,而HC-SR04超声波模块则是距离检测领域的经典选择。本文将带您从零开始构建一个完整的测距系统,涵盖硬件连接、软件配置到功能扩展的全过程。

1. 硬件系统搭建

1.1 元器件选型与成本控制

对于预算有限的开发者,合理的元器件选择至关重要:

  • 核心控制器:STM32F103C8T6最小系统板(蓝桥杯指定型号)

    • 72MHz主频的Cortex-M3内核
    • 64KB Flash + 20KB RAM
    • 市场价约15-25元
  • 测距模块:HC-SR04超声波传感器

    • 测量范围:2cm-400cm
    • 精度:3mm
    • 市场价约8-12元
  • 辅助元件

    • 有源蜂鸣器(报警提示)
    • LED指示灯(状态显示)
    • 杜邦线若干
    • USB转TTL串口模块(调试用)

提示:整套系统硬件成本可控制在50元以内,非常适合学生实验和竞赛项目。

1.2 电路连接详解

连接示意图如下:

STM32F103C8T6 HC-SR04 PA8 -----------> TRIG PA9 <----------- ECHO 3.3V -----------> VCC GND -----------> GND

关键连接注意事项:

  1. 供电选择:

    • 开发板可通过USB供电(5V)
    • HC-SR04工作电压5V,但ECHO信号为5V TTL
    • STM32 GPIO耐受5V电压,可直接连接
  2. 信号线处理:

    • TRIG:普通GPIO输出模式
    • ECHO:配置为输入模式,建议启用内部上拉
  3. 扩展功能连接:

    • PC13 -> LED(板载LED)
    • PB8 -> 蜂鸣器控制端

2. 软件开发环境配置

2.1 Keil工程建立

针对STM32F103C8T6的工程配置要点:

  1. 设备选择:

    Device: STM32F103C8
  2. 时钟配置:

    #define HSE_VALUE 8000000U // 外部8MHz晶振 SystemCoreClock = 72000000; // PLL输出72MHz
  3. 关键库文件:

    • CMSIS核心库
    • STM32F10x标准外设库
    • 串口printf重定向支持

2.2 定时器配置策略

使用TIM2进行高精度时间测量:

void TIM2_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; TIM_TimeBaseStructure.TIM_Prescaler = 72-1; // 1MHz计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); }

3. 核心测距算法实现

3.1 超声波驱动时序

完整的测距流程:

  1. 触发阶段:

    void TriggerPulse(void) { GPIO_SetBits(GPIOA, GPIO_Pin_8); // TRIG高电平 delay_us(20); // 维持20us GPIO_ResetBits(GPIOA, GPIO_Pin_8);// TRIG低电平 }
  2. 回波检测:

    float MeasureDistance(void) { uint32_t start_time, end_time; TriggerPulse(); while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == 0); // 等待回波高电平 start_time = TIM2->CNT; while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_9) == 1); // 等待回波结束 end_time = TIM2->CNT; return (end_time - start_time) / 58.0f; // 转换为厘米 }

3.2 数据滤波处理

针对超声波测量的波动性,采用滑动平均滤波:

#define FILTER_SIZE 5 float DistanceFilter(float new_val) { static float buffer[FILTER_SIZE] = {0}; static uint8_t index = 0; float sum = 0; buffer[index] = new_val; index = (index + 1) % FILTER_SIZE; for(uint8_t i=0; i<FILTER_SIZE; i++) { sum += buffer[i]; } return sum / FILTER_SIZE; }

4. 系统功能扩展与优化

4.1 多级报警系统实现

根据距离设置不同级别的报警:

void AlarmControl(float distance) { if(distance < 10.0f) { // 危险距离 GPIO_SetBits(GPIOB, GPIO_Pin_8); // 蜂鸣器长鸣 GPIO_ResetBits(GPIOC, GPIO_Pin_13); // LED常亮 } else if(distance < 30.0f) { // 警告距离 // 蜂鸣器间歇鸣响 static uint32_t last_tick = 0; if(HAL_GetTick() - last_tick > 200) { GPIO_ToggleBits(GPIOB, GPIO_Pin_8); GPIO_ToggleBits(GPIOC, GPIO_Pin_13); last_tick = HAL_GetTick(); } } else { // 安全距离 GPIO_ResetBits(GPIOB, GPIO_Pin_8); // 关闭蜂鸣器 GPIO_SetBits(GPIOC, GPIO_Pin_13); // LED熄灭 } }

4.2 串口数据可视化

通过串口输出格式化数据,便于调试:

void USART_SendData(float distance) { printf("当前距离: %.1fcm\n", distance); // ASCII条形图显示 uint8_t bars = (uint8_t)(distance / 5); printf("["); for(uint8_t i=0; i<20; i++) { printf(i < bars ? "=" : " "); } printf("]\r"); }

4.3 低功耗优化策略

对于电池供电的应用场景:

  1. 间歇工作模式:

    void EnterLowPowerMode(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); }
  2. 定时唤醒测量:

    void TIM3_Init(void) { // 配置TIM3为1秒间隔唤醒 TIM_TimeBaseInitTypeDef TIM_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_InitStruct.TIM_Period = 1000-1; TIM_InitStruct.TIM_Prescaler = 7200-1; // 10kHz TIM_TimeBaseInit(TIM3, &TIM_InitStruct); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn; NVIC_Init(&NVIC_InitStruct); TIM_Cmd(TIM3, ENABLE); }

5. 常见问题排查指南

在实际开发中可能会遇到以下典型问题:

现象可能原因解决方案
测量值固定为01. 接线错误
2. 触发信号不足
1. 检查TRIG/ECHO连接
2. 确保触发脉冲>10us
测量值波动大1. 电源噪声
2. 物体表面吸收
1. 增加滤波电容
2. 调整测量角度
超出测量范围1. 障碍物太远
2. 环境干扰
1. 确认在2-400cm范围内
2. 避免强声源干扰

调试技巧:

  • 使用逻辑分析仪检查TRIG和ECHO信号时序
  • 通过串口打印原始计时值辅助诊断
  • 在不同环境温度下测试(声速受温度影响)

这个项目最让我惊喜的是STM32F103C8T6的性能表现——仅用不到30%的CPU负载就能实现精确的超声波测距,同时还有充足资源可以扩展更多功能如无线传输或LCD显示。在实际测试中,只要保证供电稳定并做好简单的软件滤波,测量精度完全能满足大多数应用场景的需求。

http://www.jsqmd.com/news/519232/

相关文章:

  • 人工智能如何改变 Anthropic 的工作方式60
  • 霍尔木兹海峡:帝国黄昏的祭坛?
  • 毕业论文神器 9个一键生成论文工具测评:全流程开题报告+学术论文写作全攻略
  • 从微库配置到时钟树:STM32H750VB调试卡死全流程避坑指南(附DAP调试技巧)
  • 人工智能如何改变 Anthropic 的工作方式47
  • Linux CDC ACM驱动:从USB描述符到tty终端的协议转换之旅
  • [内容创作/微信公众号/Markdown] Neura Press:开源的 Markdown 转微信公众号内容编辑器
  • 多智能体协同编队控制:DWA与VO融合避障的实现
  • 稀有变异关联分析:负荷检验、方差分量模型与SKAT算法
  • 毕业论文神器!全学科适配的AI论文软件 —— 千笔AI
  • 10 车位三层四列立体车库:组态王 6.53 与西门子 200PLC 仿真实践
  • 54321
  • C语言OTA升级日志系统崩溃?3类隐蔽内存泄漏+5种日志竞态死锁,99%工程师从未排查过
  • 第三周 - qwerzxcv-
  • 群体基因组学基础:等位基因频谱、群体分化、选择信号检测
  • 牛场喂料机监控系统 西门子S7-200SMART PLC 与MCGS7.7通讯 带 独立仿真M...
  • 【实战】ERPS主子环网在新能源电站中的高效配置与故障恢复
  • 前端vue代码架子搭建
  • 双层停车场五车位:组态王 6.53 与西门子 S7 - 200 PLC 联机实战
  • Vue2中利用$attrs和$listeners实现el-input的高效二次封装
  • 线粒体DNA与叶绿体基因组分析:组装、异质性检测与进化研究
  • FPGA相位差检测:基于Vivado环境的7606三路采样探索
  • CentOS 8 网络管理实战:从NetworkManager未运行到网卡成功接管的完整指南
  • 快速排序(Quick Sort)
  • 2026-03-22 我国文化数字化政策主题演化与区域分布特征——基于2012—2024年政策文本计算分析
  • CODESYS双机Socket通讯实战:从零搭建PLC数据互传系统
  • Star CCM+旋风分离器后处理实战:从压力分布到流线绘制的完整流程
  • 被EdgeToEdge适配折磨疯了,谁懂!
  • 深入LLM黑盒:我是如何通过‘复制头’和‘知识FFN’找到RAG幻觉元凶的
  • 游戏开发必备技能:2D坐标系中角色移动的三角函数原理(Unity/Cocos案例)