一、本期进展
开箱帖发完之后,花了两天时间把开发环境搭好,并且完成了项目的第一步核心功能:
✅ HC-SR04 超声波模块驱动(Trig 触发 + Echo 输入捕获测脉宽)
✅ 距离计算与串口回显
✅ 200 ms 周期循环测量
这篇帖子就把整个移植过程中的硬件接线、软件思路、踩坑记录整理一下,给后面还在搭环境的朋友做个参考。
二、在MCUXpresso Congfic中初始化外设
如图所示:

| Capture0 | 上下边沿捕获 | 计算脉冲宽度 |
| Match0 | 定时触发中断 | 实现超时计数 |
三、软件设计思路
整个超声波测距的软件流程非常经典,分三步:
触发:MCU 给 Trig 引脚一个 ≥10 μs 的高电平脉冲,启动测距
等待回响:HC-SR04 自动发射 8 个 40 kHz 超声波脉冲,遇到障碍物后反射
测脉宽:Echo 引脚输出一段高电平,高电平持续时间 = 声波往返时间
算距离:距离(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");
}五、验证结果

▲ 串口回显的测距数据
八、下一步计划
超声波驱动已经跑通,串口数据也稳定了,下一步就该接 LCD 屏幕了。
过程帖就到这里,成果帖见~
我要赚赏金
