裸奔程序之外部中断检测按键

原创 2012年08月12日 15:56:09
      开发环境:ADS1.2

      实验实验功能:在TQ2440开发板上,利用外部中断模式检测按键是否按下,

                               如果某按键被按下则点亮对应某个LED。

——————————————————————————————————

#include"2440addr.h"
#include"option.h" //这个文件中定义了中断服务程序的起始地址


#define  LED1_ON (rGPBDAT &=~(1<<5))
#define  LED1_OFF (rGPBDAT |=(1<<5) )
#define  LED2_ON (rGPBDAT &=~(1<<6))
#define  LED2_OFF (rGPBDAT |=(1<<6))
#define  LED3_ON (rGPBDAT &=~(1<<7))
#define  LED3_OFF (rGPBDAT |=(1<<7))
#define  LED4_ON (rGPBDAT &=~(1<<8))
#define  LED4_OFF (rGPBDAT |=(1<<8))

void Delay(void)
{
        int i;
        for(i=0;i<100000;i++);
}


/****************************外部中断处理函数**********************************/

void __irq IRQ_KEY1(void)
{

        rSRCPND |=(1<<1); //清除中断标志位
        rINTPND |=(1<<1);

        LED1_ON;
        Delay();
        LED1_OFF; 
}

void __irq IRQ_KEY2(void)
{

       rSRCPND |=(1<<4);          //清除中断标志位
       rINTPND |=(1<<4);
       rEINTPEND |=(1<<4);       //清除ENIT4的中断标志位

       LED2_ON;
       Delay();
       LED2_OFF;
}

void __irq IRQ_KEY3(void)
{
      rSRCPND |=(1<<2);         //清除中断标志位
      rINTPND |=(1<<2);

      LED3_ON;
      Delay();
      LED3_OFF; 
}

void __irq IRQ_KEY4(void)
{

      rSRCPND |=1<<0;         //清除中断标志位 
      rINTPND |=1<<0;

      LED4_ON;
      Delay();
      LED4_OFF; 
}
/**************************外部中断初始化函数******************************/ 
void Eint_Init(void)
{
      rGPFCON &=~(0x33f);
      rGPFCON |=0x22a;              //设置GPF0、1、2、4为中断输入功能
 
      rEXTINT0 = 0x20222;         //ENIT0、1、2、4下降沿触发中断
 
      rSRCPND = 0x17;              //清除ENIT0、1、2、4的中断标志位
      rINTPND = 0x17;               //清除ENIT0、1、2、4的中断标志位
      rEINTPEND=(1<<4);         //清除ENIT4的中断标志位
 
      rINTMOD=0x0;                   //所有中断为IRQ中断
    
      rINTMSK &= ~0x17;                   //ENIT0、1、2、4中断服务有效(这里就是使能外部中断)
      
rEINTMASK &= ~(1<<4);           //EINT4中断服务有效


      pISR_EINT0 = (unsigned)IRQ_KEY4;         //设置各中断服务子程序地址
      pISR_EINT1 = (unsigned)IRQ_KEY1;
      pISR_EINT2 = (unsigned)IRQ_KEY3;
      pISR_EINT4_7 = (unsigned)IRQ_KEY2;
}

void Main(void)
{
       rGPBCON &=~((3<<10)|(3<<12)|(3<<14)|(3<<16));   //对GPBCON[10:17]清零
       rGPBCON |=((1<<10)|(1<<12)|(1<<14)|(1<<16));      //设置GPB5~8为输出
       rGPBUP &=~((1<<5)|(1<<6)|(1<<7)|(1<<8));             //设置GPB5~8的上拉功能
       rGPBDAT |=(1<<5)|(1<<6)|(1<<7)|(1<<8);                //关闭LED

       Eint_Init();
       while(1);
}

——————————————————————————————————

      我们来简单描述一下S3C2440的中断内容,它总共有60个中断源,分为中断源和子中断源;下图为中断源种类:

   下图为子中断源种类:

      中断控制器所用到的中断寄存器有八个:

     中断处理框图如下所示(重点):

现在主要说下外部中断(其寄存器使用说明在数据手册的输入输出端口章节)

S3C2440有24个外部中断,GPF0--GPF7对应于外部中断EINT0--EINT7,GPG0--GPG15对应于外部中断EINT8--EINT23,支持上升沿、下降沿、高电平、低电平、双边沿触发。

设置外部中断的一般步骤

1、选择管脚功能为外部中断功能
     2、设置触发方式
     3、清中断源挂起寄存器,中断服务寄存器(可选,防止原有中断干扰)
     4、设置中断模式(IRQ、FRQ, 默认为IRQ)
     5、设置中断优先级(可选,一般默认)
     6、打开外部中断屏蔽
     7、设置中断服务入口程序

下面我们开始分析main.c这个程序,首先从main函数开始;

进入main函数后,首先是初始化LED,这四条语句在前面LED已经讲过,这里不再重复;接着调用Eint_Init();我们进入Eint_Init();函数看到,

首先是 rGPFCON &=~(0x33f);   rGPFCON |=0x22a;   执行完这二句后,GPF0、1、2、4被设置为中断输入功能。

接着执行rEXTINT0 = 0x20222; 意思是将ENIT0、1、2、4配置为下降沿触发中断。

再执行rSRCPND = 0x17;  意思是清除ENIT0、1、2、4的中断标志位,SRCPND这个寄存器是中断请求标识的寄存器,如果SRCPND中哪一位置为1表示相应中断源有请求,如果要清除某一位则向相应位置写入1。

rINTPND = 0x17;  也是清除ENIT0、1、2、4的中断标志位  INTPND同样也是中断源请求寄存器,如果有中断发生,对应位会自动置1,如果要清除某一位也是向相应位写入1。

rEINTPEND=(1<<4); //清除ENIT4的中断标志位

rINTMOD=0x0;   //所有中断为IRQ中断  ,INITMOD为中断模式寄存器,有FIQ快速中断模式,当INTMOD被置1时为FIQ模式,否则为IRQ模式,默认为IRQ模式。

rINTMSK &= ~0x17; //ENIT0、1、2、4中断服务有效(这里就是使能外部中断)  INTMSK负责总的中断向量屏蔽,当被置1时则被屏蔽,否则没有被屏蔽。

rEINTMASK &= ~(1<<4);//EINT4中断服务有效    EINTMASK负责具体某一中断向量是否被屏蔽,当被置1时则被屏蔽,否则没有被屏蔽。

pISR_EINT0 = (unsigned)IRQ_KEY4; //设置各中断服务子程序地址

我们在2440addr.h头文件里面找到  #define pISR_EINT0  (*(unsigned *)(_ISR_STARTADDRESS+0x20))

我们在option.inc汇编头文件里面找到 _ISR_STARTADDRESS EQU 0x33ffff00  从上面二句我们知道,这是中断服务的起始地址。

pISR_EINT0是一个中断入口地址变量,把该中断处理函数的首地址传递给该变量,即中断入口地址。

一般来说,使用__irq这个关键词来定义中断处理函数,这样系统会为我们自动保存一些必要的变量,并能够在中断处理函数执行完后正确地返回。还需要注意的是,中断处理函数不能有返回值,也不能传递任何参数。

void __irq IRQ_KEY4(void)
      {
             rSRCPND |=1<<0; //清除中断标志位 
             rINTPND |=1<<0;

             LED4_ON;
             Delay();
             LED4_OFF; 
     }

这是一个外部中断0的处理函数,

rSRCPND |=1<<0;       

rINTPND |=1<<0;

执行完这二句后表示源挂起中断标志和具体某中断挂起标志都被清楚,其他外部中断1、2、4处理函数亦是如此。

———————————————————————————————————

到这里,这个main.c程序就讲解完毕啦。裸奔程序之外部中断检测按键 - 23号的wj - 伟坚的博客你懂了吗?


一种基于中断的按键检测方法

slam_navigation原创: 按键检测是初学单片机的同学玩的前几个例程,按键的种类有许多(普通按钮,矩阵键盘等等),按键检测的方法也有许多。对于普通按钮当然你会说设计一个外围电路通过GPIO...
  • slam_navigation
  • slam_navigation
  • 2017-02-18 12:43:30
  • 1295

按键的编程—中断检测按键

基于轮询的方法效率会比较低,在大型的系统中,或者实时性要求比较高的系统中应该慎重使用。而使用中断的编程就更好的实现了按键和cpu的异步工作,可以很好的解决效率问题。不过后面我们可以看到,这也不是最好啊...
  • a5436137
  • a5436137
  • 2010-07-02 16:59:00
  • 999

STM32外部中断测试

STM32外部中断测试   文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.23 MCU:STM32F10...
  • jdh99
  • jdh99
  • 2012-05-29 14:41:02
  • 5203

裸奔程序之外部中断检测按键

开发环境:ADS1.2       实验实验功能:在TQ2440开发板上,利用外部中断模式检测按键是否按下,                                如果某按键被按下则点亮对...
  • lwj103862095
  • lwj103862095
  • 2012-08-12 15:56:09
  • 27934

S5P4418裸机系列教程之<em>按键中断</em>测试

S5P4418裸机系列教程之<em>按键中断</em>测试,按下<em>按键</em>,触发<em>中断</em>,并控制一盏LED灯 综合评分:5 收藏评论(3)举报 所需: 3积分/C币 下载个数: 21 开通VIP 立即下载 ...
  • 2018年04月11日 00:00

mini2440-128M开发板裸奔系列——外部中断EINT8-23 六按键中断

  • 2010年04月16日 18:45
  • 120KB
  • 下载

STM8S---外部中断应用之长按键识别

STM8常用中断指令 开总中断 _asm(“rim”); 禁止中断 _asm(“sim”); 进入停机模式 _asm(“halt”); 中断返回 _asm(“iret”); 等待中断 _as...
  • FreeApe
  • FreeApe
  • 2015-07-21 18:32:40
  • 4977

linux字符驱动之中断按键

在上一节中,我们讲解了如何自动创建设备节点,实现一个查询方式的按键驱动。测试的时候,大家都看到了,使用查询式的方法,占用CPU的利用率高达99%,那么有没有好的办法来取代这惨不忍睹的方法呢?答案当然是...
  • lwj103862095
  • lwj103862095
  • 2013-12-23 21:53:46
  • 8477

STM32按键中断学习记录

习惯了调程序遇到问题就在网上各种搜罗,常常能从大牛的记录或者回复中得到启发,没想到有一天自己也开始写博客记录下学习的点滴。 学习STM32的这一个月颇有点闭门造车的意思,因为周围没有学习这个开发板的朋...
  • mingtianwendy
  • mingtianwendy
  • 2015-07-13 15:34:18
  • 3020

外部中断的按键,软件滤波实现方法

外部中断的按键,软件滤波实现方法
  • lile777
  • lile777
  • 2016-01-18 11:56:37
  • 1780
收藏助手
不良信息举报
您举报文章:裸奔程序之外部中断检测按键
举报原因:
原因补充:

(最多只允许输入30个字)