标签:
转帖: 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) } }
可以测试了,但是 只有 三个按键可以控制灯 亮灭,所以自己需要思考修改,现在看自己的了。
外部按键 控制 LED 中断 (参考 http://www.oschina.net/question/565065_115196?sort=time )
标签:
原文地址:http://www.cnblogs.com/shengruxiahua/p/4891179.html