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主页、知乎主页、微信公众号 平台上。
微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。