- UID
- 1023166
- 性别
- 男
- 来自
- 燕山大学
|
S3C2440-按键
使用按键控制跑马灯。扫描哪个按键被按下有两种方式。一个是查询扫描,一个是中断扫描。查询扫描就是不断轮询哪个引脚变成低电平了。中断扫描主要通过中断方式实现。
查询扫描程序:
#define rGPFCON (*(volatile unsigned *)0x56000050)
#define rGPFDAT (*(volatile unsigned *)0x56000054)
#define rGPFUP (*(volatile unsigned *)0x56000058)
#define rGPBCON (*(volatile unsigned *)0x56000010)
#define rGPBDAT (*(volatile unsigned *)0x56000014)
#define rGPBUP (*(volatile unsigned *)0x56000018)
int KeyMain(){
void Delay(unsigned int x);
unsigned char ledtab[]={0xf7,0xef,0xdf,0xbf};
unsigned int t;
rGPBCON = 0xffc3fc; //0,2 为输入,3,4,5,6为输出
rGPBDAT = 0x7fe;
rGPFCON = 0xd54c; //5,6为输入
rGPFDAT = 0xff;
rGPBUP &= 0xf9f;
rGPFUP &= 0x82;
while(1){
while(((rGPBDAT & 0x7ff) == 0x7fe) && ((rGPFDAT & 0xff) == 0xff)); //不断轮询,如果找到往下执行,看是那个被按下
if((rGPBDAT & (0x1<<5)) == 0){
rGPFDAT = ledtab[0];
Delay(70);
}
if((rGPBDAT & (0x1<<6)) == 0){ //取出rGPBDAT的第6位,看是不是0
rGPFDAT = ledtab[1];
Delay(70);
}
if((rGPFDAT & (0x1<<0)) == 0){
rGPFDAT = ledtab[2];
Delay(70);
}
if((rGPFDAT & (0x1<<2)) == 0){
rGPFDAT = ledtab[3];
Delay(70);
}
rGPFDAT = 0xff; //恢复,以便重新响应按键
}
}
void Delay(unsigned int x){
unsigned int i, j, k;
for(i =0; i <= x; i++)
for(j = 0; j <= 0xff; j++)
for(k = 0; k <= 0xff; k++)
;
}
中断扫描程序:
#define rGPFCON (*(volatile unsigned *)0x56000050)
#define rGPFDAT (*(volatile unsigned *)0x56000054)
#define rGPFUP (*(volatile unsigned *)0x56000058)
#define SRCPND (*(volatile unsigned *)0x4a000000)
#define INTPND (*(volatile unsigned *)0x4a000010)
#define INTMSK (*(volatile unsigned *)0x4a000008)
#define _ISR_STARTADDRESS 0x33ffff00
#define pISR_EINT0 (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT2 (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define U32 unsigned int
void delay(U32 x){
int i,j,k;
for(i = 0; i < x; i++)
for(j = 0; j < 0xff; j++)
for(k = 0; k < 0xff; k++)
;
}
void __irq EINT0_ISR(void){
SRCPND |= 1; //SRCPND 通过写入数据清零,如果不清零,会反复进行请求
INTPND |= 1; //INDPND 通过置1清零
rGPFDAT = 0xf7;
delay(1000);
rGPFDAT = 0xff;
delay(1000);
}
void __irq EINT2_ISR(void){ //使用__irq这个关键字定义终端服务例程,这样系统会自动为我们保留一些变量,并能在中断处理完后正确的返回
SRCPND |= 1<<2;
INTPND |= 1<<2;
rGPFDAT = 0xef;
delay(1000);
rGPFDAT = 0xff;
delay(1000);
}
int Main(){
rGPFCON &= 0xfc0c; //0 2 3 4
rGPFCON |= (1<<1)|(1<<5)|(1<<6)|(1<<8);
rGPFUP = 0xe2;
SRCPND |= (1<<0)|(1<<2);
INTPND |= (1<<0)|(1<<2);
INTMSK &= ("(0x1<<0)) & ("(0x1<<2)); //开中断
pISR_EINT0 = (U32)EINT0_ISR; //给中断服务例程入口地址
pISR_EINT2 = (U32)EINT2_ISR;
while(1);
return 0;
}
李万鹏 |
|