通过串口向电脑传送数据
硬件准备
NXP FRDM-MCXA153 开发板 1 块
上位机电脑 1 台
开发环境说明
本次活动我尝试使用 Zephyr 进行开发,在 Zephyr 官方恰好有本次活动的开发支持。基于 Zephyr 可以非常简单地实现与上位机的串口通信。只需要新建工程后配置启动 Console 即可。
代码实现
prj.conf 配置串口使能
CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y CONFIG_UART_MCUX_LPUART=y
Zephyr 串口输出日志
LOG_INF("[DBG][seq=%" PRIu32
"] echo=%" PRIu32 " us raw=%" PRIu32
" mm median=%" PRIu32 " mm filtered=%" PRIu32
" mm state=%s err=%" PRId32,
data.sequence, data.echo_time_us,
data.raw_distance_mm, data.median_distance_mm,
data.filtered_distance_mm,
ranging_state_name(data.state), data.error_code);效果展示

MCU读取超声波模块数据并传到上位机上
结构与工作原理

工作原理时序

外部 微控制器 向 TRIG 引脚发送一个至少 10μs 的高电平脉冲,触发模块发射超声波。
超声波发射头发射超声波信号。
超声波在空气中传播,遇到障碍物后反射回来,被超声波接收头接收并转换为电信号。
接收信号经过放大、滤波和整形后,从 ECHO 引脚输出一个高电平信号,其持续时间与超声波的传播时间成正比。
外部微控制器通过测量 ECHO 引脚高电平的持续时间,并根据超声波的传播速度(在空气中约为 340 m/s),计算出障碍物与模块之间的距离。距离 = 高电平时间*声速(340 M/S)/ 2
声速与温度补偿

硬件准备
NXP FRDM-MCXA153 开发板 1 块
HC-SR04 超声波距离传感器模块 1 块
Arduino 传感器拓展板 1 块
杜邦线 若干
上位机电脑 1 台
为了方便接线,我将 HC-SR04 超声波距离传感器模块 连接到了 Arduino 接口的 IIC 接口,HC-SR04 的 Trig 引脚接到 Arduino 的 D15,Echo 引脚接到 Arduino 的 D14。如下图所示:

代码实现
// 触发测量
ret = gpio_pin_set_dt(&trig_gpio, 1);
if (ret != 0) {
measurement_active = false;
return ret;
}
// 维持触发测量高电平时长
k_busy_wait(APP_TRIG_PULSE_US);
// 触发测量结束,重置 Trig 引脚为低电平
ret = gpio_pin_set_dt(&trig_gpio, 0);
if (ret != 0) {
measurement_active = false;
return ret;
}
// 等待测量完成信号量
ret = k_sem_take(&echo_complete,
K_MSEC(CONFIG_APP_HCSR04_ECHO_TIMEOUT_MS));
if (ret != 0) {
key = irq_lock();
measurement_active = false;
waiting_for_rise = true;
irq_unlock(key);
return -ETIMEDOUT;
}
// 计算测量结果下降沿和上升沿时长
pulse_cycles = (uint32_t)(fall_cycle - rise_cycle);
pulse_us = k_cyc_to_us_floor64((uint64_t)pulse_cycles);
if (pulse_us > UINT32_MAX) {
return -ERANGE;
}
*echo_time_us = (uint32_t)pulse_us;
// 计算距离,单位 mm。
*distance_mm = (uint32_t)((pulse_us * 343U) / 2000U);效果展示

MCU与显示屏通信并使其显示数字
硬件准备
NXP FRDM-MCXA153 开发板 1 块
M5Stack StickS3 开发板 1 块
Arduino 传感器拓展板 1 块
杜邦线 若干
上位机电脑 1 台
这里我使用了一个 M5Stack StickS3 开发板作为显示器显示距离数据,我使用 M5Stack StickS3 开发板的 Grove 接口作为串口,读取串口距离数据进行显示。
// 测距仪结果帧:DIST,<序列号>,<距离mm|INVALID>,<状态> DIST,125,248,NORMAL DIST,126,INVALID,TIMEOUT
代码实现
auto& d = M5.Display;
const char* unitText = (currentUnit == UNIT_CM) ? "cm" : "mm";
float shownDistance = (currentUnit == UNIT_CM)
? (latestDistanceMm / 10.0f)
: latestDistanceMm;
char valueBuf[24];
if (hasValidData) {
snprintf(valueBuf, sizeof(valueBuf), "%.2f %s",
shownDistance, unitText);
} else {
snprintf(valueBuf, sizeof(valueBuf), "--.-- %s", unitText);
}
// 数值使用等宽粗体,宽度超出屏幕时自动缩小
d.setTextFont(&fonts::FreeMonoBold18pt7b);
d.setTextSize(1.0f);
float rawWidth = d.textWidth(valueBuf);
float scale = 1.0f;
float maxWidth = static_cast<float>(d.width()) - 12.0f;
if (rawWidth > maxWidth) {
scale = maxWidth / rawWidth;
}
d.setTextSize(scale);
d.setTextDatum(middle_center);
d.setTextColor(TFT_WHITE, TFT_BLACK);
// 擦除数值区域,防止位数变短时残留旧字符
d.fillRect(0, d.height() / 2 - 24, d.width(), 48, TFT_BLACK);
d.drawString(valueBuf, d.width() / 2, d.height() / 2);效果展示


我要赚赏金
