前言
本文基于S3C2440开发板所写的按键中断
一、中断过程
1、初始化。①设置中断,让它能够发出中断信号
②设置中断控制器,让它能发出中断给CPU
③设置CPU,CPSR有I位,它是总开关
2、处理时,要分辨中断源
3、处理完,清中断
二、关键代码
代码如下(示例):
#include "s3c2440_soc.h"
/* SRCPND 用来显示哪个中断产生了, 需要清除对应位
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTMSK 用来屏蔽中断, 1-masked
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTPND 用来显示当前优先级最高的、正在发生的中断, 需要清除对应位
* bit0-eint0
* bit2-eint2
* bit5-eint8_23
*/
/* INTOFFSET : 用来显示INTPND中哪一位被设置为1
*/
/*初始化中断控制器*/
void interrupt_init(void) {
INTMSK &= ~((1<<0) | (1<<2) | (1<<5));
}
/*初始化按键的外部中断*/
void key_eint_init(void) {
/* 配置GPIO为中断引脚 */
GPFCON &= ~((3 << 0) | (3 << 4));
GPFCON |= ((2 << 0) | (2 << 4)); //S2和S3被设置为中断引脚
GPGCON &= ~((3 << 6) | (3 << 22));
GPGCON |= ((2 << 6) | (2 << 22)); //S4和S5被设置为中断引脚
/* 设置中断触发方式 ,双边沿触发*/
EXTINT0 &= ~((7 << 0) | (7 << 8)); //清零
EXTINT0 |= ((7 << 0) | (7 << 8)); //清零
EXTINT1 &= ~(7 << 12);
EXTINT1 |= (7 << 12);
EXTINT2 &= ~(7 << 12);
EXTINT2 |= (7 << 12);
/* 设置EINTMASK使能eint11,19 */
EINTMASK &= ~((1 << 11) | (1 << 19));
}
/* 读EINTPEND分辨率哪个EINT产生(eint4~23)
* 清除中断时, 写EINTPEND的相应位
*/
void key_eint_irq(int irq) {
unsigned int val = EINTPEND;
if(0 == irq) { //外部中断0:s2控制D12
//控制D12
if (!(GPFDAT & ( 1 << 0 )) ) { //if(GPDAT & (1<<0) ==0 )
//D12(GPF6)灯亮
GPFDAT &= ~( 1 << 6 );
} else {
//D12(GPF6)灯灭
GPFDAT |= ( 1 << 6 );
}
} else if (2 == irq) {//外部中断2:s3 控制D11
//控制D11
if (!(GPFDAT & ( 1 << 2 )) ) {
//D11(GPF5)灯亮
GPFDAT &= ~( 1 << 5 );
} else {
//D11(GPF5)灯灭
GPFDAT |= ( 1 << 5 );
}
} else if(5 == irq) {//外部中断8-23,eint11->s4控制 D10,eint19->s5 控制所有LED
if(val & (1 << 11)) { //外部中断11发生
//控制D10
if (!(GPGDAT & ( 1 << 3 )) ) {
//D10(GPF4)灯亮
GPFDAT &= ~( 1 << 4 );
} else {
//D10(GPF4)灯灭
GPFDAT |= ( 1 << 4 );
}
} else if (val & (1 << 19)){ //外部中断19发生
if(GPGDAT & (1 << 11)) { //松开
GPFDAT |= ( (1 << 4) | (1 << 5) | (1 << 6));//全部灯熄灭
} else {
GPFDAT &= ~( (1 << 4) | (1 << 5) | (1 << 6) );//全部灯亮
}
}
}
EINTPEND = val;
return ;
}
void handle_irq_c() {
/* 分辨终中断源 */
int bit = INTOFFSET;
/*调用对应的处理函数*/
if(0 == bit || 2 == bit || 5 == bit) { //外部中断0/2/8-23
key_eint_irq(bit);
}
/* 清中断:从源头开始清 */
SRCPND = (1 << bit);
INTPND = (1 << bit);
}