这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【let'sdo|2026年第2期】简易超声波测距仪-成果贴:设计调试与功能演示

共1条 1/1 1 跳转至

【let'sdo|2026年第2期】简易超声波测距仪-成果贴:设计调试与功能演示

菜鸟
2026-09-14 13:32:58     打赏

在过程贴中我们已经完成了OLED和HC-SR04的模块化写法,下面就是具体的实现步骤与功能演示。

1.系统框图详情

本项目采取基于FRDM-MCXA153开发板,外接超声波测距模块和0.96寸i2cOLED屏幕,以实现测距及显示功能,测距可精确到0.1cm,在OLED在显示的同时,也可通过J15板载调试串口COM5发送数据到电脑端。系统框图如下屏幕截图 2026-09-14 124540.png

2.电路原理图

根据电路 原理图,我们可以很清晰的知道电路的连接关系

屏幕截图 2026-09-14 125152.png

3.主要引脚参数的具体配置和注意事项


在HC-SR04.c和HC-SR04.h中先写到对HC-SR04进行驱动,trig发送一个至少10us的高电平脉冲,后用CTIMER0(1MHz自由 运行定时器)测量echo高电平脉宽,除以58得到厘米(cm)。

在ssd1306.c和ssd1306.h中先对其进行驱动,LPI2C0通信+128*64帧缓冲+5*7点阵字库。

而后在pin_mux.c和pin_mux.h中进行引脚配置,trig(P3_15)输出,echo(P3_1)输入,SDA(P3_28),SCL(P3_27)占用LPI2C0外设。还得在hardware_init.c中挂起LPI2C0的时钟,CTIMER0的时钟,务必在prj.conf中加入driver.Ctimer和driver.lpi2c两个组件,不加会导致编译错误,缺少驱动driver。还需把新创建的文件在CMakeLists.txt中加入文件路径。

屏幕截图 2026-09-14 122712.png

4.如何开启运行

首先确认硬件本身功能是否完好,而后检查接线是否正确。后打开Vscode,我是使用的官方提供的vscode扩展进行开发。正常按照扩展之后,左侧栏会出现一个X的标识,我们右键所开发的工程文件,即可完成编译烧录的工作。而后屏幕会出现一秒钟的白屏,串口会有以下输出。


5.实现步骤

步骤 1:建立工程骨架

以 SDK 的 `driver_examples/gpio/led_output` 示例为基础复制工程,

在 `CMakeLists.txt` 的 `mcux_add_source()` 中登记自己新增的源文件:

SOURCES main.c

        hc_sr04.c

        ssd1306.c


步骤 2:规划并配置引脚与外设

1. 选定各功能所用引脚(见 2.3),确保互不冲突。

2. 在 `frdmmcxa153/led_output/pin_mux.c` 的 `BOARD_InitPins()` 中;

   - 使能对应 PORT 时钟:`CLOCK_EnableClock(kCLOCK_GatePORTn)`

   - 释放对应 PORT 复位:`RESET_ReleasePeripheralReset(kPORTn_RST_SHIFT_RSTn)`

   - 释放 外设自身复位(LPI2C0、GPIO3 等)

   - 用 `PORT_SetPinConfig()` 设置每个引脚的复用值、上下拉、方向

3. 在 `frdmmcxa153/led_output/hardware_init.c` 中把 **FRO12M** 分别接到

   LPI2C0 和 CTIMER0,并设置分频。


步骤 3:实现 HC-SR04 驱动

1. `HCSR04_Init()`

   - 把 TRIG 配成输出、ECHO 配成输入

   - 把 CTIMER0 配成 1 MHz 自由运行计数器(prescale = 11)

2. `HCSR04_MeasureEchoUs()`

   - 发 20 µs 触发脉冲

   - 轮询等 ECHO 上升沿 → 记下 `tStart`

   - 轮询等 ECHO 下降沿 → 记下 `tEnd`

   - 两个等待各自带超时计数,超时返回约定的错误码

   - `tEnd - tStart` 即为高电平时长,并对 32 位回绕做补偿

3. `HCSR04_GetDistanceCm()` —— 时长 ÷ 58 得到厘米数


步骤 4:实现 SSD1306 驱动

分三层,自底向上实现:

第一层:I2C 通信

SSD1306_Init()` 里配置并启动 LPI2C0

ssd1306_send_command()` —— 发送控制字节 `0x00` + 命令

ssd1306_send_data()` —— 发送控制字节 `0x40` + 显存数据

ssd1306_probe_address()` —— 地址探测(起始 + 地址 + 1 字节 + 停止,取返回状态)

第二层:显存与刷新

- 定义与屏幕同构的帧缓冲 `s_framebuffer[8][128]`

  (每个字节纵向装 8 个像素,bit0 是该页最上面一行)

- `SSD1306_Update()`:先设列范围 `0x21`、页范围 `0x22`,

  再整块推送 1024 字节。

  水平寻址模式下地址会自动递增,因此只需设置一次地址窗口

第三层:字符绘制

- 建 5×7 点阵字库表

- `ssd1306_draw_char()`:逐行逐列取字形位 → 按 `scale` 放大 →

  按 `[py/8][px]` 定位、`1 << (py%8)` 置位 → 边界检查

- `SSD1306_DrawString()`:逐字符调用,每字符右移 `6 × scale` 像素

初始化命令序列(顺序不可随意调换):

```

0xAE          关显示(避免配置中途闪出乱码)

0xD5 0x80     时钟分频 / 振荡频率

0xA8 0x3F     扫描行数 = 64

0xD3 0x00     显示偏移 = 0

0x40          起始行 = 0

0x8D 0x14     使能电荷泵  ← 漏掉此项屏幕全黑,但 I2C 通信正常

0x20 0x00     水平寻址模式

0xA1          段重映射

0xC8          COM 反向扫描

0xDA 0x12     COM 引脚硬件配置

0x81 0xCF     对比度

0xD9 0xF1     预充电周期

0xDB 0x40     VCOMH 电平

0xA4          恢复显示(按显存内容)

0xA6          正常显示(非反色)

0xAF          开显示

```


步骤 5:主程序整合

1. `BOARD_InitHardware()` —— 时钟、引脚、串口

2. 红灯闪 3 次 —— 确认程序确实在运行(与串口、屏幕无关的独立指示)

3. `HCSR04_Init()`

4. `SSD1306_Init()` —— **返回值存入 `oledReady`,失败时仅跳过刷屏

5. 进入主循环(见第四节)


 步骤 6:调试与验证

- 加入 HardFault 异常处理器,打印 CFSR / HFSR / MMFAR / BFAR 和出错 PC

- 加入 I2C 总线扫描,在地址不应答时区分"地址不对"与"设备不在总线上"

- 加入引脚电平采样与寄存器转储,用于判定故障在总线侧还是控制器侧

- OLED 初始化成功后做 1 秒全屏白屏自检。

346ede992930d435003d6e3120d509ce.jpg



本期活动的全部设计就差不多结束了,后面可以会加上中值和EMA滤波滤除一些野值,也可以使用开发板进行其他的项目设计,因为其的外设功能非常丰富。





关键词: 超声波     测距仪     FRDM-MCXA153     成果         

共1条 1/1 1 跳转至

回复

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