S3C2440-按键

发布时间:2011-3-25 14:27    发布者:techshare
关键词: 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;
}

李万鹏
本文地址:https://www.eechina.com/thread-59918-1-1.html     【打印本页】

本站部分文章为转载或网友发布,目的在于传递和分享信息,并不代表本网赞同其观点和对其真实性负责;文章版权归原作者及原出处所有,如涉及作品内容、版权和其它问题,我们将根据著作权人的要求,第一时间更正或删除。
您需要登录后才可以发表评论 登录 | 立即注册

厂商推荐

  • Microchip视频专区
  • 我们是Microchip
  • 更佳设计的解决方案——Microchip模拟开发生态系统
  • 深度体验Microchip自动辅助驾驶应用方案——2025巡展开启报名!
  • Cortex-M4外设 —— TC&TCC结合事件系统&DMA优化任务培训教程
  • 贸泽电子(Mouser)专区

相关视频

关于我们  -  服务条款  -  使用指南  -  站点地图  -  友情链接  -  联系我们
电子工程网 © 版权所有   京ICP备16069177号 | 京公网安备11010502021702
快速回复 返回顶部 返回列表