LPC824-外部引脚中断

发布者:数字火箭最新更新时间:2023-10-03 来源: elecfans关键字:LPC824  外部事件 手机看文章 扫描二维码
随时随地手机看文章

外部中断作为处理器响应外部事件的通道,在控制系统中起着非常重要的作用。从前面的讨论中我们知道,在NVIC中有8个外部中断源,下面就来讨论一下这8个外部中断的使用情况。
LPC824的每一根引脚都可以响应一个外部中断,所以理论上有多少个引脚就有多少个外部中断。但由于LPC824采用了引脚挂接外部中断源的形式,所以并不是所有的引脚都可以同时设置为外部中断引脚。在LPC824中,可同时响应的外部中断源只有8个(即NVIC的8路引脚中断),所以同时只能有8个外部中断引脚在工作,但这8个外部中断引脚可选择从PIO0_0至PIO0_28中的任意一根。

LPC824外部引脚中断所涉及到的寄存器如下表所示。

从上表中可以看到,在LPC824的引脚中断控制中,一共使用了13个寄存器。下面是这些寄存器组所对应的结构体形式(位于头文件LPC82x.h中)。

typedef struct {       
  __IO uint32_t  ISEL; 
  __IO uint32_t  IENR; 
  __O  uint32_t  SIENR;
  __O  uint32_t  CIENR;
  __IO uint32_t  IENF; 
  __O  uint32_t  SIENF;
  __O  uint32_t  CIENF;
  __IO uint32_t  RISE; 
  __IO uint32_t  FALL; 
  __IO uint32_t  IST;  
  __IO uint32_t  PMCTRL;
  __IO uint32_t  PMSRC;
  __IO uint32_t  PMCFG;
} LPC_PIN_INT_Type;

因为引脚中断寄存器组的基址为0xA0004000,所以要将基址指针强制转换为上述结构体,还必须要加上下面的定义。
#define LPC_PIN_INT_BASE                0xA0004000UL
#define LPC_PIN_INT                     ((LPC_PIN_INT_Type *) LPC_PIN_INT_BASE)

下面先对其中与外部引脚中断相关的10个寄存器的功能进行讨论,另外3个与模式匹配相关的寄存器后面再专门讨论。先来看引脚中断模式寄存器ISEL,其字节地址为0xA0004000,下表给出了它的全部位结构。

(1)第0到7位为8个外部中断引脚的模式选择位,置0时,对应的外部中断被设置为边沿触发型,置1时,设置为电平触发型,默认为边沿触发型。
(2)第8到31位为保留位。

下表给出的是引脚中断电平或上升沿中断使能寄存器IENR的全部位结构,其字节地址为0xA0004004。

(1)第0到7位为引脚中断的上升沿或电平中断选择位,置0时,对应的外部中断被禁用上升沿或电平中断,置1时,使能上升沿或电平中断,默认为禁用上升沿或电平中断。
(2)第8到31位为保留位。

下表给出的是引脚中断电平或上升沿中断置位寄存器SIENR的全部位结构,其字节地址为0xA0004008。SIENR寄存器实际上为了对IENR寄存器进行单独的置位操作而设立的,如果是按字(或字节)操作直接写IENR寄存器即可。

(1)在第0到7位中写入1会置位IENR寄存器中相对应的位,从而使能上升沿或电平中断,置0时无影响。
(2)第8到31位为保留位。

下表给出的是引脚中断电平或上升沿中断清零寄存器CIENR的全部位结构,其字节地址为0xA000400C。CIENR寄存器实际上为了对IENR寄存器进行单独的清零操作而设立的,如果是按字(或字节)操作直接写IENR寄存器即可。

(1)在第0到7位中写入1会清零IENR寄存器中相对应的位,从而禁用上升沿或电平中断,置0时无影响。
(2)第8到31位为保留位。

下表给出的是引脚中断有效电平或下降沿中断使能寄存器IENF的全部位结构,其字节地址为0xA0004010。

(1)第0到7位为引脚中断的下降沿或有效中断电平选择位,置0时,对应的外部中断被禁用下降沿中断或置位有效中断电平为低电平,置1时,使能下降沿中断使能或置位有效中断电平为高电平,默认为禁用下降沿中断或置位有效中断电平为低电平。
(2)第8到31位为保留位。

下表给出的是引脚中断有效电平或下降沿中断置位寄存器SIENF的全部位结构,其字节地址为0xA0004014。SIENF寄存器实际上为了对IENF寄存器进行单独的置位操作而设立的,如果是按字(或字节)操作直接写IENF寄存器即可。

(1)在第0到7位中写入1会置位IENF寄存器中相对应的位,从而使能下降沿中断或置位有效中断电平为高电平,写0时无影响。
(2)第8到31位为保留位。

下表给出的是引脚中断有效电平或下降沿中断清零寄存器CIENF的全部位结构,其字节地址为0xA0004018。CIENF寄存器实际上为了对IENF寄存器进行单独的清零操作而设立的,如果是按字(或字节)操作直接写IENF寄存器即可。

(1)在第0到7位中写入1会清零IENF寄存器中相对应的位,从而禁用下降沿中断或置位有效中断电平为低电平,写0时无影响。
(2)第8到31位为保留位。

下表给出的是引脚中断上升沿寄存器RISE的全部位结构,其字节地址为0xA000401C。

(1)在第0到7位中写入1会清除相应引脚的上升沿检测标记,从而为下一次上升沿检测作准备,写0时无影响。若在相应的位上读取到1,则表示自复位或上一次向该位写1清除起,对应的引脚上检测到了上升沿,读取到0,则表示对应引脚上未检测到上升沿。
(2)第8到31位为保留位

下表给出的是引脚中断下降沿寄存器FALL的全部位结构,其字节地址为0xA0004020。

(1)在第0到7位中写入1会清除相应引脚的下降沿检测标记,从而为下一次下降沿检测作准备,写0时无影响。若在相应的位上读取到1,则表示自复位或上一次向该位写1清除起,对应的引脚上检测到了下降沿,读取到0,则表示对应引脚上未检测到下降沿。
(2)第8到31位为保留位。

下表给出的是引脚中断状态寄存器IST的全部位结构,其字节地址为0xA0004024。

(1)在第0到7位中写入1时,对于边沿触发型中断,将会清除对应引脚的上升和下降沿检测,对于电平触发型中断,将会切换对应引脚上的有效电平,写0时无影响。若在相应的位上读取到1,则表示对应的中断引脚上有正在请求的外部中断,读取到0,则表示对应的中断引脚上无正在请求的外部中断。
(2)第8到31位为保留位。

注意,电平触发的中断会由硬件在有效电平消失时自动清除标志,并没有软件清除电平中断标志的操作。

以上10个寄存器就是LPC824中与外部引脚中断相关寄存器,其实除了这10个寄存器以外,还有1个名为PINTSEL的寄存器也与外部引脚中断密切相关,只不过它不在上述寄存器组中,而是位于SYSCON模块中。下表就给出了引脚中断选择寄存器PINTSEL的全部位结构,这样的寄存器一共有8个(PINTSEL0~PINTSEL7),其字节地址从0x40048178到0x40048194。

(1)第0到5位用来选择外部中断的引脚编号,范围从PIO0_0到PIO0_28共29根引脚。
(2)第6到31位为保留位。

注意,PINTSEL寄存器一共有8个,也即LPC824的外部引脚中断同时最多只能使用8个,但每一个外部中断都可以在全部PIO0_0到PIO0_28端口中选择引脚。 相当于PINTSEL0~PINTSEL7是8个外部中断源,具体哪个中断源使用哪个引脚,是根据PINTSEL寄存器的配置来确定的。

在讨论完了寄存器的功能后,下面就来分解一下把某个引脚配置为外部中断模式的具体步骤:
1、确定要配置为中断模式的引脚,然后在SYSCON模块的PINTSEL寄存器中进行选择设置,一共可以配置8个外部中断引脚。例如,执行“LPC_SYSCON->PINTSEL0 |= 0x01;”语句后,就把PIO0_1引脚设置为了外部中断引脚。
2、确定是电平触发还是边沿触发,通过ISEL寄存器进行选择配置。例如,执行“LPC_PIN_INT->ISEL &= ~0x01;”语句后,就把PIO0_1引脚设置为边沿触发方式(其实默认就是边沿触发方式,此句也可不写)。
3、若上一步配置成电平触发,则需要确定是低电平触发还是高电平触发,若是边沿触发,则需要确定是上升沿触发还是下降沿触发,通过IENR或IENF寄存器进行执行配置。例如,执行“LPC_PIN_INT->IENR |= 0x01;”语句后,就把PIO0_1引脚设置为上升沿触发方式;执行“LPC_PIN_INT->IENF |= 0x01;”语句后,就把PIO0_1引脚设置为下降沿触发方式。
4、在第3步中,还可以通过访问SIENR和CIENR寄存器来更改IENR寄存器中的某一位,通过访问SIENF和CIENF寄存器来更改IENF寄存器中的某一位。SIENR、CIENR和SIENF、CIENF这四个寄存器其实是IENR和IENF寄存器的伴侣寄存器,用来优化位操作,以避免对IENR和IENF寄存器直接执行“读—改—写”的操作,提高效率。
5、使能NVIC中的相关外部中断。例如,执行“NVIC_EnableIRQ(PIN_INT0_IRQn);”语句后,就使能了PIO0_1上的外部引脚中断。
6、在中断服务程序中,需要清除原有的外部中断标记,以保证下一次外部中断顺利触发,通过访问RISE寄存器来清除上升沿中断标记,通过访问FALL寄存器来清除下降沿标记。例如,执行“LPC_PIN_INT->RISE |= 0x01;”语句后,PIO0_1原来的上升沿中断标记就被清除了。执行“LPC_PIN_INT->FALL |= 0x01;”语句后,PIO0_1原来的下降沿中断标记就被清除了。
7、在第6步中,也可以通过访问IST寄存器来清除边沿(包括上升沿和下降沿)触发的标记。执行“LPC_PIN_INT->IST |= 0x01;”语句后,PIO0_1原来的边沿中断标记就被清除了。

上述步骤也可通过下图来描述。

最后需要说明一点,即使某个引脚并不作为GPIO使用,也能配接到PININT的中断源上。比如:要自动探测4个I2C接口中哪一个被连接到主机上,即可以把它们4个的SCL线所在的IO引脚分别配接到4路PININT中断上。通信时,发生哪个中断,就认为连接到了哪个I2C接口上。而此时,IO引脚并没有作为GPIO使用,而是作为I2C的SCL信号接口。

此外,对于外部引脚中断,在MDK5的开发环境中有特定的入口函数形式,比如对于PINTSEL0的中断,函数形式如下所示。
 void PIN_INT0_IRQHandler(void)
{
       PINTSEL0中断服务程序部分
}

下面来看一个外部引脚中断的实际例子,电路原理图如下所示。

在上面的电路中,两个按键S1和S2分别接到了引脚PIO0_4和PIO0_1上,并且都为其配置了上拉阻。现在要求按下S1时,对LED1状态进行取反,按下S2时,对LED2状态进行取反,其中S1采用上升沿方式检测,S2采用下降沿方式检测。完整代码如下:

#include
//************************端口初始化***********************************
void Port_init(void)
{
LPC_GPIO_PORT->DIRSET0 = (1<<7) | (1<<13); //设置端口为输出方向
LPC_GPIO_PORT->SET0 = (1<<7) | (1<<13); //熄灭LED
}
//***************************主函数************************************
int main(void)
{
Port_init(); //调用端口初始化
LPC_SYSCON->PINTSEL0 = 0x1;//选择PIO0_1作为外部中断引脚
LPC_SYSCON->PINTSEL1 = 0x4;//选择PIO0_4作为外部中断引脚
// LPC_PIN_INT->ISEL &= ~0x3; //边沿触发
LPC_PIN_INT->IENR |= 0x1; //PINTSEL0上升沿使能
LPC_PIN_INT->IENF |= 0x2; //PINTSEL1下降沿使能
NVIC_EnableIRQ(PIN_INT0_IRQn);//使能PINTSEL0中断
NVIC_EnableIRQ(PIN_INT1_IRQn);//使能PINTSEL1中断
while(1)
{
;
}
}
//*********************PINTSEL0中断(S2)*****************************
void PIN_INT0_IRQHandler(void)
{
LPC_GPIO_PORT->NOT0 = 0x2000; //LED2取反
LPC_PIN_INT->RISE |= 0x1;
}
//*********************PINTSEL1中断(S1)*****************************
void PIN_INT1_IRQHandler(void)
{
LPC_GPIO_PORT->NOT0 = 0x80; //LED1取反
LPC_PIN_INT->FALL |= 0x2;
}

把程序编译后下载到LPC824中,初始状态LED都不亮,按下S1,LED1仍然不亮,松开S1,LED1亮,证明上升沿有效,再次按下S1,LED1仍然亮,松开S1,LED1熄灭,证明上升沿有效。 按下S2,LED2亮,松开S2,LED2仍然亮,证明下降沿有效,再次按下S2,LED2熄灭,松开S2,LED2仍然熄灭,证明下降沿有效。


关键字:LPC824  外部事件 引用地址:LPC824-外部引脚中断

上一篇:LPC824-系统定时器SysTick
下一篇:采用处理器实现便携式振动测试分析仪的改进设计

推荐帖子

mpu6050读初始化时配置的寄存器,但是读出的值与写入的不一致
mpu6050读初始化时配置的寄存器,但是读出的值与写入的不一致,这是什么原因呢?mpu6050读初始化时配置的寄存器,但是读出的值与写入的不一致有卖方提供的例程?用于那种开发板上?这种一般严格按照DATASHEET上的时序操作不会出现什么问题的。或许楼主可以描述的再仔细一些楼主我也遇到这样的问题,你解决了吗 解决了,就是IIC的一个接受应答的引脚的输入输出的引脚没有配置好
哈哈哈哼 传感器
如何设计电源模块
现在在设计一个电路,整体由±12V电源供电,但其中有芯片AD603(AGC电路模块)需要±5V来供电,,那么应该如何设计电源模块呢??如何设计电源模块如果±5V供电电流不大(你那个AD603芯片),例如10mA以内,那么使用7805和7905是比较简单的方法,甚至可以考虑78L05和79L05。7805和7905分别是+12V转=5V及-12V转-5V,那±12V供电部分如何设计呢在请教一个问题哦:RS422转TTL电平应该如何设计呢,用什么芯片比较好呢?还有TTL转RS422该如何设计
xxhhzz 电源技术
TMS320C6678多核间通信代码
TMS320C6678多核间通信代码TMS320C6678多核间通信代码
Aguilera 微控制器 MCU
win ce Platform Builder安装问题
wincePlatformBuilder5.0与VS2005安装在同一台机器有没有冲突,如果有,怎么解决?谢谢!wincePlatformBuilder安装问题没有。没有,安装在同一分区都没问题.先装PB,后装VS2005安装分区需要保留10G以上的剩余空间(具体大小跟你选项有关系),系统分区要1G以上剩余空间谢谢。
pcbaggio 嵌入式系统
【平头哥RVB2601开发板试用体验】 设计外围CAN通信测试板
这篇没有测试,设计了硬件扩展部分,在开发板扩展口上设计外围CAN通信测试板。一、测试板设计图片二、打样回来的PCB板图【平头哥RVB2601开发板试用体验】设计外围CAN通信测试板挺好,能继续开工了板子焊接完成图: 加上Can,这成本不低呀,看来是花了大价钱的老板了。 学习嘛
TL-LED 玄铁RISC-V活动专区
简单的课程设计~~~~~~~~89C51电子秤的设计
多亏各位前辈一步步的提点,顺利完成了软件的课程设计,但是现在更令我头疼的硬件又来了,对于硬件每次都是考试前死记硬背勉强过关,我只能说对于它,我是完全入不了门,所以请各位多多指教了(1)设计智能电子秤的软硬件,实现如下功能。(2)能随时检测在称重盘上物体的重量,并显示出来。(3)根据输入的单价,计算出需要的金额。并显示出来。(4)在此基础上的物体的累加,可以直接计算第二种物体的重量,和累计金额(5)重量和价格要求精确到小数点后三位。(6)
evilsop 嵌入式系统
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved