【干货】不看你就亏大了! LPC824 外部中断详解及实例应用

外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使 CPU 暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续执行下去。LPC82X 系列的外部中断包含了单引脚中断和模式匹配中断两种方式。接下来,我们除了介绍 LPC82X 单引脚中断外,还会揭秘 LPC82X 的高级应用模式匹配中断

一、PININT 模块功能简介

1.1 PININT 模块功能简介

  • 有 8 路引脚信号输入,每路输入可以与任何一个 IO 引脚配接

            − 这意味着每个 IO 脚都能产生外部中断,但最多选出 8 个脚

            − 8 路输入可以按两种方式产生中断:引脚中断与模式匹配中断

            − 单个引脚可以配接到多路输入

            − 注意:即使某个 IO 脚不是当作 GPIO 使用,也能配接到 PININT 的中断源上。

  • (常用)引脚(Pin)中断:单路信号产生中断,也就是常说的“外部中断”。

            − 触发条件可配置为:

               电平触发:高电平、低电平

               边沿触发:上升沿、下降沿、双边沿

            − 8 路输入每路都在 NVIC 中有自己专用的中断号,共 8 个

  • (高级应用)模式匹配(Pattern match)中断:1-8 路信号经过布尔位运算为真时产生中断 ,每路信号亦可以选择电平或刚刚的边沿来触发

            − 例如,三人意见表决器,以少数服从多数原则:(A&B)|(B&C)|(C&A)


二、 PININT 单引脚中断

2.1 单引脚中断的功能框图(如图 2-1-1 所示)

  • 共 8 路独立工作的引脚输入中断信号,每路都可配接到任何 IO 引脚,而且不限于用作 GPIO 的脚

2.2 使用 PININT 模块的步骤(如图 2-2-1 所示)



2.3 PININT 中断源与 IO 引脚的配接(IO 不是 GPIO)

  • 在 SYSCON 模块中,有一组寄存器 PINTSEL[8],用于配接每个 PINTSEL 对应一路中断源(如图 2-3-1 所示)

           

  • 寄存器的值决定配接到哪个 IO 口

            − 端口号:PINTSEL# / 32

            − 引脚号:PINTSEL# % 32

  • 例:把 P0_20 配接到 5 号中断源

           − SYSCON.PINTSEL[5] = 20

  • PININT 与 GPIOINT 的区别

          − 中断可分为硬件中断(由硬件产生)和软件中断(由当前进程产生)。每个硬件设备或者设备集都有自己的 IRQ(中断请求),且硬件中断又可以分为内部中断和外部中断。外部中断,即 PINT 一般是指由 MCU 外设发出的中断请求,中断请求通过对应的 PIN 脚传递到 MCU;因为每个 PIN 脚都可以配置成多种模式,如:GPIO、ADC、I2C 等,如下举例。

  • 即使某个引脚并不作为 GPIO 使用,也能配接到 PININT 的中断源

           − 例如:要自动探测 4 个 I2C 接口中哪一个被连接到主机上,即可以把它们 4 个的 SCL 线所在的 IO 脚分别配接到 4 路 PININT 中断上。通信时,发生哪个中断,就认为连接到了哪个 I2C 接口。

           − 上例中,IO 引脚并非作为 GPIO 使用,而是作为 I2C 的 SCL 信号。

2.4 PININT 单引脚中断的寄存器配置

  • 所有寄存器都是每个位(bit)对应一路引脚中断源
  • 通过 ISEL 寄存器决定信号的触发是电平还是边沿(如图 2-4-1 所示)

           − PINT->ISEL = 0 : 将外部中断源 0 配置为边沿触发
           − PINT->ISEL = 1 : 将外部中断源 0 配置为电平触发

             

  • 配置 IENR 和 IENF 寄存器以决定触发方式的细节(如图 2-4-2 所示)

           − 电平和边沿共享这一对配置寄存器,但是有各自的用法

               电平触发:分别为每路输入设定是否允许电平触发和选择高/低电平

               边沿触发:分别为每路输入设定是否分别允许上升沿和下降沿触发

           − PINT->IENR = 0 : 将外部中断源 0 除能低电平触发或上升沿触发

           − PINT->IENR = 1 : 将外部中断源 0 使能低电平触发或上升沿触发

           − PINT->IENF = 0 : 将外部中断源 0 除能高电平触发或下降沿触发

           − PINT->IENF = 1 : 将外部中断源 0 使能高电平触发或下降沿触发(使能高电平触发还需要配置 PINT->IENR = 1)


            

  • 如果同时允许两个,就实现了双边沿触发。

           − PINT-> ISEL = 0 : 先将外部中断源 0 配置为边沿触发

           − PINT->IENR = 1 : 将外部中断源 0 使能上升沿触发

           − PINT->IENF = 1 : 将外部中断源 0 使能下降沿触发

  • 边沿在检测后被锁存,因此提供了边沿检测与清除的功能,由寄存器”RISE”和”FALL”负责(如图 2-4-3 所示)

           − 被读取时,反映上升沿/下降沿是否已检测待处理

               PINT-> RISE = 0 : 自复位或上次写入该位以来,外部中断源 0 没有检测到上升沿。

               PINT-> RISE = 1 : 自复位或上次写入此位以来,外部中断源 0 检测到上升沿。

               PINT-> FALL = 0 : 自复位或上次写入该位以来,外部中断源 0 没有检测到下降沿。

               PINT-> FALL = 1 : 自复位或上次写入此位以来,外部中断源 0 检测到下降沿。

           − 被写 1 时(写 0 无效),清除对应的边沿检测锁存标志

               PINT-> RISE = 1 : 清除外部中断源 0 的上升边沿检测锁存标志

               PINT-> FALL = 1 : 清除外部中断源 0 的下降边沿检测锁存标志 

               

  • 通过“IST”寄存器查看各路中断请求的状态,并快速执行常用操作(如图 2-4-4 所示)

           − 被读取时,反映当前各路中断是否已请求(触发)

               PINT-> IST = 0 : 外部中断源 0 没有被请求(触发)

               PINT-> IST = 1 : 外部中断源 0 正在被请求(触发)

           − 被写入时,只能写 1,写 0 无效

               PINT-> IST = 1 :

               对于边沿触发,同时清除双边沿检测的锁存标志

               对于电平触发,切换触发电平
           
               注意:电平触发的中断由硬件在有效电平消失时自动清除标志,没有软件清除电平中断标志的操作——会被解释为切换触发电平!

                


2.5 用于化简“读-改-写”为单次操作的伴侣寄存器

  • 为了免除“读-改-写”的麻烦,IENR 和 IENF 都有对应的两个伴侣寄存器,分别用于置 1 和置 0(如图 2-4-5 所示)

           − IENR 的伴侣寄存器是 SIENR, CIENR; IENF 的是 SIENF   和 CIENF

           − 伴侣寄存器都是写 1 有效的,写 0 无效,避免了读-改-写

           − 往置 1 寄存器(SIENR, SIENF)的位里写 1,主寄存器的相应位被置 1

               PINT-> SIENR = 1 => PINT-> IENR= 1

               PINT-> SIENF = 1 => PINT-> IENR= 1

          − 往置 0 寄存器(CIENR, CIENF)的位里写 1,主寄存器的相应位被置 0

              PINT-> CIENR = 1 => PINT-> IENR= 0
              PINT-> CIENF = 1 => PINT-> IENR= 0

             


三、PININT模式匹配引擎

3.1 模式匹配引擎功能简介引脚中断功能的扩展

  • 模式匹配引擎是 PININT 模块的一部分,扩展了单引脚中断的功能。把多个引脚的状态进行逻辑运算后再产生中断

           − 支持“与”,“或”,“非”,不原生支持“异或”

  • 实现方式是,创建一个或多个布尔表达式,每个布尔表达式都可以产生中断请求

           − 共有 8 个输入变量,每个变量可以与任一个 PININT 输入配接

           − 同一变量可以在一个表达式中出现多次,

           − 例如(三人表决器):A&B | B&C | C&A

3.2 模式匹配引擎的  8 个输入变量(Slice)(如图 3-2-1 所示)

 
     

3.3 变量布尔运算的实现逻辑(如图 3-3-1 所示)

        


3.4 示例 三人表决器(如图 3-4-1 所示)

       


四、 PININT单引脚中断实验

4.1 实验目的:
       通过本实验,理解和掌握外部引脚中断配置的全过程、边沿触发中断的用法。

4.2 实验软/硬件环境搭建:

       − 硬件:LPC824Lite-V1.0(评估板)

       − 软件:SDK 从 NXP 官网下载(https://mcuxpresso.nxp.com/en/select);

           工程位置:..\..\..\driver_examples \pint\pin_interrupt\mdk\pint_pin_interrupt.uvprojx

4.3 实验描述:

       − 本实验把 S2 键所在的 PIO0_12 配置为上升沿触发中断,S4 键所在的 PIO0_1 配置为下降沿触发中断。

       − S2 按下后或者 S4 按下时在引脚中断 ISR 里设置软件标志——全局变量 g_pinIntFlags 的 bit 1,并在 while 循环里检查此标志,如果设置就反转 LED1。

4.4 实验结果:

       按下按键 S2 后,串口调试助手上会打印相关信息(外部中断源 1),并反转 LED1;按下按键 S4 时,立即打印相关信息(外部中断源 2),并反转 LED1。

4.5 实验代码:

       /*!

       * @brief Call back for PINT Pin interrupt 0-7.

       */

        void pint_intr_callback(pint_pin_int_t pintr, uint32_t pmatch_status)

       {

            g_pinIntFlags = true;

           PRINTF("\f\r\nPINT Pin Interrupt %d event detected.", pintr);}

       /*!

        * @brief Main function

      */

      int main(void)

      {

          /* Define the init structure for the output LED pin*/

          gpio_pin_config_t led_config = {

                 kGPIO_DigitalOutput,

                 0,

                 };

                 ……

                 /* Init output LED GPIO. */

                 GPIO_PortInit(GPIO, 0U);

           

                 /* Connect trigger sources to PINT */

                 //将外部中断源与对应引脚相连

                 SYSCON_AttachSignal(SYSCON, kPINT_PinInt1, DEMO_PINT_PIN_INT1_SRC);

                 SYSCON_AttachSignal(SYSCON, kPINT_PinInt2, DEMO_PINT_PIN_INT2_SRC);

                 ……

                 /* Initialize PINT */

                 //初始化 PINT 的外围设备

                 PINT_Init(PINT);

 

                 /* 设置外部中断源 1 为上升沿触发,并使能 */

                 /* Setup Pin Interrupt 1 for rising edge */

                 PINT_PinInterruptConfig(PINT, kPINT_PinInt1, kPINT_ PinIntEnableRiseEdge, pint_intr_callback);

                 /* Enable callbacks for PINT1 by Index */

                 PINT_EnableCallbackByIndex(PINT, kPINT_PinInt1);



                  /* 设置外部中断源 2 为下降沿触发,并使能 */

                  /* Setup Pin Interrupt 2 for falling edge */

                  PINT_PinInterruptConfig(PINT, kPINT_PinInt2, kPINT_PinIntEnableFallEdge, pint_intr_callback);

                  /* Enable callbacks for PINT2 by Index */

                  PINT_EnableCallbackByIndex(PINT, kPINT_PinInt2);

 

                  //LED 引脚配置,输出高电平

                  GPIO_PinInit(GPIO, 0U, 7U, &led_config);

                  GPIO_PinWrite(GPIO, 0U, 7U, 1);

                  ……

                        while (1)

                        {

                               __WFI();                       

                               if(g_pinIntFlags)

                               {

                                       GPIO_PortToggle(GPIO, 0U, 1u << 7U);

                                       g_pinIntFlags = false;

                                }

                      }

          }

 
五、 PININT 模式匹配引擎实验

5.1 实验目的:

          通过本实验,理解和掌握外部引脚中断配置成模式匹配引擎的全过程及用法。

5.2 实验软/硬件环境搭建:

         − 硬件:LPC824Lite-V1.0(评估板)

         − 软件:SDK 从 NXP 官网下载(https://mcuxpresso.nxp.com/en/select);

             工程位置:..\..\..\driver_examples \pint\pattern_match\mdk\pint_pattern_match.uvprojx

 

5.3 实验描述:

          − 本实验把 S2 键所在的 PIO0_12 连接到外部中断源 2,S4 键所在的 PIO0_1 连接到外部中断源 0。

          − 把外部中断源 0 的下降沿触发配置为单引脚中断;将外部中断源 0 的上升沿触发和外部中断源 2 的下降沿触发配置为模式匹配引擎。

 

5.4 实验结果:

       按下按键 S2,串口调试助手上不会打印;按下按键 S4,立即打印相关信息(外部中断源 0);按下按键 S4 后再按下 S2,打印相关信息(外部中断源 2)。

 

5.5 实验代码:

        /*!

         * @brief Call back for PINT Pin interrupt 0-7.

         */

        void pint_intr_callback(pint_pin_int_t pintr, uint32_t pmatch_status)

        {

            PRINTF("\f\r\nPINT Pin Interrupt %d event detected. PatternMatch status = %8b\r\n", pintr, pmatch_status);

        }

 

        /*!

         * @brief Main function

         */

        int main(void)

        {

            pint_pmatch_cfg_t pmcfg;

        ……

            /* Connect trigger sources to PINT */

              //将外部中断源与对应引脚相连

            SYSCON_AttachSignal(SYSCON, kPINT_PatternMatchInp0Src, kSYSCON_GpioPort0Pin1ToPintsel);

            SYSCON_AttachSignal(SYSCON, kPINT_PatternMatchInp1Src, kSYSCON_GpioPort0Pin12ToPintsel);

        ……

            /* Initialize PINT */

        //初始化 PINT 的外围设备

            PINT_Init(PINT);

 

            /*

        将模式匹配引擎变量 0 配置为单引脚中断

             设置变量 0 的外部中断源为外部中断源 0,下降沿触发,结果变量

        */

        /* configure kPINT_PatternMatchBSlice0 to show the single inputsrc */

            /* Setup Pattern Match Bit Slice 0 */

          pmcfg.bs_src    = DEMO_PINT_BSLICE0_SRC;

            pmcfg.bs_cfg    = kPINT_PatternMatchStickyFall;

            pmcfg.callback  = pint_intr_callback;

            pmcfg.end_point = true;

            PINT_PatternMatchConfig(PINT, kPINT_PatternMatchBSlice0, &pmcfg);

 

             /* Enable callbacks for PINT0 by Index */

            //使能外部中断源 0

            PINT_EnableCallbackByIndex(PINT, kPINT_PinInt0);

 

            /*

        将模式匹配引擎变量 1 和模式匹配引擎变量 2 配置为组合中断

              设置变量 1 的中断源为外部中断源 0,上升沿触发,中间变量

             设置变量 2 的中断源为外部中断源 2,下降沿触发,结果变量

        */

        /* configure kPINT_PatternMatchBSlice1 and kPINT_PatternMatchBSlice2 to show the combined inputsrc */

            /* Setup Pattern Match Bit Slice 1 */

            pmcfg.bs_src    = DEMO_PINT_BSLICE1_SRC;

            pmcfg.bs_cfg    = kPINT_PatternMatchStickyRise;

            pmcfg.callback  = pint_intr_callback;

            pmcfg.end_point = false;

            PINT_PatternMatchConfig(PINT, kPINT_PatternMatchBSlice1, &pmcfg);

 

            /* Setup Pattern Match Bit Slice 2 for falling edge detection */

            pmcfg.bs_src    = DEMO_PINT_BSLICE2_SRC;

            pmcfg.bs_cfg    = kPINT_PatternMatchStickyRise;

            pmcfg.callback  = pint_intr_callback;

            pmcfg.end_point = true;

            PINT_PatternMatchConfig(PINT, kPINT_PatternMatchBSlice2, &pmcfg);

 

            /* Enable callbacks for PINT2 by Index */

            //使能外部中断源 2

            PINT_EnableCallbackByIndex(PINT, kPINT_PinInt2);

 

            /* Enable PatternMatch */

             //使能模式匹配引擎

            PINT_PatternMatchEnable(PINT);

         ……

            while (1)

            {

                 __WFI();

            }

        }

 

 

★博文内容均由个人提供,与平台无关,如有违法或侵权,请与网站管理员联系。

★文明上网,请理性发言。内容一周内被举报5次,发文人进小黑屋喔~

评论