STM32与US-100串口触发测距:协议、接线与代码实现

发布时间:2026/9/16 21:07:46

STM32与US-100串口触发测距:协议、接线与代码实现 简介面向STM32嵌入式开发者与物联网、自动化设备及机器人测距场景的US100超声波模块资料包重点解析利用串口UART触发模式实现非接触测距的方法。资源基于STM32微控制器覆盖串口初始化、接收中断、超声波发送与回波计时等关键环节适合希望快速上手US100模块的入门者也便于工程人员二次开发移植。包内文件共353个压缩后约14.43MB类型以C语言源码.c/.h、Keil工程文件.uvprojx/.uvoptx、编译输出.axf/.hex为主另有链接映射.map/.lst、批处理脚本.bat以及PDF/DOC说明文档和7z压缩件可辅助查阅模块手册、构建过程与综合示例目录层次清晰易于按需学习。当前已有181人浏览学习。通过该资源可掌握US100串口触发时序、距离计算公式声速×往返时间/2与STM32中断/定时器协作方式减少从零调试的工作量完整工程结构和编译产物也能帮助验证代码、排查问题是一份实用的超声波测距参考资料。1. US-100 串口触发测距到底避开哪些麻烦用 STM32 做超声波测距很多人第一反应是 HC-SR04 的 Trig/Echo 加定时器输入捕获。但如果拿到的是 US-100并且手册上明确写着“串口触发”整个设计思路就要换掉Trig 脚不再作为脉冲触发而是作为 UART 接收脚Echo 脚也不再回矩形波而是直接给出测距结果。STM32 只需在串口上发一个字节 0x55等模块回两字节距离值就出来了。这个模式对工程师最现实的价值是省掉一路定时器通道也绕开回波脉宽测量里最麻烦的低电平噪声干扰。适合那些已经有串口资源、又需要把测量周期稳定控制在几十毫秒的小系统工业料位、智能台灯、倒车雷达一类的。本文要解决的就是串口触发模式下 US-100 和 STM32 之间的接线、代码、数据格式和异常处理。2. US-100 的串口触发模式从硬件到协议2.1 两种模式如何切换模式跳线与引脚复用US-100 最常见的是四针封装VCC、Trig、Echo、GND。模块背面通常会有一个模式选择电阻或者一组可以短接的焊盘用来切换 GPIO 和串口两种工作方式。GPIO 模式下Trig 和 Echo 的行为和 HC-SR04 一致给 Trig 一个 10us 以上高电平模块自动发射 40kHz 超声波Echo 输出与距离成正比的脉宽。串口模式下Trig 和 Echo 不再是普通的输入输出脚而是被复用成 UART 接口其中 Trig 接 STM32 的 TXEcho 接 STM32 的 RX。把模块切换到串口模式这一步最容易踩坑。部分 US-100 的串口模式不是靠代码配置的而是必须改模块背面电阻或者把某个排针短接。我一般会先看模块丝印找到标有 Mode 或 UART 字样的焊盘用万用表确认电阻默认状态。如果你收到的模块是从二手渠道拆下来的背面的跳线状态可能已经被改过上电后怎么发 0x55 都没反应多半就是模式没切对。判断方法很简单上电瞬间用示波器看 Echo 引脚串口模式下它保持空闲高电平GPIO 模式下它平时是低电平。没有示波器也可以直接量静态电压串口模式下 Echo 会被模块内部上拉到高。选好模式后测距过程就变成了一次标准的串口问答。STM32 先发命令模块再回数据包。由于模块内部自带超声波发射、回波检测和时间测量逻辑MCU 端不再需要关心声速换算和脉宽测量因此 CPU 占用率会明显低于 GPIO 方案。代价是每次测量必须等模块串口把数据返回测量周期至少要在回波等待时间的基础上再加一个串口传输时间这在后面章节会专门讲。2.2 串口触发命令与返回帧格式US-100 串口模式的默认参数基本固定为 9600bps8 位数据无校验1 位停止位也就是常说的 8N1。极少数版本支持修改波特率但通常需要额外发配置命令不建议在产品里依赖这一点。模块上电后不会主动上报必须由主机发命令触发一次测量。命令和返回值可以整理成一张参数表命令字节含义返回数据长度返回内容0x55触发测距2 字节距离高字节、距离低字节单位 mm0x50触发测距并读温度3 字节距离高字节、距离低字节、温度字节0x51读取内部温度1 字节温度值部分固件支持命令 0x55 是串口触发的基础用法返回的两个字节按大端方式组合成一个 uint16_t。比如收到 0x01 0x2C去掉高字节左移 8 位0x012C 等于 300对应的距离就是 300mm也就是 30.0cm。注意单位是毫米不是厘米。如果你以前写的是 HC-SR04 的厘米值这里千万不能直接除以 10 存成浮点数应该先保留毫米值做判断在显示层再转成厘米。有些批次的 US-100 固件返回 0.1cm 单位这个差异非常害人拿到新模块后先用卷尺量一个已知距离对比一次确认单位。如果发 0x50模块会在距离之外额外返回当前环境温度温度字节的格式在不同版本里不太统一。有的直接表示摄氏度整数有的用补码表示 0.1 摄氏度精度还有部分早期模块根本不返回有效温度。我的建议是在项目初期只用 0x55温度补偿在 MCU 端用自己的传感器做不要依赖模块那颗温度测量的精度。本章后面第五节会讲到温度修正的替代方案。2.3 STM32 的接线位置与电平注意点串口模式下的接线比 GPIO 模式简单但电平匹配问题更需要注意。US-100 的 VCC 一般接 5V也允许 3.3V但 5V 供电时模块的串口输出高电平会接近 5V。STM32F103 大部分引脚不是真正的 5V 容忍引脚直接接到 Echo 脚上有两个风险一是模块输出高电平超过单片机引脚耐压长期可能损害引脚二是 STM32 的 RX 在 3.3V 电平下会把部分 5V 高电平识别成高电平偶尔会导致数据错位。可以选带 FT 标记的引脚作为 RX例如 PA10、PB11并加一个 1k 到 2.2k 的串联电阻。更稳妥的做法是在模块 Echo 和 STM32 RX 之间加一个电平转换芯片或者用两个电阻组成分压网络上面 1k下面 2k把 5V 分到 3.3V。注意这个分压只适合单向信号而 Trig 接 STM32 TX 是 3.3V 输出模块输入端一般能识别 2V 以上的高电平不需要做反向转换。接线建议如下US-100 引脚接 STM32说明VCC5V 电源距离较远时在模块端加 100uF 电解电容TrigPA9 / USART1_TX模块的串口接收端EchoPA10 / USART1_RX经电阻分压后接入注意上拉状态GNDGND必须共地否则串口通信不可靠另外要留意 US-100 测距存在盲区。官方标称量程是 2cm 到 450cm实际使用中 2cm 以内的目标容易读出飘忽不定的异常值5cm 以下不建议作为控制判断依据。传感器正前方如果有倾斜表面回波会打偏这时串口返回的是超时最大值而不是真实距离。在做首版原理图时最好把 US-100 放在远离电机、继电器和电源变压器的位置因为这些器件产生的噪声会干扰回波放大电路。3. STM32 串口触发 US-100 的最小可运行实现3.1 CubeMX 打开 USART 的关键参数用 STM32CubeMX 生成工程时先按常规流程配置时钟然后打开 USART1Mode 选择 Asynchronous波特率填 9600数据位 8奇偶校验 None停止位 1。这个配置和模块内部默认一致请不要为了“跑得更快”把波特率改成 115200除非你确认模块支持。在 CubeMX 的 NVIC 页面把 USART1 global interrupt 打开。如果只做实验可以不开中断用阻塞式收发也能跑但我建议一开始就开中断因为实际项目中测距任务往往要和按键、显示、电机控制共存阻塞等待一个回波最长可能等 20ms这段时间 CPU 干等很浪费。生成代码后HAL 库会自动初始化 huart1。串口触发 US-100 和普通串口通信有一点不一样模块要求主机先发命令然后立刻准备接收。但 US-100 的串口输出不是连续流而是测量完成后才回数据所以接收超时要设置得比声波往返时间更长。以 450cm 量程为例声速按 340m/s 计算往返大约 26ms再加上串口发送 2 字节耗时约 2ms超时设 50ms 比较保险。在 CubeMX 里没办法直接配置 Receive 超时需要自己调用 HAL 函数时传入 Timeout 参数。3.2 阻塞式发送命令并读取距离最小实现可以直接在 main 中调用 HAL_UART_Transmit 和 HAL_UART_Receive。下面这段代码演示了一个完整的测距函数#include us100.h uint8_t us100_measure_mm(uint16_t *distance_mm) { uint8_t cmd 0x55; uint8_t buf[2]; uint16_t dist 0; if (HAL_UART_Transmit(huart1, cmd, 1, 10) ! HAL_OK) { return 0; } if (HAL_UART_Receive(huart1, buf, 2, 50) ! HAL_OK) { return 0; } dist ((uint16_t)buf[0] 8) | buf[1]; if (dist 0xFFFF || dist 0x0000) { return 0; } *distance_mm dist; return 1; }调用方式是在主循环里先读一次如果返回 0 就继续读直到拿到有效距离。这里把返回值设计成是否成功的标志distance_mm 通过指针传出。HAL_UART_Transmit 的第四个参数 10 表示发送超时 10ms发送 1 个字节在 9600 波特率下大约需要 1ms超时给 10ms 足够。HAL_UART_Receive 的第三个参数是读取 2 字节第四个参数 50 表示如果 50ms 内没有收满 2 字节就放弃返回超时错误。注意这里没有对接收到的两字节做合法性判断。0xFFFF 通常代表回波超时0x0000 可能是模块上电未稳定或目标距离过近这两种值都必须过滤。如果直接把 0xFFFF 当成距离 65535mm 参与运算后续做限幅滤波时会引入巨大跳变。3.3 中断接收方式与超时看护阻塞式代码简单但在带操作系统的项目里会让任务卡住。更合适的方案是开一个接收中断每收到一个字节就进一次中断收满两字节后置位测量完成标志。参考代码如下volatile uint8_t us100_rx_buf[2]; volatile uint8_t us100_rx_index 0; volatile uint8_t us100_rx_ready 0; void us100_start_receive(void) { us100_rx_index 0; us100_rx_ready 0; HAL_UART_Receive_IT(huart1, (uint8_t *)us100_rx_buf[0], 1); } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart huart1) { if (us100_rx_index 0) { HAL_UART_Receive_IT(huart1, (uint8_t *)us100_rx_buf[1], 1); us100_rx_index 1; } else { us100_rx_ready 1; us100_rx_index 0; } } }这段代码用了一个倒装结构第一次中断收第一字节顺手启动第二次接收第二次中断收到第二字节后直接置 ready。注意不能让同一个数组元素被连续接收两次否则第二个字节会覆盖第一个字节。这里的 us100_rx_index 没有用锁保护如果 main 函数和中断同时访问它理论上会产生未定义行为。在简单裸机程序里风险不大但如果你在 FreeRTOS 中用信号量保护临界区会更安全。需要在主循环里检查超时#define US100_TIMEOUT_MS 50 static uint32_t last_cmd_time 0; uint8_t us100_result 0; uint16_t distance 0; last_cmd_time HAL_GetTick(); HAL_UART_Transmit(huart1, cmd, 1, 10); while (HAL_GetTick() - last_cmd_time US100_TIMEOUT_MS) { if (us100_rx_ready) { distance ((uint16_t)us100_rx_buf[0] 8) | us100_rx_buf[1]; us100_result 1; break; } } if (!us100_result) { us100_start_receive(); // 重新准备下一次接收 }超时看护的核心思想是发送命令后进入等待但只等一个上限时间。实际上模块没有回数据时不一定是硬件坏了可能只是这次回波太弱被模块判定为无效所以超时后不要立刻再次触发最好隔 30ms 到 50ms 再发下一次命令。超声波测距天生不能连续快速触发模块发射完第一波后需要等待余振结束间隔太短会出现串扰。4. 串口触发测距的隐藏陷阱4.1 返回长度不固定两字节和三字节协议并存串口触发 US-100 最常见的坑是协议版本不统一。你在网上找到的代码有的读取 2 字节有的读取 3 字节还有的发送 0x55 后要等 100ms 再读。这些差异不是作者写错了而是 US-100 模块本身有多个固件版本。早期版本只支持 GPIO 模式后期固件加入了温度读取返回长度从 2 字节变成了 3 字节。我一般会在代码里做一个初始化自检上电后发送 0x55如果 50ms 内收到 2 字节就把模块识别为默认协议如果收到 3 字节就按 3 字节解析。但要注意收到 3 字节时第三字节可能是温度也可能是无效填充所以不能直接丢弃了事。最稳妥的做法是先查模块背面的版本丝印再把手册上的协议抄到程序头文件里。不要轻易相信网上别人写的读取函数因为人家手里的模块和你的可能完全是两代硬件。4.2 收到数据没有应答时怎么处理有一个容易被忽略的现象模块在超量程或目标太近时可能根本不发数据也可能返回 0xFFFF。具体表现取决于固件版本。如果你的程序只调用一次阻塞接收遇到这种情况就直接超时返回下一轮又继续发命令表面看起来是“偶尔没距离”实际原因是模块进入了一种等待回波衰减的工作状态。处理办法是加入重试机制但重试不能无限循环。建议把一次有效测量限制在 3 次尝试内每次尝试间隔 60ms。如果 3 次都失败返回错误码让上层决定是报故障还是沿用最近一次有效距离。后续文章还会讲用限幅滤波把异常值挡住但底层超时处理必须先做对否则滤波算法收到的输入序列全是空洞。4.3 用限幅加均值去掉飞点US-100 串口返回的数据在静态场景下也不是每帧都稳定。拿它对着 1m 远的墙面连续读 100 次你会发现最大值和最小值之间可能差 2cm 到 3cm。这个波动来自超声波换能器的余振和空气湍流不是模块坏了。直接拿单次值做阈值判断容易在某些临界距离上输出抖动。常用的小技巧是限幅滤波加滑动平均。限幅的作用是剔除突变值如果当前值和上一次有效值之差超过 50mm就认为本次是异常帧丢弃不参与平均。滑动平均窗口取 5 到 7 次比较合适窗口太大会让移动目标测距时响应变慢。代码实现时用环形队列每次 append 新值并计算平均队列满后覆盖最旧值。4.4 常见调试环境问题CH340 驱动和串口烧写失败调试 US-100 时经常需要同时用到 STM32 的串口和 USB 转串口模块。很多新手把 USB 转串口模块直接插到 US-100 的串口上然后用串口调试助手发 0x55发现没反应排查半天发现是电脑上的 CH340 驱动装错了。CH340 在 Windows 下需要安装正确版本驱动USB 转串口模块本身不能输出 3.3V最好选择带电平标称 3.3V/5V 切换的模块并把板载跳线调到 3.3V 再连接 STM32。另外使用 STM32 串口烧写时如果 BOOT0 没有拉高或者复位电路不完善也会出现“串口烧写失败”。这和 US-100 本身无关但经常在联合调试时把问题搞混。我建议开发阶段把 US-100 接到 USART2把调试串口留在 USART1这样即使传感器出错也不影响打印日志和固件下载。5. 让 US-100 在真实项目里更可靠5.1 用 0x50 返回温度并修正声速如果你确认手头的 US-100 支持 3 字节返回可以发送 0x50 读取温度然后对距离做声速修正。空气中的声速公式是 v 331.45 0.6 * T其中 T 是摄氏度。模块内部默认按 25 摄氏度声速计算距离所以当环境温度变化 10 度时测量误差可达约 2%。这对料位检测可能无关紧要但对需要厘米级精度的测量场景就必须修正。更简单的做法是在 STM32 外挂一个 18B20 或使用片内温度传感器把测得的温度代入声速公式重新计算真实距离。因为 US-100 输出的是模块内部计算的距离它是基于固定声速的所以需要把模块读到的距离除以标准声速再乘以当前声速。注意这个修正要在毫米级整数运算里做避免浮点数开销。5.2 多路 US-100 分时触发避免串扰一个系统里接两路以上 US-100 时不能让它们同时发送 0x55。超声波信号在空气中会互相反射两个模块同时工作时其中一个可能接收到另一个模块发射的余波导致距离数据跳变。解决办法是分时触发第一路发命令后等待 30ms再触发第二路。在 STM32 上如果两路用同一个 UART 不方便可以把第二路改成 GPIO 模拟串口或者直接分配两个不同的 USART 外设。分时触发时要注意 US-100 的测量周期大约在 30ms 到 50ms两个模块交替测量的总周期不会超过 100ms对大多数应用足够。如果传感器安装距离小于 20cm尽量让它们朝不同方向发射并且不要在模块正前方放置金属反射面。5.3 异常帧输出与完整解析技巧把最后一条留给你一个能立刻上手的技巧在串口接收中断里不要只收 2 字节而是用状态机解析不定长帧。即使你的模块固定返回 2 字节状态机也能在收到 0x55 命令后自动丢弃多余字节并保证每次解析都从帧头开始。常见做法是把接收到的字节放入一个 4 字节环形缓冲区然后检查缓冲区头两个字节是否为有效距离第三字节是否为温度。这种写法能同时兼容早期 2 字节固件和后期 3 字节固件也方便以后接入其他串口传感器。代码层面可以用一个简单的字节索引计数器每收到一字节就判断当前状态超时后强制复位状态机。重点是把“等待命令下发”和“等待数据回包”分成两个状态因为 US-100 只有在收到命令后才会发数据在没有命令的空闲期收到任何字节都应该丢弃。这个状态机写好后你就不必担心模块偶尔多回一个字节导致后续所有帧错位。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/16 21:07:46

Rust实现ffmpeg:安全高效的音视频处理新选择

1. 项目背景:为什么需要纯Rust实现的ffmpeg?在音视频处理领域,ffmpeg堪称瑞士军刀级别的存在。这个开源项目几乎成了多媒体处理的代名词,从简单的格式转换到复杂的流媒体处理,ffmpeg都能胜任。但它的C语言实现也带来了…

2026/9/16 21:07:46

AI技能模块化:TypeScript + Nx 实现可插拔、可审计的Agent能力架构

1. 项目概述:一个被严重低估的“AI能力模块化”实践样本“agent-skills”这个名称乍看像某个开源库的包名,但如果你在GitHub上搜它,会发现它既不是热门明星项目,也没有铺天盖地的教程——它更像一个安静蹲在Nx单体仓库角落里的子项…

2026/9/16 22:02:55

聚合支付自助接入实战:汇付天下签名验签与回调全流程详解

做支付开发这些年,我最大的感受是:业务再急,急不过接口文档;代码再简单,绕不开密钥签名。前段时间团队接了一个商场聚合支付项目,要求在一个商户号下同时收微信、支付宝、银联云闪付,还要支持刷…

2026/9/16 22:02:55

tcpdump UDP抓包实战:过滤表达式、分片与丢包分析

抓 UDP 的包,翻车点从来不在 tcpdump 这个工具本身,而在你敲下的那一串过滤表达式,以及你对 UDP 协议栈行为的预判。我见过太多人在机器上敲了tcpdump -i eth0 udp,屏幕上哗哗刷屏,然后CtrlC一按,说一句&qu…

2026/9/16 22:02:54

Win11后台服务优化:关闭5个诊断进程,释放约1/3内存占用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/16 21:57:54

量子计算如何重塑韧性供应链优化

1. 项目背景与核心价值当全球供应链面临前所未有的不确定性时,传统物流优化方法已显疲态。去年一家跨国零售企业因单一供应商断供导致季度亏损23亿美元的事件,彻底暴露了现有供应链模型的脆弱性。而沃伦巴菲特的伯克希尔哈撒韦公司却能在同期保持供应链稳…

2026/9/16 12:52:37

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/16 0:04:09

PHP源码部署实战:从环境配置到运行情侣游戏全攻略

简介:这是一套面向情侣互动场景的PHP完整源码,集成情侣飞行棋、真心话大冒险、情趣骰子等玩法,并内置完整分销制度,可自定义多种返佣比例,源码完全开源无加密,支持微信无感自动授权登录与第三方授权&#x…

2026/9/15 14:22:53

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/15 21:31:11

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/15 11:42:23

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码