一、项目背景
基于 NXP FRDM-MCXA153 开发板(MCXA153,Cortex-M33)实现一个经典入门项目:超声波测距与屏幕实时显示。
功能需求:每秒测距两次,LCD 显示 Dist: 123.4 cm,同时通过串口上传数据。
硬件清单:
FRDM-MCXA153 开发板
HC-SR04 类超声波模块(型号 3942)
NHD-0116AZ 字符 LCD(HD44780 兼容,16×1)

两个模块均通过杜邦线连接至电源。LCD 的 V0 接 10kΩ 电位器调节对比度,背光串接限流电阻后接 5V;本实验使用另一块开发板提供 5V 供电。

三、软件设计
工程基于 MCUXpresso SDK 裸机框架,用户代码位于 source 目录下。
app_delay.h:延时与计时基于 DWT->CYCCNT 周期计数器实现,提供 APP_DelayUs、APP_DelayMs、APP_GetTick、APP_Elapsed。不占用定时器外设,也不需要中断。
ultrasonic.c/h:Trig 输出 10µs 高电平脉冲,随后轮询 Echo,使用 DWT 计数测量高电平脉宽,按 时间(µs) × 0.0343 cm/µs ÷ 2 换算距离;超时 60ms 返回 -1.0f,表示无回波。
lcd1602.c/h:4 位数据总线、只写模式驱动。
NXP.c:主循环每 500ms 测量一次,刷新 LCD,并通过 LPUART0(115200)PRINTF 输出数据。
四、调试问题与解决方案
Echo 始终读到 0
MCXA153 外设上电后处于复位保持状态,使用 GPIO 前必须调用 CLOCK_EnableClock() 与 RESET_ReleasePeripheralReset()。
此外,PORT_SetPinMux() 仅设置 MUX,不会使能输入缓冲 IBE。必须改用 PORT_SetPinConfig(),并将 inputBuffer 设为 kPORT_InputBufferEnable,否则 GPIO_PinRead() 恒为 0。该问题排查耗时较长。
LCD 仅显示 8 个方块
NHD-0116AZ 使用 ST7066U,1/16 Duty,内部 DDRAM 为 8×2 结构:物理第 1~8 列对应 0x00~0x07,第 9~16 列对应 0x40~0x47。
因此 Function Set 必须使用 0x28(4 位 / 2 行,N=1);若使用 0x20,控制器只扫描 COM0~7,右半边无信号。驱动中在第 8 列自动切换 DDRAM 地址以解决该问题。
按复位键后屏幕内容随机
根因:复位释放到 LCD_Init() 之间存在 1~3ms 总线悬空。E 为下降沿锁存,噪声产生一个边沿即可能被当作“写数据”,随机字节进入 DDRAM。
软件上在 main() 第一句加入 LCD_BusIdle(),将窗口缩短至 0.3ms;根治需依靠硬件,在 E 和 RS 上各加 10kΩ 下拉到 GND。
延时基准不可信
BOARD_InitBootClocks() 为空函数,系统运行在复位默认时钟,而 SystemCoreClock 只是 C 语言初值,从未与寄存器校验。一旦不一致,所有延时将按比例缩放,LCD 时序直接不达标。
解决方法:在 APP_InitDelay() 中先调用 SystemCoreClockUpdate()。
五、最终效果
上电后 LCD 稳定显示 Dist: xx.x cm。手掌在 5~150cm 范围内移动时,读数跟随流畅,无明显跳变;超出量程或无回波时显示 Dist: ---- cm,串口同步打印 Distance: ---- cm。

六、小结
该项目代码量不到 500 行,但覆盖了嵌入式入门中容易出错的若干问题:外设复位释放、输入缓冲配置、复用功能与时序、时钟基准校验、5V/3.3V 电平兼容。
建议初学者在进行 GPIO 采集类实验时,先单独验证“读数是否真实”,例如将 Echo 脚接 3.3V,确认 GPIO_PinRead 能读到 1,再叠加算法,可显著减少调试时间。
我要赚赏金
