这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【let'sdo|2026年第2期】成果帖|基于FRDM-MCXA153的简易超

共1条 1/1 1 跳转至页

【let'sdo|2026年第2期】成果帖|基于FRDM-MCXA153的简易超声波测距仪

菜鸟
2026-09-27 11:31:53     打赏

开箱帖认了板,过程帖打完了黑块那场仗,这一篇是收官:把整台测距仪的框图、接线、关键代码和实测效果一次摆全。

一、项目概述

本项目以 NXP FRDM-MCXA153 开发板(MCXA153,Cortex-M33,主频 96 MHz)为核心,搭配 HC-SR04 超声波模块和 NHD-0116AZ-FL-YBW 1×16 字符 LCD,实现一台裸机简易超声波测距仪:周期约 10 Hz 测量前方距离,LCD 实时显示 `Dist: xxx.x cm`,同时经 LPUART0(115200)打印到串口,便于对照。无 RTOS,逻辑全部在主循环 + 一个定时器中断里完成。

二、系统框图

image.png

测距链路:Trig 发 10 µs 高电平 → 模块发 40 kHz 超声 → Echo 拉高,脉宽正比距离 → CTIMER 捕获上升/下降沿算出脉宽 → 换算距离 → LCD 与串口输出。

三、电路原理图(接线表)

供电:HC-SR04、LCD 逻辑与背光均接 **J3-10 SYS_5V0(5V)**,地接 **J3-12 GND**,三者共地。

信号器件脚MCU 脚板座说明
TrigHC-SR04 TrigP1_9J2-20GPIO 输出
EchoHC-SR04 EchoP1_8J2-18经 10k/15k 分压到约 3.0V,接 CTIMER0 CAP0
RSLCD pin4P3_15J2-2GPIO 输出
R/WLCD pin5GNDJ3-12硬件接地,只写
ELCD pin6P3_14J2-4GPIO 输出,下降沿锁存
DB0~DB7LCD pin7~14P1_4/P1_5/P2_4/P3_0/P2_5/P3_12/P3_13/P3_1J18 位数据
V0LCD pin310kΩ/1kΩ 固定分压—对比度 ≈0.45V(落在 0.3~0.8V 窗口即可;有电位器也可)
LED+/LED-LCD pin15/165V / GNDJ3-10/J3-12背光约 110 mA

Echo 分压:`Echo(5V) ─ 10kΩ ─┬─ P1_8(≈3.0V)`,再经 `15kΩ` 到 GND。

V0 说明:V0 是模拟偏置脚不是逻辑电平脚,必须落在 **0.3~0.8 V**(对应 VLCD 4.2~4.7 V)。手头没有电位器,用 10kΩ+1kΩ 固定分压得到 0.45 V,一次到位;接 GND(VLCD 超上限)或接 3.3 V(VLCD 低于下限)都会看不到东西。

四、如何开启运行

1. 编译:工程基于 CMake + MCUXpresso SDK。引脚与 CTIMER 由 Config Tools(`hello_world.mex`)生成,编译入口 `CMakeLists.txt`,产物为 `.bin`。

2. 烧录:通过板载 MCU-Link,USB 连接 J15,下载固件。

3. 运行:上电后 `BOARD_InitHardware()` 完成引脚/时钟/外设初始化,`HCSR04_Init()` 启动定时器,`LCD_Init()` 初始化屏并显示 `HC-SR04 ready`,随后进入测距主循环。

4. 观察:打开串口助手(115200),开机打印 banner `HC-SR04 + LCD. Echo must be divided to ~3.0 V on P1_8.`,随后测距行格式为 `dist=x.x cm (raw y.y) echo=xxx us`(raw 是滤波前单次值,便于对照);LCD 同步显示滤波后的距离。

五、主要参数情况

参数数值
量程2~400 cm(最佳 10~250 cm)
显示分辨率0.1 cm(1 mm)
刷新率约 10 Hz(测量间隔 100 ms)
软件滤波3 点中值(有效帧入窗;连续无效保持 2 帧后刷 `--.-`)
单次测量超时30 ms(Match0)
时基CTIMER0 96 MHz ÷ 95 = 1 µs/tick
距离公式`d_cm = t_us / 58`,`mm = (t_us×10 + 29) / 58`(四舍五入)
供电器件 5V,MCU IO 3.3V


六、实现步骤与关键代码

软件分层:芯片层(mex 生成的 `pin_mux.c`/`peripherals.c`)负责"脚是什么功能",驱动层(`hcsr04.c`/`lcd_st7066u.c`)负责"按协议说话"。

① 超声状态机(`Idle→WaitRise→WaitFall→Done`),CTIMER 回调里只记时间、置标志:

void HCSR04_CtimerCallback(uint32_t flags)
    {
        if (((flags & (uint32_t)kCTIMER_Capture0Flag) != 0U) &&
            ((s_state == kHcsr04_WaitRise) || (s_state == kHcsr04_WaitFall)))
        {
            uint32_t cap = CTIMER_GetCaptureValue(HCSR04_CTIMER, HCSR04_CAPTURE);
            if (s_state == kHcsr04_WaitRise) {
                s_riseTicks = cap;
                s_state     = kHcsr04_WaitFall;
            } else {
                s_echoUs = cap - s_riseTicks;      /* 无符号减,脉宽 */
                s_valid  = (s_echoUs >= 116U) && (s_echoUs <= 30000U);
                s_state  = kHcsr04_Done;
            }
        }
        if (((flags & (uint32_t)kCTIMER_Match0Flag) != 0U) &&
            ((s_state == kHcsr04_WaitRise) || (s_state == kHcsr04_WaitFall))) {
            s_echoUs = 0U; s_valid = false; s_state = kHcsr04_Done;  /* 超时 */
        }
    }

② 主循环:发 Trig → 等完成 → 读距离 → 中值滤波 → 刷屏 + 打印:

while (1) {
        HCSR04_Start();
        while (!HCSR04_IsDone()) { }
        mm    = HCSR04_GetDistanceMm();   /* 无效返回 -1 */
        shown = DistanceFilter(mm);       /* 3 点中值,飞点剔除 */
        LCD_ShowDistance(shown);
        PRINTF("dist=%d.%d cm  (raw %d.%d)  echo=%u us\r\n", ...);
        SDK_DelayAtLeastUs(100000U, CLOCK_GetCoreSysClkFreq());
    }

③ LCD 处理 DDRAM 断点:写到第 9 字跳地址到 `0x40`,并用固定 16 字符覆盖写避免清屏闪烁。

④ 3 点中值滤波(`DistanceFilter()`):有效帧进 3 深环形缓冲取中值,孤立飞点被直接顶掉;偶发无效帧在 2 帧内沿用上次显示值防闪屏,连续第 3 帧无效则清缓冲、刷 `--.-`;缓冲未满(上电/清空后)单帧直出,行为与未滤波一致。

七、软件调试心得

这一路从超声调到 LCD、再从黑块里杀出来,攒下几条实打实的心得:

用 CTIMER 输入捕获而非 `while` 轮询读 GPIO,时间戳由硬件打,近距一百多微秒也测得准,不受写屏、打印的抖动影响。

超时靠 Match0 兜底:无目标时 Echo 可能一直为低,不能死等下降沿。

ISR 里绝不写 LCD、不打印,只更新状态变量(均 `volatile`),避免拖死捕获。

先启动定时器再发 Trig,防止近距目标 Echo 来得太快丢上升沿。

板载 RGB LED 是免费的总线监视器:DB3/DB5/DB6 与 RGB 共脚,写屏正常时灯呈青白色(总线静态停在空格 0x20 → 蓝灯+绿灯亮);若常亮纯白,说明引脚停在初始低电平、写屏代码根本没在跑——这次排查旧固件就是靠灯色发现的。

黑块排障首选"总线自检:加一个编译期开关,让十根线逐根单独拉高、串口实时报"该去 LCD 第几脚量",万用表一轮量完通断+线序+电平,比肉眼对线可靠得多。DB6 断线就是靠"pin13 量到 4.66 V"暴露的——3.3 V 推挽输出物理上给不出 4.66 V,只能是悬空泄漏电平。

八、效果演示

代码全部落地,来验货。上电后 LCD 显示 `HC-SR04 ready`,随即进入测距。对准静止目标(约 58 cm),单次测量在 58.0~59.3 cm 之间抖动(±0.7 cm,HC-SR04 典型水平),经 3 点中值滤波后 LCD 锁定单一读数,只有目标真实移动才跳变;串口同步输出 `dist=58.4 cm (raw 59.3) echo=3387 us`,滤波前后值同屏可对照。目标拉远到约 2 m,回波变间歇(约每 5 帧一次有效),滤波的保持/超时序列正确接管,LCD 不闪 `--.-`;目标完全移出量程后 3 帧内刷为 `Dist: --.- cm` 并打印超时。用尺子在 10/30/100 cm 标定,误差在可接受范围内。

image.png

lQDPJx2KS-zsFrHNA8DNBQCwy2NEqA11-14KidO2wdAzAA_1280_960.jpg

lQDPKHCJXxy-xrHNA8DNBQCwVAx8MF5KsuIKidO13gZmAA_1280_960.jpg

九、总结

这次用 MCXA153 的 CTIMER 捕获 + GPIO 模拟并口,把"超声波测距仪"完整跑通。三篇帖子从开箱、踩坑到收官,收获集中在两块:

电平边界的账要提前算。 Echo 分压、LCD R/W 接地只写、DDRAM 断点、V0 对比度窗口(0.3~0.8 V,固定电阻分压即可,没电位器也能玩)——3.3V MCU 与 5V 器件混接的每一处边界,方案阶段算清楚,比现场翻手册快得多。

黑盒排障有三板斧。板载 RGB LED 当总线活动指示(灯色即静态电平指纹)、编译期总线自检逐根扫线、用"悬空 4.66 V 不可能出自 3.3 V 推挽"这类物理判据锁定断线——DB6 断线就是这么揪出来的。

这颗 MCU 的家底还没摸完,后续还有不少可玩的:温度补偿声速(`d=t/58` 固定按 340 m/s 算,室温偏差能到 ±2%)、串口协议帧对接上位机、低功耗间歇测量,看时间慢慢填坑。感谢活动方提供的机会,代码与文档已整理,欢迎评论区交流。










共1条 1/1 1 跳转至页

回复

匿名不能发帖!请先 [ 登陆 注册 ]