分类: 嵌入式
2011-05-10 14:44:42
按键控制LED(中断)
一、开发环境
开发板:mini2440
集成环境:ADS1.2
仿真器:J-LINK V8
二、按键中断步骤
参照中断流程图,更容易理解下面的步骤
1,初始化寄存器GPGCON
设置对应的GPG0,GPG3,GPG5,GPG6,GPG7,GPG11为外部中断的功能接口,它们分别对应外部中断EINT8,EINT11,EINT13,EINT14,EINT15,EINT19
2,设置外部按键中断的触发方式
这里包括EXTINT1和EXTINT2两个寄存器的配置,分别对EINT8,EINT11,EINT13,EINT14,EINT15,EINT19六个外部中断设定!按键没按下时为高电平,被按下后为低电平;所以设定为低电平触发!
3,设定各个按键的中断源不屏蔽!
这里就是设置寄存器EINTMASK,将对应EINT8,EINT11,EINT13,EINT14,EINT15,EINT19的位,置0!也就是不屏蔽! 置1表示屏蔽,初始化时为屏蔽的!
4,设定寄存器EINTPEND,SRCPND,INTPND
官方设置是这样的: 将EINTPEND,SRCPND,INTPND中对应的EINT8,EINT11,EINT13,EINT14,EINT15,EINT19位全部置1处理;根据2440文档9-33,14-8,14-15的说明,1=Occur interrupt.表示中断发生!It is cleard by writing “1” PS:因为是中断的初始化,复位后怎么会立马有中断请求呢?可能我没能理解这里置1的意思.所以,我对这三个寄存器初始化时 没有设置,取默认的复位值,即0x00
5,将中断服务函数的地址传给对应的中断向量处(重点理解,解释pISR_EINT8_23=(U32)extint8_23)
代码为pISR_EINT8_23=(U32)extint8_23;//extint8_23为中断服务函数的地址!pISR_EINT8_23为指向中断向量表的HandleEINT8_23(2440init.s中).
//#define pISR_EINT8_23 (_ISR_STARTADDRESS+0x34)
这里的_ISR_STARTADDRESS=0x33ffff00,为什么是这个数呢,在网上查了很多,有位网友是这样解释的:_ISR_STARTADDRESS=_RAM_ENDADDRESS-0x100,那么_RAM_ENDADDRESS又是多少呢(参考2440用户手册1.3.2),因为2440采用了2片32M的SDRAM芯片并接形成32位总线数据宽度。物理起始地址为0x30000000,再加上64M的空间,就是_RAM_ENDADDRESS的值0x34000000,那这里为什么是_RAM_ENDADDRESS-0x100呢,为什么是减去0x100(256字节的空间)呢?谁能帮我解释下,谢谢
6,设定外部按键总中断源EINT8_23不屏蔽!
注意这里设置的是寄存器INTMSK,而不是EINTMASK;我把INTMSK称为中断源的总屏蔽寄存器,EINTMASK称为各个中断的屏蔽寄存器,不知道叫起来晕不晕,呵呵
7,等待中断发生,或者结束
8,最后关闭总中断源,设置寄存器INTMSK
以上的步骤并非本人所写,借用了,感谢cumt2009的贴子
使用中断前,必须对RAM进行初始化,所以在代码中添加了MMU。异常向量表缺省时放在0x0,当从SDRAM启动时,异常向量表没有放在该地址,而是在0x3000 0000,当然程序也就找不到中断的入口地址。所以需要MMU来对异常向量表重新映射到0x0地址。-----这是本人的理解,仅供参考。
仿真调试的时候,你的程序是运行在sdram里面的,也就是0x3000_0000处开始运行
你的中断向量表通过仿真器已经放在了0x3000_0000处,
打开mmu是为了把0x3000_0000地址处的值映射到0x0的地方,因为你的中断向量表是保存在0x0开始的地方,当中断发生时的第一时间CPU会去0x0地方查中断向量表看是发生了什么中断,是reset还是IRQ还是FIQ还是取数据终止或取指令终止按键外部中断是IRQ中断,然后CPU会去IRQ开始的地方找到你的中断服务函数,这个时候轮到了你的中断服务函数运行的时间了。所以你不打开MMU就不会进入中断服务函数
参考网址:
三、打开ADS,编写代码
这一步请参考http://blog.chinaunix.net/space.php?uid=25119314&do=blog&id=298350,作者转载的,很不错的博文,感谢 蓝点IT工坊
程序附件: key_led_simple.zip
水平有限,如果有错误的地方,请指正,thanks
cjok.liao@gmail.com