本篇先吐槽下,MCX 是 NXP 新一代通用物联网 / 工业 MCU,接替 Kinetis、LPC 系列,统一软件生态(MCUXpresso),内核以 Cortex‑M33/M0+ 为主,集成 SmartDMA、FlexIO、EdgeLock 安全子系统,覆盖低成本、主流、低功耗、无线、AI 边缘多个档位。
| MCX‑C | Cortex‑M0+ | 48 MHz | 高性价比,16 位 ADC,USB/LCD,小封装,替代 8/16 位 MCU | 小家电、简单传感器、IO 控制 | FRDM‑MCXC444 |
| MCX‑A(主流) | Cortex‑M33 | 96‑240 MHz | 强模拟、电机 PWM、FlexIO、SmartDMA;部分型号集成 T1S 工业以太网 | 工业 IO、电机控制、家电、楼宇控制 | FRDM‑MCXA156 / FRDM‑MCXA346 |
| MCX‑L(超低功耗) | 2×M33 + M0+ | M33 @96 M,M0+@10 M | 多电源域,有源功耗~23 μA/MHz,M0 + 专做常开检测 | 电池设备、传感器节点、可穿戴 | FRDM‑MCXL556 |
| MCX‑W(无线) | Cortex‑M33 | 96 MHz | 内置 BLE、Thread、Zigbee,支持 Matter;W72 支持蓝牙 6.0 信道测距 | 智能家居、Matter 节点、无线传感器 | FRDM‑MCXW72 |
| MCX‑N(AI / 高性能) | 单 / 双 Cortex‑M33 | 150 MHz | eIQ‑Neutron NPU、PowerQuad DSP、CAN‑FD、FlexSPI、SDIO;EdgeLock PSA‑L3 安全认证 | 边缘 AI、HMI、音频、摄像头采集 | FRDM‑MCXN947、FRDM‑MCXN236 |
| MCX‑E | Cortex‑M33 | 96 MHz | 5V 耐压 IO,工业强抗干扰 | 工业现场 5V 输入场景 | ‑ |
最早的型号是MCXN947,2022‑11‑02 正式发布,2023 年样品,2024 量产。
远远晚于STM32,甚至瑞萨RA系列MCU,这就导致网上可参考的中文资料非常少,野火、正点原子也没有推出对应的开发板和教程,这就导致开发难度比较大,得死啃SDK中的驱动库。

比如:IO输出为1的函数
/*!
* @brief Sets the output level of the multiple GPIO pins to the logic 1.
*
* @param base GPIO peripheral base pointer (GPIOA, GPIOB, GPIOC, and so on.)
* @param mask GPIO pin number macro
*/
static inline void GPIO_PortSet(GPIO_Type *base, uint32_t mask)
{
#if !(defined(FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL) && FSL_FEATURE_GPIO_HAS_NO_INDEP_OUTPUT_CONTROL)
base->PSOR = GPIO_FIT_REG(mask);
#else
base->PDOR |= GPIO_FIT_REG(mask);
#endif
}好在MCUXpresso IDE v25.6.136也提供了图形化的配置软件,类似STM32的CubeIDE和CubeMX。
需要说明的是,在上一贴中,详细说明了最新IDE MCUXpresso IDE v25.6.136默认是不支持MCXA366的,需要额外下载软件。
本篇为了方便讲解,以MCXA153为例介绍GPIO的 输出、输入、中断。
其他型号也都一样。
话不多说,先贴main.c文件
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "fsl_common.h"
#define SDK_DelayMs(ms) SDK_DelayAtLeastUs((ms)*1000U, 100000000U)
volatile bool SW3_flag = false; //中断和main循环共享的全局标志,必须加volatile
/* TODO: insert other include files here. */
/* TODO: insert other definitions and declarations here. */
/*
* @brief Application entry point.
*/
int main(void) {
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
PRINTF("Hello World\r\n");
/* Force the counter to be placed into memory. */
volatile static int i = 0 ;
/* Enter an infinite loop, just incrementing a counter. */
while(1) {
i++ ;
/* 'Dummy' NOP to allow source level single stepping of
tight while() loop */
//GPIO_PortToggle(GPIO3, 1u << 12);
//SDK_DelayMs(500); //延时500ms
/*GPIO_PortSet(GPIO3, 1u << 12);
SDK_DelayMs(500);
GPIO_PortClear(GPIO3, 1u << 12);
SDK_DelayMs(500);*/
/* if(GPIO_PinRead(GPIO1, 7) == 0)
{GPIO_PortSet(GPIO3, 1u << 12);}
else
{GPIO_PortClear(GPIO3, 1u << 12);}*/
if(GPIO_PinRead(GPIO3, 29) == 0) //SW2 轮询
{GPIO_PortSet(GPIO3, 1u << 0);}
else
{GPIO_PortClear(GPIO3, 1u << 0);}
if(SW3_flag == true) //SW3 中断
{
SW3_flag = false;
GPIO_PortToggle(GPIO3, 1u << 12);
}
__asm volatile ("nop");
}
return 0 ;
}
/* GPIO1_IRQn interrupt handler */
void INT_0_IRQHANDLER(void) {
/* Place your code here */
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
Store immediate overlapping exception return operation might vector to incorrect interrupt. */
uint32_t flags = GPIO_GpioGetInterruptFlags(GPIO1); //GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin);
if (flags & (1u << 7))
{
SW3_flag = true;
//GPIO_PortToggle(GPIO3, 1u << 12);
GPIO_PinClearInterruptFlag(GPIO1,7);
}
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}要彻底搞通MCX系列MCU的GPIO(输出、输入、中断)
在此之前需要先配置IO的功能选择(GPIO)、方向(输入输出)、初始值、中断。
点击IDE右侧的芯片图标,打开引脚配置页面。
需要重点吐槽下,如果IDE有多个工程,即便选择了某个工程,一定还要在左侧的工程栏选中正确的工程,IDE他不会自动切换,这真是个Bug。



接下来配置 GPIO
P3_0 是输出——LED BLUE
P3_12 是输出——LED RED
P1_7是按键输入——SW3 下降沿中断
P3_29是按键输入——SW2 关闭中断

接下来点击IDE右上角的USB图标配置外设(中断 NVIC)

新建NVIC,选择中断源为GPIO0
enable中断优先级0
使用默认中断函数void INT_0_IRQHANDLER(void),并在其中编写指令。
/* GPIO1_IRQn interrupt handler */
void INT_0_IRQHANDLER(void) {
/* Place your code here */
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
Store immediate overlapping exception return operation might vector to incorrect interrupt. */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
全部配置完成后,点击菜单栏左侧“更新源代码”,相关代码就自动生成了。

延时函数
#define SDK_DelayMs(ms) SDK_DelayAtLeastUs((ms)*1000U, 100000000U)
2. GPIO输出
GPIO_PortToggle(GPIO3, 1u << 12); SDK_DelayMs(500); //延时500ms GPIO_PortSet(GPIO3, 1u << 12); SDK_DelayMs(500); GPIO_PortClear(GPIO3, 1u << 12); SDK_DelayMs(500);
3. GPIO输入(不带中断)
采用轮询方式
if(GPIO_PinRead(GPIO3, 29) == 0) //SW2 轮询
{GPIO_PortSet(GPIO3, 1u << 0);}
else
{GPIO_PortClear(GPIO3, 1u << 0);}4. GPIO输出(带中断)
采用前后台
后台中断仅获取中断,并置状态位SW3_flag
前台while(1)中根据SW3_flag状态执行对应操作
中断函数(后台)
/* GPIO1_IRQn interrupt handler */
void INT_0_IRQHANDLER(void) {
/* Place your code here */
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F
Store immediate overlapping exception return operation might vector to incorrect interrupt. */
uint32_t flags = GPIO_GpioGetInterruptFlags(GPIO1); //GPIO_PinGetInterruptFlag(GPIO_Type *base, uint32_t pin);
if (flags & (1u << 7))
{
SW3_flag = true;
//GPIO_PortToggle(GPIO3, 1u << 12);
GPIO_PinClearInterruptFlag(GPIO1,7);
}
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}while(1)函数(前台)
if(SW3_flag == true) //SW3 中断
{
SW3_flag = false;
GPIO_PortToggle(GPIO3, 1u << 12);
}这样就实现了LED输出 闪烁
按键SW2按下 输入轮询
按键SW3按下 中断执行
我要赚赏金
