这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » FRDM-MCXA153超声波驱动移植与串口回显调试

共1条 1/1 1 跳转至页

FRDM-MCXA153超声波驱动移植与串口回显调试

菜鸟
2026-10-04 23:50:50     打赏

一、本期进展

开箱帖发完之后,花了两天时间把开发环境搭好,并且完成了项目的第一步核心功能:

  • ✅ HC-SR04 超声波模块驱动(Trig 触发 + Echo 输入捕获测脉宽)

  • ✅ 距离计算与串口回显

  • ✅ 200 ms 周期循环测量

这篇帖子就把整个移植过程中的硬件接线、软件思路、踩坑记录整理一下,给后面还在搭环境的朋友做个参考。


二、在MCUXpresso Congfic中初始化外设

如图所示:

屏幕截图 2026-10-04 220256.png

引脚模式功能
Capture0上下边沿捕获计算脉冲宽度
Match0定时触发中断实现超时计数

三、软件设计思路

整个超声波测距的软件流程非常经典,分三步:

  1. 触发:MCU 给 Trig 引脚一个 ≥10 μs 的高电平脉冲,启动测距

  2. 等待回响:HC-SR04 自动发射 8 个 40 kHz 超声波脉冲,遇到障碍物后反射

  3. 测脉宽:Echo 引脚输出一段高电平,高电平持续时间 = 声波往返时间

  4. 算距离:距离(cm) = 高电平时间(μs) × 0.034 / 2

四、核心代码片段

下面这段是超声波驱动的核心逻辑,包含 Trig 触发、CTIMER 捕获中断处理和距离计算:

static void HCSR04_TriggerMeasurement(void)
{
    s_risingCapture = 0U;
    s_pulseWidthTicks = 0U;
    s_hcsr04State = kHcsr04WaitingForRise;

    CTIMER_StopTimer(HCSR04_CAPTURE_TIMER);
    CTIMER_Reset(HCSR04_CAPTURE_TIMER);
    CTIMER_ClearStatusFlags(HCSR04_CAPTURE_TIMER,
                            HCSR04_TIMEOUT_FLAG | HCSR04_CAPTURE_FLAG);
    CTIMER_StartTimer(HCSR04_CAPTURE_TIMER);

    GPIO_PinWrite(HCSR04_TRIGGER_GPIO, HCSR04_TRIGGER_PIN, 1U);
    SDK_DelayAtLeastUs(10U, SystemCoreClock);
    GPIO_PinWrite(HCSR04_TRIGGER_GPIO, HCSR04_TRIGGER_PIN, 0U);
}

/* Called from the CTIMER0 driver callback for Match 0. */
void TimeOut(uint32_t flags)
{
    if (((flags & HCSR04_TIMEOUT_FLAG) != 0U) &&
        ((s_hcsr04State == kHcsr04WaitingForRise) ||
         (s_hcsr04State == kHcsr04WaitingForFall)))
    {
        s_hcsr04State = kHcsr04TimedOut;
        CTIMER_StopTimer(HCSR04_CAPTURE_TIMER);
    }
}

/* Called from the CTIMER0 driver callback for Capture 0 (both edges). */
void HCSR04_Edge(uint32_t flags)
{
    uint32_t capture;

    if (((flags & HCSR04_CAPTURE_FLAG) == 0U) ||
        ((s_hcsr04State != kHcsr04WaitingForRise) &&
         (s_hcsr04State != kHcsr04WaitingForFall)))
    {
        return;
    }

    capture = CTIMER_GetCaptureValue(HCSR04_CAPTURE_TIMER, HCSR04_CAPTURE_CHANNEL);
    if (s_hcsr04State == kHcsr04WaitingForRise)
    {
        s_risingCapture = capture;
        s_hcsr04State = kHcsr04WaitingForFall;
    }
    else
    {
        s_pulseWidthTicks = capture - s_risingCapture;
        s_hcsr04State = kHcsr04Complete;
        CTIMER_StopTimer(HCSR04_CAPTURE_TIMER);
    }
}

主循环里就是每 200 ms 调用一次 ultra_start_measure(),然后等 ULTRA_MEASURE_DONE 状态,算出距离后 printf 到串口:

HCSR04_TriggerMeasurement();

        /* Keep a 200 ms trigger period; CTIMER interrupts handle capture/timeout. */
        SDK_DelayAtLeastUs(HCSR04_MEASURE_INTERVAL_US, SystemCoreClock);

        /* Fail safe if the expected 30 ms match interrupt did not arrive. */
        if ((s_hcsr04State == kHcsr04WaitingForRise) ||
            (s_hcsr04State == kHcsr04WaitingForFall))
        {
            CTIMER_StopTimer(HCSR04_CAPTURE_TIMER);
            s_hcsr04State = kHcsr04TimedOut;
        }

        if (s_hcsr04State == kHcsr04Complete)
        {
            /* distance in tenths of a centimeter: ticks * 343 / 192,000 */
            uint32_t distanceTenthsCm = (s_pulseWidthTicks * 343U) / 192000U;
            PRINTF("Echo pulse: %u ticks, distance: %u.%u cm\r\n",
                   (unsigned int)s_pulseWidthTicks,
                   (unsigned int)(distanceTenthsCm / 10U),
                   (unsigned int)(distanceTenthsCm % 10U));
        }
        else
        {
            PRINTF("HCSR04 timeout (>30 ms)\r\n");
        }

五、验证结果

屏幕截图 2026-10-04 223913.png

▲ 串口回显的测距数据


八、下一步计划

超声波驱动已经跑通,串口数据也稳定了,下一步就该接 LCD 屏幕了。

过程帖就到这里,成果帖见~



共1条 1/1 1 跳转至页

回复

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