转帖: http://www.oschina.net/question/565065_115196?sort=time
实验目的: mini2440开发板上有6个按键,将其中的前4个按键设为外部中断方式,当按下K1时,LED1亮;当按下K2时,LED2亮;当按下K3时,LED3亮;当按下K4时,LED4亮。
首先我们先了解一下 mini2440 按键和LED接口:
GPBCON 地址: 0x56000010 (LED 灯可以参考流水灯的随笔)
按键接口电路如图2所示,当按键没有按下时,GPGx引脚为高电平;当按键按下时,引脚电平变为低电平。
外部中断文件布局:
该工程有三个模块组成。
按键模块主要包含 button.c 和 button.h
LED模块包含led.c和led.h。
中断处理模块主要包含 interrupt.c、interrupt.h、isrservice.c和isrservice.h文件。其中,interrupt.h和interrupt.c文件主要包含中断初始化函数,isrservice.c和isrservice.h文件主要包含中断处理函数。
_______________________________________________________________________________________________________________________________________________________________________
main.c 文件
1 #include"led.h" 2 #include"button.h" 3 #include"isrservice.h" 4 #include"interrupt.h" 5 6 7 int main() 8 { 9 Led_Init(); //初始化LED 10 KeyInt_Init(); //初始化按键 11 Irq_Init(); //初始化外部中断 12 while(1) //循环,等待中断发生 13 { 14 ; 15 } 16 }
————————————————————————————————————————————————————————————————————————————————————————————————————————————————
led.h 文件
1 #ifndef __LED_H__ 2 #define __LED_H__ 3 4 #include<s3c2440.h> 5 #define Led1_On() {GPBDAT&=(~(1<<5));} 6 #define Led1_Off() {GPBDAT|=(1<<5);} 7 #define Led2_On() {GPBDAT&=(~(1<<6));} 8 #define Led2_Off() {GPBDAT|=(1<<6);} 9 #define Led3_On() {GPBDAT&=(~(1<<7));} 10 #define Led3_Off() {GPBDAT|=(1<<7);} 11 #define Led4_On() {GPBDAT&=(~(1<<8));} 12 #define Led4_Off() {GPBDAT|=(1<<8);} 13 /**************************************************** 14 * 函数名称:void Led_Init(void) 15 * 全局变量:无 16 * 参数说明:无 17 * 返 回 值;无 18 * 功 能:设置GPN5-8为输出功能,初始化4个LED灯灭 19 *****************************************************/ 20 void Led_Init(void); 21 22 #endif
led.c 文件
1 #include<s3c2440.h> 2 3 /**************************************************** 4 * 函数名称:void Led_Init(void) 5 * 全局变量:无 6 * 参数说明:无 7 * 返 回 值;无 8 * 功 能:设置GPB5-8为输出功能,初始化4个LED灯灭 9 *****************************************************/ 10 void Led_Init(void) 11 { 12 GPBCON&=~((3<<10)|(3<<12)|(3<<14)|(3<<16)); 13 GPBCON|=((1<<10)|(1<<12)|(1<<14)|(1<<16));//设置GPB5-8口为输出功能 14 GPBUP&=~((1<<5)|(1<<6)|(1<<7)|(1<<8));//上拉电阻使能 15 GPBDAT|=(1<<5)|(1<<6)|(1<<7)|(1<<8);//令GPBDAT5-8均为高电平,即令4个led灯全灭 16 }
________________________________________________________________________________________________________________________________________________________________________________________________________
button.h 文件
1 #ifndef __BUTTON_H__ 2 #define __BUTTON_H__ 3 4 /**************************************************** 5 * 函数名称:void KeyInt_Init() 6 * 全局变量:无 7 * 参数说明:无 8 * 返 回 值;无 9 * 功 能:设置GPG0、3、5、6、7、11为外部中断输入功能 10 *****************************************************/ 11 void KeyInt_Init(void); 12 13 #endif
button.c 文件
1 /************************************************ 2 * mini2440板子上六个按键对应的GPIO和中断 3 * 按键 GPIO 中 断 4 * K1 GPG0 EINT8 5 * K2 GPG3 EINT11 6 * K3 GPG5 EINT13 7 * K4 GPG6 EINT14 8 * K5 GPG7 EINT15 9 * K6 GPG11 EINT19 10 ************************************************/ 11 12 #include<s3c2440.h> 13 #include"button.h" 14 15 #define KEY1_C (3<<0) 16 #define KEY2_C (3<<6) 17 #define KEY3_C (3<<10) 18 #define KEY4_C (3<<12) 19 20 #define KEY1 (2<<0) 21 #define KEY2 (2<<6) 22 #define KEY3 (2<<10) 23 #define KEY4 (2<<12) 24 25 /**************************************************** 26 * 函数名称:void KeyInt_Init() 27 * 全局变量:无 28 * 参数说明:无 29 * 返 回 值;无 30 * 功 能:设置GPG0、3、5、6、7、11为外部中断输入功能 31 *****************************************************/ 32 void KeyInt_Init(void) 33 { 34 GPGCON&=~(KEY1_C|KEY2_C|KEY3_C|KEY4_C); 35 GPGCON|=KEY1|KEY2|KEY3|KEY4; //将GPG0、3、5、6、7、11设为输入功能 36 GPGUP&=~((1<<0)|(1<<3)|(1<<5)|(1<<6)); 37 GPGDAT|=(1<<0)|(1<<3)|(1<<5)|(1<<6); //因为按下按键后,相应的GPIO口为0,所以初始化为高电平 38 }
________________________________________________________________________________________________________________________________________________________________________________________________________
interrupt.h 文件
1 #ifndef __INTERRUPT_H__ 2 #define __INTERRUPT_H__ 3 4 5 /**************************************************** 6 * 函数名称:void Irq_Init(void) 7 * 全局变量:无 8 * 参数说明:无 9 * 返 回 值;无 10 * 功 能:将Led1-4按键对应的中断屏蔽位置设为无效 11 *****************************************************/ 12 void Irq_Init(void); 13 14 #endif
interrupt.c 文件
1 /************************************************ 2 * mini2440板子上六个按键对应的GPIO和中断 3 * 按键 GPIO 中 断 4 * K1 GPG0 EINT8 5 * K2 GPG3 EINT11 6 * K3 GPG5 EINT13 7 * K4 GPG6 EINT14 8 * K5 GPG7 EINT15 9 * K6 GPG11 EINT19 10 ************************************************/ 11 12 #include<s3c2440.h> 13 #include"interrupt.h" 14 15 16 /**************************************************** 17 * 函数名称:void Irq_Init(void) 18 * 全局变量:无 19 * 参数说明:无 20 * 返 回 值;无 21 * 功 能:将Led1-4按键对应的中断屏蔽位置设为无效 22 *****************************************************/ 23 void Irq_Init(void) 24 { 25 //对于EINT8,EINT11,EINT13,EINT14,需要在EINTMASK寄存器使能它们 26 EINTMASK&=(~(1<<8))&(~(1<<11))&(~(1<<13))&(~(1<<14)); 27 //这4个外部中断的优先级是相同的,EINT8_23都接仲裁器的REQ1引脚 28 //所以不用像韦东山程序里那样再设置优先级了 29 30 //EINT8,EINT11,EINT13,EINT14使能 31 INTMSK&=(~(1<<5)); 32 }
_____________________________________________________________________________________________________________________________________________________________________________________________________
irservice.h 文件
1 #ifndef __ISRSERVICE_H__ 2 #define __ISRSERVICE_H__ 3 4 /**************************************************** 5 * 函数名称:void __irq IRQ_Handler(void) 6 * 全局变量:无 7 * 参数说明:无 8 * 返 回 值;无 9 * 功 能:中断服务函数,必须加__irq 10 *****************************************************/ 11 void __irq IRQ_Handler(void); 12 13 #endif
isrservice.c 文件
1 #include<s3c2440.h> 2 #include"isrservice.h" 3 #include"led.h" 4 5 void delay(void); 6 /**************************************************** 7 * 函数名称:void __irq IRQ_Handler(void) 8 * 全局变量:无 9 * 参数说明:无 10 * 返 回 值;无 11 * 功 能:中断服务函数,必须加__irq 12 *****************************************************/ 13 void __irq IRQ_Handler(void) 14 { 15 unsigned long oft=INTOFFSET; 16 unsigned long val; 17 18 19 val=EINTPEND; //EINT寄存器,它的位x为1时,表示EINT已经发生(x为4——23)。 20 if(val&(1<<8)) //K1被按下,LED1被点亮 21 { 22 Led1_On();delay();Led1_Off(); 23 } 24 25 if(val&(1<<11)) //K2被按下,LED2被点亮 26 { 27 Led2_On();delay();Led2_Off(); 28 } 29 30 if(val&(1<<13)) //K3被按下,LED3被点亮 31 { 32 Led3_On();delay();Led3_Off(); 33 } 34 if(val&(1<<14)) //K4被按下,LED4被点亮 35 { 36 Led4_On();delay();Led4_Off(); 37 } 38 //清除中断 39 if(oft==5) 40 EINTPEND=(1<<8)|(1<<11)|(1<<13)|(1<<14); //清除EINTPEND寄存器,往某位写入1即可清楚此位 41 SRCPND=1<<oft; //清除SRCPND寄存器,往某位写入1即可清楚此位 42 INTPND=1<<oft; //清除INTPND寄存器,往某位写入1即可清楚此位 43 //注意:清除顺序很重要:先是EINTPEND,然后是SRCPND,最后是INTPND 44 } 45 /**************************************************** 46 * 函数名称:static void delay(void) 47 * 全局变量:无 48 * 参数说明:无 49 * 返 回 值;无 50 * 功 能:延时函数,前边加static是为了限制该函数只在 51 * 本文件中使用 52 *****************************************************/ 53 static void delay(void) 54 { 55 int i,j; 56 for(i=0;i<100;i++) 57 for(j=0;j<10;j++); 58 }
总共 10个文件(包括初始化的 s3c2440.s 文件)
当然 我们调试的时候 ,把 .sct 文件改了一下,才能在 norflash 里面运行
; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************************* LR_ROM1 0x00000000 0x0200000 { ; load region size_region ER_ROM1 0x00000000 0x0200000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_RAM1 0x30000000 0x04000000 { ; RW data .ANY (+RW +ZI) } RW_IRAM1 0x40000000 0x00001000 { .ANY (+RW +ZI) } }
可以测试了,但是 只有 三个按键可以控制灯 亮灭,所以自己需要思考修改,现在看自己的了。