查看: 24|回复: 0

[分享] MCXC444: FlexIO 实现外部引脚上升沿中断捕捉

[复制链接]

该用户从未签到

728

主题

6387

帖子

0

超级版主

Rank: 8Rank: 8

积分
25704
最后登录
2025-9-30
发表于 前天 17:48 | 显示全部楼层 |阅读模式
本帖最后由 小恩GG 于 2025-9-29 17:48 编辑

一、概述
在 MCU 开发过程中,我们经常需要检测外部信号的上升沿或下降沿,并据此触发中断。然而,有些端口(如 MCXC444 的 PortE)并不直接支持 GPIO 中断,这时候就需要寻找替代方案。
FlexIO 模块本质上是一个可编程外设,可以模拟 UART、SPI、I²C,也可以灵活实现 波形捕捉、边沿检测。我们就利用它的 Timer 功能实现外部边沿捕捉。

本文将介绍如何利用 FlexIO 模块,在 FLEXIO_D4(PTE20)引脚上实现上升沿捕捉中断。

硬件环境:
        开发板:FRDM-MCXC444
软件环境:
        IDE:MCUXpresso IDE v11.9.0
        SDK:SDK Builder | MCUXpresso SDKBuilder (nxp.com)
        基础工程: Hello World


二、设计思路

FlexIO Timer 的核心思想是:

PinSelect → 指定输入引脚(FLEXIO_D4 ↔ PTE20)。

TimerDecrement → 由引脚电平驱动计数。

TimerReset → 在引脚上升沿复位计数器。

TimerCompare → 计数到比较值时置位中断标志(TIF)。

这样就能保证:每次上升沿触发一次中断。


三、实现步骤

3.1 时钟配置
  1. /* Set FLEXIO clock source. */
  2.     CLOCK_SetFlexio0Clock(SIM_FLEXIO_CLK_SEL_IRC48M_CLK);
复制代码
为 FlexIO 模块开启时钟。

3.2  配置引脚
  1. /* PORTE20 (pin 9) is configured as FXIO0_D4 */
  2.     PORT_SetPinMux(PORTE, 20U, kPORT_MuxAlt6);
  3.   /* PORTE30 (pin 18) is configured as PTE30 */
  4.     PORT_SetPinMux(PORTE, 30U, kPORT_MuxAsGpio);
复制代码


将 PTE20 复用为 FLEXIO0_D4。为了产生上升延和下降延,将 PTE30配置成GPIO 输出。

3.3 配置FlexIO Timer

  1. flexio_config_t flexioConfig;
  2.     flexio_timer_config_t timerConfig;

  3.     /* 3. 初始化 FlexIO 模块 */
  4.     FLEXIO_GetDefaultConfig(&flexioConfig);
  5.     FLEXIO_Init(BOARD_FLEXIO_BASE, &flexioConfig);

  6.         memset(&timerConfig, 0, sizeof(timerConfig));
  7.           timerConfig.pinConfig = kFLEXIO_PinConfigOutputDisabled;
  8.           timerConfig.pinSelect = 4;
  9.           timerConfig.pinPolarity = kFLEXIO_PinActiveHigh;

  10.           timerConfig.triggerSelect = FLEXIO_TIMER_TRIGGER_SEL_PININPUT(FLEXIO_PIN);
  11.           timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh; // rising edge
  12.           timerConfig.triggerSource   = kFLEXIO_TimerTriggerSourceExternal;

  13.           timerConfig.triggerPolarity = kFLEXIO_TimerTriggerPolarityActiveHigh;

  14.           timerConfig.timerMode = kFLEXIO_TimerModeSingle16Bit;
  15.           timerConfig.timerOutput = kFLEXIO_TimerOutputOneNotAffectedByReset;
  16.           timerConfig.timerDecrement= kFLEXIO_TimerDecSrcOnPinInputShiftPinInput;
  17.           timerConfig.timerReset = kFLEXIO_TimerResetOnTimerPinRisingEdge;
  18.           timerConfig.timerDisable = kFLEXIO_TimerDisableNever;
  19.           timerConfig.timerEnable = kFLEXIO_TimerEnabledAlways;
  20.           timerConfig.timerCompare = 0x0001;
  21.           FLEXIO_SetTimerConfig(BOARD_FLEXIO_BASE, 0, &timerConfig);

  22.          FLEXIO_EnableTimerStatusInterrupts(BOARD_FLEXIO_BASE, 1U << 0);
  23.          EnableIRQ(UART2_FLEXIO_IRQn);
  24.          NVIC_SetPriority(UART2_FLEXIO_IRQn, 2);
复制代码

关键点:
triggerSelect:选择FLEXIO_TIMER_TRIGGER_SEL_PININPUT(FLEXIO_PIN);引脚作为输入触发源。

timerReset:设置为 kFLEXIO_TimerResetOnTimerPinRisingEdge,这样每次上升沿都会触发 flag。

timerDecrement: 选择 kFLEXIO_TimerDecSrcOnPinInputShiftPinInput,保证计数由外部引脚驱动。

pinConfig/pinSelect:指定输入引脚为 FlexIO_D4。

timerMode:单次计数模式,用于捕获事件而非周期计数。

TimerCompare: 设为 0x01,确保每次边沿都会立刻触发中断。值太大会导致需要多次脉冲才触发。

MCXC444 没有单独的 FLEXIO_IRQn,而是复用在 UART2_FLEXIO_IRQ


3.4 中断服务函数
  1. void UART2_FLEXIO_IRQHandler(void)
  2. {
  3.     uint32_t flags = FLEXIO_GetTimerStatusFlags(BOARD_FLEXIO_BASE);
  4.     if (flags & (1U << FLEXIO_TIMER))
  5.     {
  6.         FLEXIO_ClearTimerStatusFlags(BOARD_FLEXIO_BASE, 1U << FLEXIO_TIMER);
  7.         PRINTF("FlexIO: Rising edge detected!\r\n");
  8.     }
  9. };

复制代码

四、实验结果
当外部信号接入 PTE20 (FLEXIO0_D4) 并产生上升沿时,FlexIO Timer检测到事件,触发中断,串口会输出提示信息。

验证了 FlexIO Timer 可以作为额外的“可编程外部中断”使用。


五、总结
本文展示了如何利用 MCXC444 MCU 的 FlexIO 模块实现边沿检测中断。

相比传统 GPIO 中断方式,FlexIO 提供了更高的灵活性,适合在 GPIO 资源有限或需要复杂触发条件的场景下使用。




回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-10-1 07:15 , Processed in 0.068898 second(s), 18 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表