在线时间6060 小时
UID3426478
注册时间2017-9-25
NXP金币5610
TA的每日心情 | 奋斗 昨天 20:36 |
---|
签到天数: 1484 天 [LV.10]以坛为家III
超级版主
- 积分
- 93044
- 最后登录
- 2024-5-7
|
本帖最后由 stm1024 于 2018-11-5 14:31 编辑
前面测试了GPIO的输入,当然都说了那个例子实用意义不大,接下来就是真正有点意思的,采用中断方式的按键输入。
老规矩,上代码,简单粗暴。
- #include "board.h"
- #define INT_IDX 5
- #define IRQ_NAME PIN_INT5_IRQn
- #define IRQ_HANDLER PIN_INT5_IRQHandler
- int main()
- {
- //clock for GPIO
- LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 6);
-
- //red led,GPIO output
- LPC_GPIO->DIR[2] |= 1UL << 17;
-
- //SW1, GPIO input
- LPC_GPIO->DIR[0] &= ~(1UL<<1);
-
- //clock for GPIO pin interrupt
- LPC_SYSCTL->SYSAHBCLKCTRL |= (1 << 19);
-
- //GPIO pin interrupt select register
- LPC_SYSCTL->PINTSEL[INT_IDX]=1;//select port0 pin 1
- LPC_IOCON->PIO0[1]=IOCON_MODE_PULLUP;
- LPC_PININT->ISEL &= ~(1<<INT_IDX);
- LPC_PININT->IST=(1<<INT_IDX);
- LPC_PININT->SIENF = (1<<INT_IDX);
-
- NVIC_ClearPendingIRQ(IRQ_NAME);
- NVIC_EnableIRQ(IRQ_NAME);
-
- while(1)
- {
- __wfi();
- }
- }
复制代码 然后是代码分析。
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.中断处理函数
- void IRQ_HANDLER(void)
- {
- LPC_GPIO->NOT[2]=(1<<17);//toggle
- LPC_PININT->IST=(1<<INT_IDX);
- }
复制代码 这个函数其实就是中断后指令跳转的地方,首先我们把红色的LED灯翻转,然后,清除这个中断标志,另一种做法是进入之后失能该中断,退出前使能该中断, 避免反复进入此中断。像这样:
- void IRQ_HANDLER(void)
- {
- NVIC_DisableIRQ(IRQ_NAME);
- LPC_GPIO->NOT[2]=(1<<17);//toggle
- LPC_PININT->IST=(1<<INT_IDX);
- NVIC_EnableIRQ(IRQ_NAME);
- }
复制代码 编译、下载以后,你可以按那个三色LED附近的按键,LED灯应该能够toggle了。
附件,拿去玩吧:
LPC11Prj.zip
(1.68 MB, 下载次数: 16)
|
|