批子恒嵌入式:比较NXP全系列MCU(包括Kinetis/LPC/i.MXRT/MCX)GPIO电平中断设计的差异
大家好,我是皮子恒,一个认真科技的痞子。今天皮子恒给大家介绍一下NXP全系列MCU(包括Kinetis、LPC、i.MXRT、MCX)在GPIO电平中断设计上的差异。
在皮子恒的旧文章《以i.MXRT1xxx的GPIO模块为例谈谈中断处理函数(IRQHandler)的标准流程》中,皮子恒主要介绍了GPIO通用控制以及最常用的输入边沿中断的知识。近日,NXP官方社区有用户反映,i.MXRT1060上的GPIO中断状态寄存器(GPIO->ISR)在有效电平中断发生后不需要手动清零(W1C)。切换到平铺状态后自动清除,与手册中的描述不一致。
首先,在皮子衡的认知中,GPIO输入电平中断并没有具体的应用场景。想象一下,如果 GPIO 中断事件是由输入电平值触发的。如果出现有效输入电平且其状态没有改变,则GPIO中断响应函数将被重复执行(此时CPU时间片不能再分配给主函数)。什么样的任务需要这样的处理?暂且不论应用场景如何,皮子恒今天就从NXP全系列MCU的行为角度进行对比。
1。 I/O中断控制模块的差异
NXP现有经典Arm Cortex-M MCU产品线有以下五类。它们的不同之处在于GPIO通用控制和中断控制外设。首先,i.MXRT四位/Kinetis/LPC这三条线是完全不同的外设。然后,在LPC外设的基础上增强了i.MXRT三位数,并与Kinetis结合了最新的MCX系列。和LPC外围设备。
芯片系列 | I/O 通用控制 | I/O中断控制 |
---|---|---|
Kinetis | GPIO 类型1 | 港口 |
LPC | GPIO 类型2 | 品脱 |
i.MXRT 四位数 | GPIO 类型3 | GPIO 类型3 |
i.MXRT 三位数 | GPIO 类型2 | GPIO type2(添加中断A/B) 品脱 |
MCX | GPIO 类型1 | GPIO 类型 1(集成 Kinetis 端口) 品脱 |
2。不同系列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功能重复执行 | 无 |
易失性 bool g_ButtonPress = false;
无效 PORTB_IRQHandler(无效)
{
// 清除中断标志
PORTB->ISFR = 1U << 5U;
g_ButtonPress = true;
}
int 主函数(无效)
{
// 省略PTB5引脚的PINMUX配置
gpio_pin_config_t sw_config = {
kGPIO_数字输入,0,
};
//此处仅修改:将GPIO中断模式改为低电平触发
PORT_SetPinInterruptConfig(PORTB, 5U, kPORT_InterruptLogicZero);
NVIC_EnableIRQ(PORTB_IRQn);
GPIO_PinInit(GPIOB, 5U, &sw_config);
而 (1)
{
如果(g_ButtonPress)
{
延迟();
PRINTF(" %s 被按下 \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 功能不再触发 | 出现一次并打印 |
易失性 bool g_InputSignal = false;
无效GPIO5_Combined_0_15_IRQHandler(无效)
{
// 清除中断标志
GPIO5->ISR = 1U << 0U;
g_InputSignal = true;
__DSB();
}
int 主函数(无效)
{
// PINMUX 配置省略 WAKEUP 引脚gpio_pin_config_t sw_config = {
kGPIO_数字输入,
0,
kGPIO_IntLowLevel, //此处只需修改:将GPIO中断模式改为低电平触发
};
GPIO_PortEnableInterrupts(GPIO5, 1U << 0U);
NVIC_EnableIRQ(GPIO5_Combined_0_15_IRQn);
GPIO_PinInit(GPIO5, 0U, &sw_config);
而 (1)
{
如果(g_输入信号)
{
延迟();
PRINTF(" %s 已打开。\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功能执行一次 | 出现一次并打印 |
易失性 bool g_ButtonPress = false;
无效PIN_INT0_DriverIRQHandler(无效)
{
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();
}
无效pint_intr_callback(pint_pin_int_t pintr,uint32_t pmatch_status)
{
g_ButtonPress = true;
}
int 主函数(无效)
{
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);
而 (1)
{
如果(g_ButtonPress)
{
延迟();PRINTF(" 检测到 %s 引脚中断事件 \r\n", "SW1");
g_ButtonPress = false;
}
}
}
至此,皮子恒就介绍完了NXP全系列MCU在GPIO电平中断设计上的差异。掌声在哪里~~~
欢迎订阅
文章将同时发布到我的博客园主页、CSDN主页、知乎主页、微信公众号平台。
微信搜索“痽子hengembedded”或扫描下方二维码即可在手机上立即观看。
相关文章
- 10-05 浅谈ubuntu中执行.sh文件的几种方式的区别
- 10-05 Linux性能优化的实用思路和技巧(linux性能
- 10-05 如何轻松安装Linux系统显卡驱动(Linux安装
- 10-05 win10动态锁设置教程
- 10-05 win10关闭Win10右下角提示的教程
- 10-05 win10设置定时提醒闹钟方法
- 10-05 win10音频服务未运行 错误1068怎么办
- 10-05 win10哪里下载
- 10-05 Win10命令提示符打不开怎么办
- 10-05 实现发送模板消息功能的微信小程序示例【通过open
- 10-05 微信公众平台发送模板消息(Java接口开发)
- 10-05 React 同构实践:实现自己的同构模板
- 10-05 java中如何拼接sql语句,java中如何拼接s
- 10-05 童刚java视频教程简介
- 10-05 Linux运维年终报告,Linux运维日常工作
- 10-05 通过一个例子演示如何使用CSS中的伪类选择器hov
- 10-05 CSS:hover 选择器的使用简单介绍
- 10-05 如何使用伪悬停
- 10-05 OpenVPN 使用用户名/密码身份验证
- 10-05 Servlet生成验证码,通过账号密码和验证码验证
- 最近发表