一、硬件介绍
1、产品特点
FRDM-MCXA153是一款NXP推出的基于Arm Cortex-M33内核(96MHz)开发板,搭载128KB带ECC纠错Flash与32KB SRAM,板载MCU-Link高速调试器,双USB‑C分别用于调试通信与设备功能,集成RGB指示灯、PMOD接口、用户按键、温度传感器等资源;

主要特性
内核:Arm Cortex-M33(96MHz),无FPU / TrustZone
Flash:128KB(ECC 校验,1 位纠错、2 位检错)
SRAM:32KB,其中8KB 支持 ECC
芯片运行功耗:59μA/MHz
掉电模式(SRAM 全保留):6.5μA
深度掉电休眠:0.39μA(394nA)
集成 MCU-Link 片上调试器(主控 LPC55S69)
RGB三色LED
3个用户按键(Reset、WakeUp、ISP)
I3C/I2C 数字温度传感器(P3T1755)
系统框图

2、引脚示意图

3、超声波测距模块
Unit Ultrasonic-IO 是一款GPIO接口的超声波测距传感器;
硬件采用RCWL-9620超声波测距单芯片搭配16mm探头,能够实现2cm-450 cm范围内的精准测距;

主要特性

二、环境搭建
详见【快速环境搭建】

三、功能实现
1、硬件搭建
将超声波测距模块连接到开发板的PMOD接口的对应引脚上;

实物搭建效果:


2、功能效果
效果:MCU读取超声波模块检测到的数据,并通过板载的MCU-Link串口,发送至串口助手上进行实时显示;
超声波模块工作原理
通过外部MCU给模块Trig脚一个大于10uS的高电平脉冲;
模块会给出一个与距离等比的高电平脉冲信号,可根据脉宽时间“T”算出当前距离;
距离 = T * C / 2 (C为声速)
声速温度公式:c ≈ 331.5 + 0.61 * t
例:25℃:
c ≈ 331.5 + 0.61 * 25 = 346.75 m/s
时序图

四、代码编写
1、导入SDK中的 led blinky 模板;

2、使用 Config Tools 图形化工具,配置相关引脚功能;

导入当前工程文件目录下的 led_blinky.mex文件 进行配置;

3、引脚功能配置
GPIO3_12:LED_RED
GPIO3_27:ECHO_PIN (开启 双边沿触发)
GPIO3_28:TRIG_PIN

4、时钟配置
使用内部RC时钟源
系统主频 96Mhz
FRO_HF_clock / LPUART0_clock:96Mhz


5、外设功能配置
GPIO3_IRQn:ECHO引脚中断优先级配置;

板载串口功能配置:串口打印

Sys定时计数器:延时

主要相关代码
主要运行流程:引脚/外设/串口等初始化 → SysTick计数器 → 发11us脉冲触发 → 等ECHO边沿中断记录时间 → 根据脉宽换算距离 → 串口打印;
在原有基础上 led blinky.c 中进行代码修改;
将TRIG (P3_28)设置为输出,将ECHO (P3_27)设置为输入;
将TRIGPin设定为高电平状态,持续11微秒;
读取ECHOPin,返回以微秒为单位的声波移动时间 T;
最后 根据公式 距离 = T * C / 2 进行计算
(声速C采用:340m/s)
对距离值,使用中值滤波(3次取中值)
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "board.h"
#include "peripherals.h"
#include "clock_config.h"
#include "fsl_adapter_gpio.h"
// TRIG = P3_28
#define HC_SR04_TRIG_HANDLE BOARD_INITPINS_TRIG_PIN_handle
// ECHO = P3_27
#define HC_SR04_ECHO_HANDLE BOARD_INITPINS_ECHO_PIN_handle
volatile uint32_t echo_start_tick = 0U;
volatile uint32_t echo_end_tick = 0U;
volatile uint8_t echo_capture_done = 0U;
void Systick_FreeCounter_Init(void)
{
SysTick->LOAD = 0xFFFFFFU;
SysTick->VAL = 0U;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
}
/*
* ECHO 引脚中断回调
* 由 GPIO3_IRQHandler 自动分发并自动清中断标志
* 读引脚电平判断上升/下降沿
*/
static void HC_SR04_Echo_Callback(void *param)
{
uint8_t level;
(void)param;
(void)HAL_GpioGetInput(HC_SR04_ECHO_HANDLE, &level);
if (level != 0U)
{
echo_start_tick = SysTick->VAL;
echo_capture_done = 0U;
}
else
{
echo_end_tick = SysTick->VAL;
echo_capture_done = 1U;
}
}
void HC_SR04_Gpio_Init(void)
{
/* 注册 ECHO 中断回调 */
(void)HAL_GpioInstallCallback(HC_SR04_ECHO_HANDLE, HC_SR04_Echo_Callback, NULL);
/* 双边沿中断触发 */
(void)HAL_GpioSetTriggerMode(HC_SR04_ECHO_HANDLE, kHAL_GpioInterruptEitherEdge);
}
/*
* 基于 SysTick 的延时
* 1us = 96 ticks;SysTick->VAL 递减计数
*/
static void delay_us(uint32_t us)
{
uint32_t start = SysTick->VAL;
uint32_t ticks = us * 96U;
while (((start - SysTick->VAL) & 0xFFFFFFU) < ticks)
{
}
}
static void delay_ms(uint32_t ms)
{
while (ms > 0U)
{
delay_us(1000U);
ms--;
}
}
void HC_SR04_Trigger(void)
{
(void)HAL_GpioSetOutput(HC_SR04_TRIG_HANDLE, 1U);
delay_us(11); /* TRIG ≥10us 精准延时 */
(void)HAL_GpioSetOutput(HC_SR04_TRIG_HANDLE, 0U);
}
float HC_SR04_ReadDistance(void)
{
uint32_t delta_tick;
uint32_t pulse_us;
uint32_t timeout = 0U;
echo_capture_done = 0U;
HC_SR04_Trigger();
while ((echo_capture_done == 0U) && (timeout < 300000U))
{
timeout++;
}
if (echo_capture_done == 0U)
{
return 0.0f;
}
if (echo_end_tick > echo_start_tick)
{
delta_tick = (0xFFFFFFU - echo_start_tick) + echo_end_tick;
}
else
{
delta_tick = echo_start_tick - echo_end_tick;
}
pulse_us = delta_tick / 96U;
float distance_cm = ((float)pulse_us * 0.034f) / 2.0f;
return distance_cm;
}
/*
* 3点中值滤波
*/
static float Median_Filter_3(float a, float b, float c)
{
if (a > b)
{
float t = a;
a = b;
b = t;
}
if (b > c)
{
float t = b;
b = c;
c = t;
}
if (a > b)
{
float t = a;
a = b;
b = t;
}
return b;
}
int main(void)
{
float dist;
BOARD_InitBootClocks(); // 96MHz
BOARD_InitPins(); // 引脚功能初始化
BOARD_InitBootPeripherals(); // 外设功能初始化
BOARD_InitDebugConsole(); // 板载串口功能初始化
HC_SR04_Gpio_Init(); // 超声波模块初始化
Systick_FreeCounter_Init(); // SysTick 计数器初始化
while (1)
{
/* 3点中值滤波 */
dist = Median_Filter_3(HC_SR04_ReadDistance(),
HC_SR04_ReadDistance(),
HC_SR04_ReadDistance());
/* 有效量程 2cm ~ 450cm */
if ((dist >= 2.0f) && (dist <= 450.0f))
{
PRINTF("Distance = %.2f cm\r\n", dist);
}
else
{
PRINTF("No echo(timeout)\r\n");
}
delay_ms(200);
}
}五、程序烧录
1、连接USB数据线至开发板MUC-LINK端口;
2、右键当前工程项目;
3、点击 Flash the Selected Target 烧录程序到开发板上;

六、效果演示

我要赚赏金
