查看: 2186|回复: 2

[原创] 【LPC11U68】7. GPIO输入—Interrupt

[复制链接]
  • TA的每日心情
    奋斗
    昨天 20:36
  • 签到天数: 1484 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93044
    最后登录
    2024-5-7
    发表于 2018-11-5 13:55:27 | 显示全部楼层 |阅读模式
    本帖最后由 stm1024 于 2018-11-5 14:31 编辑

    前面测试了GPIO的输入,当然都说了那个例子实用意义不大,接下来就是真正有点意思的,采用中断方式的按键输入。

    老规矩,上代码,简单粗暴。
    1. #include "board.h"
    2. #define INT_IDX 5
    3. #define IRQ_NAME    PIN_INT5_IRQn   
    4. #define IRQ_HANDLER  PIN_INT5_IRQHandler

    5. int main()
    6. {
    7.     //clock for GPIO
    8.     LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 6);
    9.    
    10.     //red led,GPIO output
    11.     LPC_GPIO->DIR[2] |= 1UL << 17;
    12.    
    13.     //SW1, GPIO input
    14.     LPC_GPIO->DIR[0] &= ~(1UL<<1);
    15.    
    16.     //clock for GPIO pin interrupt
    17.     LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 19);
    18.    
    19.     //GPIO pin interrupt select register
    20.     LPC_SYSCTL->PINTSEL[INT_IDX]=1;//select port0 pin 1
    21.     LPC_IOCON->PIO0[1]=IOCON_MODE_PULLUP;

    22.     LPC_PININT->ISEL &= ~(1<<INT_IDX);
    23.     LPC_PININT->IST=(1<<INT_IDX);
    24.     LPC_PININT->SIENF = (1<<INT_IDX);
    25.    
    26.     NVIC_ClearPendingIRQ(IRQ_NAME);
    27.         NVIC_EnableIRQ(IRQ_NAME);
    28.    
    29.     while(1)
    30.     {
    31.         __wfi();
    32.     }
    33. }
    复制代码
    然后是代码分析。
    1.宏定义
    INT_IDX:这个是选择了用哪一个中断号。LPC11U68的外部中断有8个,这个宏定义是采用第五个。
    IRQ_NAME 、 IRQ_HANDLER是与中断5想配套的中断名字和中断处理函数。
    因此,你需要修改中断号的时候,就要同步修改。


    2.中断源配置
    使用什么,其时钟肯定是要使能的(这就是语句LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 19);)的作用。
    接下来是比较有意思的地方。
    LPC_SYSCTL->PINTSEL[INT_IDX]=1;//select port0 pin 1
    这一句是,把GPIO Port0的PIN1作为中断输入(注意前面已经配置其GPIO方向为Input)。
    LPC_IOCON->PIO0[1]=IOCON_MODE_PULLUP;

    IO控制中,把GPIO Port0的PIN1配置为IOCON_MODE_PULLUP模式,为何呢?因为我按下按键(也就是有中断)的时候,电平肯定是一个低电平,所以常规情况下先上拉,如果是反过来,则应该是使用PULLDOWN
    3.中断模式配置
    中断的来源是知道了,现在要看看配置什么样的行为造成一次中断
    LPC_PININT->ISEL &= ~(1<<INT_IDX);
    LPC_PININT->IST=(1<<INT_IDX);
    LPC_PININT->SIENF = (1<<INT_IDX);
    第一句是中断模式,我们知道一般的外部中断有两种情况,一种是电平(高电平、低电平)触发,一种是边沿(上升沿、下降沿)触发,这里选择0,表明采用的是边沿触发。
    第二句是中断的状态寄存器,我们先把边沿检测清除,避免一开始就来一个中断(这个例子中其实这句可以省略)
    第三句则是使能下降沿中断(如果想用上升沿,有对应的SIENR寄存器,R和F分别是Rising和Falling的首写字母)。

    4.中断管理
    ARM中由NVIC对所有的中断进行统一管理。
    NVIC_ClearPendingIRQ(IRQ_NAME);
    NVIC_EnableIRQ(IRQ_NAME);
    这两句分别是清理pending的中断,避免不能正常进入中断,以及使能中断名。

    5.中断处理函数
    1. void IRQ_HANDLER(void)
    2. {
    3.         LPC_GPIO->NOT[2]=(1<<17);//toggle
    4.     LPC_PININT->IST=(1<<INT_IDX);
    5. }
    复制代码
    这个函数其实就是中断后指令跳转的地方,首先我们把红色的LED灯翻转,然后,清除这个中断标志,另一种做法是进入之后失能该中断,退出前使能该中断, 避免反复进入此中断。像这样:
    1. void IRQ_HANDLER(void)
    2. {
    3.         NVIC_DisableIRQ(IRQ_NAME);
    4.     LPC_GPIO->NOT[2]=(1<<17);//toggle
    5.     LPC_PININT->IST=(1<<INT_IDX);
    6.     NVIC_EnableIRQ(IRQ_NAME);
    7. }
    复制代码
    编译、下载以后,你可以按那个三色LED附近的按键,LED灯应该能够toggle了。
    2018-11-05_135409.png
    附件,拿去玩吧: LPC11Prj.zip (1.68 MB, 下载次数: 16)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3305

    主题

    6552

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32095
    最后登录
    2024-5-8
    发表于 2018-11-9 11:25:03 | 显示全部楼层
    学习下
    签到签到
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 20:36
  • 签到天数: 1484 天

    [LV.10]以坛为家III

    203

    主题

    2万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    93044
    最后登录
    2024-5-7
     楼主| 发表于 2019-2-26 18:17:15 | 显示全部楼层
    ~~~~~~~~~~~~~~~~~~~~
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-5-8 15:42 , Processed in 0.145968 second(s), 24 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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