这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 【2026Let'sdo第2期】简易超声波测距仪实践成果帖

共1条 1/1 1 跳转至页

【2026Let'sdo第2期】简易超声波测距仪实践成果帖

助工
2026-10-10 00:12:53     打赏

【2026Let'sdo第2期】简易超声波测距仪实践成果帖

一、项目介绍

项目采用 NXP FRDM-MCXA153 开发板、HC-SR04 超声波模块,SSD1306 OLED 显示屏,实现简易测距并在 OLED 上显示距离值。目前测距和显示两块底层已经跑通,不过还在面包板上飞线。

系统框图.png


软件使用 MCUXpresso IDE 开发。

二、硬件连接

FRDM-MCXA153HC-SR04OLED备注
+3.3VVCCVCCOLED 用 3.3V
GNDGNDGND
P3_15Trig
飞线
P3_14Echo
经电阻分压后接入
P1_0
SCL软件 I2C
P1_1
SDA软件 I2C

三、主要参数

HC-SR04 超声波模块:工作电压 5V DC,测距范围 2cm 至 400cm,测距精度 ±3mm,超声波频率 40kHz,感应角度不大于 15 度。

SSD1306 OLED:128×64 点阵,I2C 接口,3.3V 供电。

四、工作原理与测距计算

1、单片机给 Trig 引脚发送至少 10µs 的高电平脉冲触发测距。

2、模块自动发送 8 个 40kHz 超声波脉冲。

3、超声波遇到障碍物反射后被接收器检测。

4、Echo 引脚输出高电平,持续时间与超声波往返时间成正比。

距离计算公式:声速在空气中约 340m/s(常温下),距离 =(高电平时间 × 声速)÷ 2,除以 2 是因为声波走了往返路程。简化公式:距离(cm) = 高电平时间(µs) ÷ 58。

五、软件配置

HC-SR04 触发引脚配置为 GPIO 输出,Echo 配置为 GPIO 中断,上升沿和下降沿都触发。定时器用 CTimer,配成计数器每微秒走一格,读出来直接是微秒数。

SSD1306 用软件 I2C 驱动,GPIO 手动模拟时序。显存开一块 1024 字节的缓冲区,按页刷新。

测出来的数据先做五点中值滤波,再做一阶滞后滤波平滑。

按键用非阻塞轮询,一毫秒查一次,二十五毫秒消抖,下降沿触发一次。SW3 切单位,SW2 切显示样式。

六、超声波测距代码

触发时序:

static void trig_pulse(void)
{
    GPIO_PinWrite(TRIG_GPIO, TRIG_PIN, 0U);
    for (volatile uint32_t i = 0; i < 20; i++) __NOP();
    GPIO_PinWrite(TRIG_GPIO, TRIG_PIN, 1U);
    for (volatile uint32_t i = 0; i < 100; i++) __NOP();
    GPIO_PinWrite(TRIG_GPIO, TRIG_PIN, 0U);
}

Echo 中断里上升沿清计数器,下降沿读计数值:

void GPIO3_IRQHandler(void)
{
    GPIO_GpioClearInterruptStatusFlags(GPIO3, 1U << ECHO_PIN);
    if (GPIO_PinRead(ECHO_GPIO, ECHO_PIN)) {
        CTIMER_Reset(CTIMER0);
        CTIMER_StartTimer(CTIMER0);
    } else {
        echo_count = CTIMER_GetCurrentTimerCount(CTIMER0);
        CTIMER_StopTimer(CTIMER0);
        echo_ready = 1;
    }
}

测距主循环加超时,没回波直接返回:

static uint32_t ultrasonic_measure(void)
{
    echo_ready = 0;
    trig_pulse();
    uint32_t t0 = systick_ms;
    while (!echo_ready) {
        if (systick_ms - t0 > 30) return 0;
    }
    return echo_count / 58;
}

七、软件 I2C 代码

static void i2c_delay(void)
{
    for (volatile uint32_t i = 0; i < 8; i++) __NOP();
}

static void i2c_start(void)
{
    sda_high(); scl_high(); i2c_delay();
    sda_low();  i2c_delay();
    scl_low();  i2c_delay();
}

static uint8_t i2c_write_byte(uint8_t data)
{
    for (uint8_t i = 0; i < 8; i++) {
        scl_low();
        if (data & 0x80) sda_high(); else sda_low();
        data <<= 1;
        i2c_delay();
        scl_high();
        i2c_delay();
    }
    scl_low();
    sda_dir_input();
    i2c_delay();
    scl_high();
    i2c_delay();
    uint8_t ack = sda_read();   /* 0 表示从机应答 */
    scl_low();
    sda_dir_output();
    i2c_delay();
    return ack;
}

八、开启运行

1、硬件连接按上文接线表接好,USB 线连接板载 MCU-Link 调试口到 PC。

2、MCUXpresso IDE 打开工程,编译下载。

3、Debug 运行,观察 OLED 显示。

4、按键 SW3 切单位,SW2 切显示样式。

九、效果展示

5fb0944b5354aa272e02775768872e0c

QQ_1791562332585.png


共1条 1/1 1 跳转至页

回复

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