大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦全系列MCU(包含Kinetis, LPC, i.MXRT, MCX)的GPIO电平中断设计差异

  在痞子衡旧文 《以i.MXRT1xxx的GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程》里,痞子衡主要介绍得是 GPIO 一般控制以及最常用的输入边沿中断相关知识。最近恩智浦官方社区有用户反映 i.MXRT1060 上 GPIO 中断状态寄存器(GPIO->ISR)在发生有效电平中断后的置位并不需要手动清零(W1C),其会在 I/O 输入电平状态切换后自动清零,这和手册里描述不一致。

  首先在痞子衡的认知里 GPIO 输入电平中断没有什么具体应用场景,想象一下,如果 GPIO 中断事件由输入电平值来触发,如果发生了有效输入电平且其状态不改变,那么 GPIO 中断响应函数就会被不断重复执行(此时 CPU 时间片无法再分给主函数),什么样的任务需要这样的处理呢?暂且不论应用场景,痞子衡今天就从恩智浦全系列 MCU 这方面的行为角度来做一下对比吧。

一、I/O中断控制模块差异

  恩智浦现有的经典 Arm Cortex-M MCU 产品线共有如下五大类,它们在 GPIO 一般控制和中断控制外设上是有差异的。首先 i.MXRT四位数/Kinetis/LPC 这三条线各自是完全不同的外设,然后 i.MXRT三位数是在 LPC 外设基础上做了增强,而最新的 MCX 系列则是组合了 Kinetis 和 LPC 外设。

芯片系列 I/O一般控制 I/O中断控制
Kinetis GPIO type1 PORT
LPC GPIO type2 PINT
i.MXRT四位数 GPIO type3 GPIO type3
i.MXRT三位数 GPIO type2 GPIO type2(增加interrupt A/B)

PINT
MCX GPIO type1 GPIO type1(集成Kinetis PORT)

PINT

二、不同系列MCU下测试结果

  根据上一节外设情况我们知道,只要测试了 i.MXRT四位数/Kinetis/LPC 这三个系列的情况,剩下两个系列自然也就不用测试了。

2.1 Kinetis

  Kinetis 系列分为 K/KL/KE/KS/KW/KV/KM/K32L 等若干子系列,但是它们关于 GPIO 中断设计这一块是一样的。痞子衡选取了 MKL03Z 这颗芯片来做的测试,查看其手册 PORTx->PCRn[ISF] 位或者 PORTx->ISFR 寄存器均标记了中断状态,并且标明了需要做 W1C 操作。

  我们可以直接在 \SDK_2.3.1_FRDM-KL03Z\boards\frdmkl03z\driver_examples\gpio\input_interrupt 例程上做测试,只需要做简单修改,痞子衡摘取了主要代码如下。FRDM-KL03Z 板上 SW3 按键对应 PTB5 引脚(按下为低电平,松开为高电平),代码设计里按一次 SW3 便打印一次。测试结果来看,在 Kinetis 上即使是电平中断,PORTx->ISFR 寄存器也是必须要手动清零的,与手册描述一致。

IRQ函数中是否清零Flag SW3动作 IRQ执行情况 打印输出结果
上电默认松开(高电平) IRQ函数未触发
SW3按下(低电平) IRQ函数重复执行
SW3松开(高电平) IRQ函数不再触发 出现一次打印
上电默认松开(高电平) IRQ函数未触发
SW3按下(低电平) IRQ函数重复执行
SW3松开(高电平) IRQ函数重复执行
volatile bool g_ButtonPress = false;
void PORTB_IRQHandler(void)
{
// 清除中断标志
PORTB->ISFR = 1U << 5U;
g_ButtonPress = true;
}
int main(void)
{
// 省略 PTB5 引脚的 PINMUX 配置
gpio_pin_config_t sw_config = {
kGPIO_DigitalInput, 0,
};
// 仅需此处修改:将 GPIO 中断模式改为低电平触发
PORT_SetPinInterruptConfig(PORTB, 5U, kPORT_InterruptLogicZero);
NVIC_EnableIRQ(PORTB_IRQn);
GPIO_PinInit(GPIOB, 5U, &sw_config);
while (1)
{
if (g_ButtonPress)
{
delay();
PRINTF(" %s is pressed \r\n", "SW3");
g_ButtonPress = false;
}
}
}

2.2 i.MXRT四位数

  i.MXRT四位数系列分为 RT1010/1015/1020/1040/1050/1060/1160/1170/1180 等若干子型号,但是它们关于 GPIO 中断设计是一样的。痞子衡选取了 i.MXRT1062 这颗芯片来做的测试,查看其手册 GPIOx->ISR 寄存器标记了中断状态,同样标明了需要做 W1C 操作。

  我们可以直接在 \SDK_2_12_1_EVK-MIMXRT1060\boards\evkmimxrt1060\driver_examples\gpio\input_interrupt 例程上做测试,只需要做简单修改,主要代码如下。MIMXRT1060-EVK 板上 SW8 按键对应 WAKEUP_GPIO5[0] 引脚(按下为低电平,松开为高电平),代码设计里按一次 SW8 便打印一次。测试结果来看,在 i.MXRT 四位数上如果是电平中断,GPIOx->ISR 寄存器会在电平状态切换时自动清零,跟手册描述有点差异,不过这样的设计比 Kinetis 上看起来更合理。

IRQ函数中是否清零Flag SW8动作 IRQ执行情况 打印输出结果
是/否 上电默认松开(高电平) IRQ函数未触发
SW8按下(低电平) IRQ函数重复执行
SW8松开(高电平) IRQ函数不再触发 出现一次打印
volatile bool g_InputSignal = false;
void GPIO5_Combined_0_15_IRQHandler(void)
{
// 清除中断标志
GPIO5->ISR = 1U << 0U;
g_InputSignal = true;
__DSB();
}
int main(void)
{
// 省略 WAKEUP 引脚的 PINMUX 配置
gpio_pin_config_t sw_config = {
kGPIO_DigitalInput,
0,
kGPIO_IntLowLevel, // 仅需此处修改:将 GPIO 中断模式改为低电平触发
};
GPIO_PortEnableInterrupts(GPIO5, 1U << 0U);
NVIC_EnableIRQ(GPIO5_Combined_0_15_IRQn);
GPIO_PinInit(GPIO5, 0U, &sw_config);
while (1)
{
if (g_InputSignal)
{
delay();
PRINTF(" %s is turned on. \r\n", "SW8");
g_InputSignal = false;
}
}
}

2.3 LPC

  LPC系列分为 800/1x00/4000/4300/51Uxx/54000/5500 等若干子型号,但是它们关于 GPIO 中断设计是一样的。痞子衡选取了 LPC54114 这颗芯片来做的测试,查看其手册 PINT->IST 寄存器标记了中断状态,这里关于 W1C 操作做了边沿方式和电平方式的区别,其中对于电平方式,W1C 是切换有效电平逻辑。

  我们可以直接在 \SDK_2_9_0_LPCXpresso54114\boards\lpcxpresso54114\driver_examples\pint\pin_interrupt 例程上做测试,只需要做简单修改,主要代码如下。LPCXpresso-54114 板上 SW1 按键对应 PIO0[24] 引脚(按下为低电平,松开为高电平),代码设计里按一次 SW1 便打印一次。测试结果来看,在 LPC 上如果是电平中断,PINT->IST 寄存器会在电平状态切换时自动清零,跟手册描述有点差异,并且中断处理函数里如果主动加上 W1C 操作其效果就变成了双边沿中断,这样的设计比 i.MXRT 四位数更进了一步。

IRQ函数中是否清零Flag SW1动作 IRQ执行情况 打印输出结果
上电默认松开(高电平) IRQ函数未触发
SW1按下(低电平) IRQ函数重复执行
SW1松开(高电平) IRQ函数不再触发 出现一次打印
上电默认松开(高电平) IRQ函数未触发
SW1按下(低电平) IRQ函数执行一次 出现一次打印
SW1松开(高电平) IRQ函数执行一次 出现一次打印
volatile bool g_ButtonPress = false;
void PIN_INT0_DriverIRQHandler(void)
{
uint32_t pmstatus = PINT_PatternMatchResetDetectLogic(PINT);
if (s_pintCallback[kPINT_PinInt0] != NULL)
{
s_pintCallback[kPINT_PinInt0](kPINT_PinInt0, pmstatus);
}
// 清除中断标志
PINT->IST = (1UL << (uint32_t)kPINT_PinInt0);
__DSB();
}
void pint_intr_callback(pint_pin_int_t pintr, uint32_t pmatch_status)
{
g_ButtonPress = true;
}
int main(void)
{
INPUTMUX_Init(INPUTMUX);
INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, kINPUTMUX_GpioPort0Pin24ToPintsel);
PINT_Init(PINT);
// 仅需此处修改:将 GPIO 中断模式改为低电平触发
PINT_PinInterruptConfig(PINT, kPINT_PinInt0, kPINT_PinIntEnableLowLevel, pint_intr_callback);
PINT_EnableCallbackByIndex(PINT, kPINT_PinInt0);
while (1)
{
if (g_ButtonPress)
{
delay();
PRINTF(" %s Pin Interrupt event detected \r\n", "SW1");
g_ButtonPress = false;
}
}
}

  至此,恩智浦全系列MCU的GPIO电平中断设计差异痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页知乎主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:对比恩智浦全系列MCU(包含Kinetis/LPC/i.MXRT/MCX)的GPIO电平中断设计差异的更多相关文章

  1. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.6)- 串行NOR Flash下载算法(MCUXpresso IDE篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是MCUXpresso IDE开发环境下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行N ...

  2. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(7)- 从SD/eMMC启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MXRTxxx系列MCU的SD/eMMC卡启动. 关于 i.MXRT 启动设备,痞子衡之前写过很多篇文章,都是关于串并行 NO ...

  3. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性介绍(2)- RT685EVKA性能实测(Dhrystone)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的性能. 在前面的文章 i.MXRTxxx微控制器概览 里,痞子衡给大家简介过恩智浦半导体在2018 ...

  4. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(3)- Serial ISP模式(blhost)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的Serial ISP模式. 在上一篇文章 Boot配置(ISP Pin, OTP) 里痞子衡为大家 ...

  5. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(4)- OTP及其烧写方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的OTP. 在i.MXRTxxx启动系列第二篇文章 Boot配置(ISP Pin, OTP) 里痞子 ...

  6. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(8)- 从Serial(1-bit SPI) NOR恢复启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的1-bit SPI NOR恢复启动. 在前几篇里痞子衡介绍的Boot Device都属于主动启动的 ...

  7. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(11.3)- FlexSPI NOR连接方式大全(RT1010)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1010的FlexSPI NOR启动的连接方式. 在写完 <FlexSPI NOR启动连接方式(RT1015/ ...

  8. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU特性那些事(1)- 概览

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的基本特性. 恩智浦半导体于2017年开始推出的i.MX RT系列重新定义了MCU,其第一款芯片i. ...

  9. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU启动那些事(13.A)- LPSPI NOR启动时间(RT1170)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT1170 1bit SPI NOR恢复启动时间. 本篇是i.MXRT1170启动时间评测第三弹了,前两篇分别给大家评 ...

  10. 痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU硬件那些事(2.4)- 串行NOR Flash下载算法(Keil MDK工具篇)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是Keil MDK工具下i.MXRT的串行NOR Flash下载算法设计. 在i.MXRT硬件那些事系列之<在串行NOR Flash ...

随机推荐

  1. PAT (Basic Level) Practice 1011 A+B 和 C 分数 15

    给定区间 [−231,231] 内的 3 个整数 A.B 和 C,请判断 A+B 是否大于 C. 输入格式: 输入第 1 行给出正整数 T (≤10),是测试用例的个数.随后给出 T 组测试用例,每组 ...

  2. Seal-Report: 开放式数据库报表工具

    Seal Report是.Net的一个基于Apache 2.0 开源工具,完全用C# 语言编写,最新的6.6 版本采用.NET 6,github: https://github.com/ariacom ...

  3. 挑战海量数据:基于Apache DolphinScheduler对千亿级数据应用实践

    点亮 ️ Star · 照亮开源之路 GitHub:https://github.com/apache/dolphinscheduler 精彩回顾 近期,初灵科技的大数据开发工程师钟霈合在社区活动的线 ...

  4. get,post,put,delete四种基础方法对应增删改查

    PUT,DELETE,POST,GET四种基础方法对应增删改查 1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数 ...

  5. 基于YOLO和PSPNet的目标检测与语义分割系统(python)

    基于YOLO和PSPNet的目标检测与语义分割系统 源代码地址 概述 这是我的本科毕业设计 它的主要功能是通过YOLOv5进行目标检测,并使用PSPNet进行语义分割. 本项目YOLOv5部分代码基于 ...

  6. 2.-url和视图函数

    一.URL-结构 1.定义:统一资源定位符 Uniform Resource Locator 2.作用:用来表示互联网上某个资源地址 3.URL的一般语法格式为(注:[]代码其中的内容可以省略): 格 ...

  7. 驱动开发:内核监控Register注册表回调

    在笔者前一篇文章<驱动开发:内核枚举Registry注册表回调>中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监 ...

  8. React动画实现方案之 Framer Motion,让你的页面“自己”动起来

    前言 相信很多前端同学都或多或少和动画打过交道.有的时候是产品想要的过度效果:有的时候是UI想要的酷炫动画.但是有没有人考虑过,是不是我们的页面上面的每一次变化,都可以像是自然而然的变化:是不是每一次 ...

  9. Spring Cloud 整合 nacos 实现动态配置中心

    上一篇文章讲解了Spring Cloud 整合 nacos 实现服务注册与发现,nacos除了有服务注册与发现的功能,还有提供动态配置服务的功能.本文主要讲解Spring Cloud 整合nacos实 ...

  10. 我的 React 最佳实践

    There are a thousand Hamlets in a thousand people's eyes. ----- 威廉·莎士比亚 免责声明:以下充满个人观点,辩证学习 React 目前开 ...