打印

为什么没有触发中断?

[复制链接]
3721|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gavin_li|  楼主 | 2009-6-27 15:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "2410addr.h"

#define LED1                (1<<5)                // rGPB[5] =1 ;
#define LED2                (1<<6)                // rGPB[6] =1 ;
#define LED3                (1<<7)                // rGPB[7] =1 ;
#define LED4                (1<<8)                // rGPB[8] =1 ;

#define KEY1                (1<<1)                // rGPF[1] =1 ;
#define KEY2                (1<<4)                // rGPF[4] =1 ;
#define KEY3                (1<<2)                // rGPF[2] =1 ;
#define KEY4                (1<<0)                // rGPF[0] =1 ;


void __irq IRQ_KEY(void){
   
   ClearPending(BIT_EINT4_7);
   rEINTPEND = 0xffffff;
   
   rGPFUP = 0xf800;                            //  KEY [7:0] => PU En
   rGPFCON=0xfcc0;                            //KEY[7:0] => INPUT;
   
   if ( !(rGPFDAT & KEY1) )
       rGPBDAT=rGPBDAT & ~LED1;
       
    if ( !(rGPFDAT & KEY2) )
       rGPBDAT=rGPBDAT & ~LED2;
    
    if ( !(rGPFDAT & KEY3) )
       rGPBDAT=rGPBDAT & ~LED3;
    
    if ( !(rGPFDAT & KEY4) )
       rGPBDAT=rGPBDAT & ~LED4;
       
     rGPFCON=0xfcc0;
}

void EINT_Init(void){   
//我这里的按键接口是
// k4-GPF0 -- 设置为中断应该是10
// k3-GPF2 -- 10
// k2-GPF4 -- 10
// k1-GPF1 -- 10 
   rGPFCON = 0xfeea;//111111 10 11 10 10 10

   rEXTINT0 = 0x002092; //set eint0,1,2,4 falling edge interrupt
   // 0 010 000 010 010 010
  
   
   pISR_EINT4_7 = (unsigned int)IRQ_KEY;
   rPRIORITY= 0x00000000; 
   ClearPending(BIT_EINT4_7);
   
   rEINTPEND = 0xffffff; //clear interrupt flag   
   rINTMOD=0x00000000;
   rINTMSK &= (~BIT_EINT4_7); 
   rEINTMASK = 0x000fffe8;//enable EINT0,EINT1,EINT2,EINT4
   //11...111 0 1 0 0 0   
}
   
void Main(void){
    
    rGPBCON = 0x015550;
    rGPBUP  = 0x7ff;   
   
    rGPBDAT = 0xfff;
    
    EINT_Init();
    while (1); 
   
 } 

我这程序错在哪里呢?怎么按键没反应,按k2就出现异常。其他键没什么反应。
 
 

相关帖子

沙发
gavin_li|  楼主 | 2009-6-27 15:18 | 只看该作者

修改阿南的按键例子的。哪里出问题呢

使用特权

评论回复
板凳
阿南| | 2009-6-27 23:27 | 只看该作者

中断问题的查找应该有:

触发信号,中断标志,ARM状态,IRQ入口,处理程序等等

使用特权

评论回复
地板
lelee007| | 2009-6-28 00:02 | 只看该作者

看datasheet吧

南哥的程序都木有问题

俺验证过的

使用特权

评论回复
5
有风| | 2009-6-28 00:49 | 只看该作者

初始化时,rGPFCON = 0xfeea

ISR中,rGPFCON=0xfcc0
为什么?

使用特权

评论回复
6
lelee007| | 2009-6-28 03:07 | 只看该作者

看datasheet啦

rGPFCON = 0xfeea:
GPF7、6、5、3 reserved
GPF4、2、1、0作外部中断

--------------------

rGPFCON=0xfcc0:
GPF7、6、5、3 reserved
GPF4、2、1、0作输入

使用特权

评论回复
7
lelee007| | 2009-6-28 03:12 | 只看该作者

初始化时将GPF4、2、1、0作为外部中断

中断产生了,进入ISR后,将GPF的4、2、1、0脚作为输入,将端口电平读进来判断是哪个引脚上的按键按下

就这样了

使用特权

评论回复
8
lelee007| | 2009-6-28 03:16 | 只看该作者

对了,你买的是南哥的板子么?

硬件配置和南哥的一样么?

估计是你的GPF4、2、1、0接的不是按键吧,如果是这样,你按下了GPF上复用的EINT当然不会产生了

而且你真正使用的中断又没配置,所以压根就不会有中断产生了

看看你的硬件原理图,看看是否跟你程序里配置的一致

使用特权

评论回复
9
有风| | 2009-6-28 08:45 | 只看该作者

退出ISR时应该也要将rGPFCON配置为0xfeea吧

void __irq IRQ_KEY(void)

  rGPFCON=0xfcc0;
  // scan key
  rGPFCON=0xfeea;

不然IRQ_KEY岂不是只能运行一次?
而且这个按键程序都没有防抖.

使用特权

评论回复
10
ywjianghu| | 2009-6-28 09:45 | 只看该作者

我的一个经验

你用的是否是ads1.2开发环境啊?
我用ads加j-link,程序进不了中断。由于自己是初学,就怀疑是程序没写好,一直看手册,也看不出什么问题。
后来,才知道是ads设置的原因,需要去掉semihosting选项。这个设置有些奇怪,就是设好后要马上退出再重启axd。如果不这样,呵呵,白设。为此绕了很多弯路。不过,也有好处,把vic部分看的很熟悉了。

使用特权

评论回复
11
gavin_li|  楼主 | 2009-6-28 13:34 | 只看该作者

我的GPIO程序没问题,为什么中断程序会有问题呢?

#include "2410addr.h"

#define LED1     (1<<5)                // rGPB[5] =1 ;
#define LED2     (1<<6)                // rGPB[6] =1 ;
#define LED3     (1<<7)                // rGPB[7] =1 ;
#define LED4     (1<<8)                // rGPB[8] =1 ;

#define KEY1     (1<<1)                // rGPF[1] =1 ;
#define KEY2     (1<<4)                // rGPF[4] =1 ;
#define KEY3     (1<<2)                // rGPF[2] =1 ;
#define KEY4     (1<<0)                // rGPF[0] =1 ;


void Main(void){
    
    rGPBCON = 0x015550;
    rGPBUP  = 0x7ff;
    rGPFUP = 0xf800;                                //  KEY [7:0] => PU En
    rGPFCON=0xfcc0;                            //KEY[7:0] => INPUT;
    
    
   
    while (1){ 
    rGPBDAT = 0xfff;
    
    if ( !(rGPFDAT & KEY1) )
       rGPBDAT=rGPBDAT & ~LED1;
       
    if ( !(rGPFDAT & KEY2) )
       rGPBDAT=rGPBDAT & ~LED2;
    
    if ( !(rGPFDAT & KEY3) )
       rGPBDAT=rGPBDAT & ~LED3;
    
    if ( !(rGPFDAT & KEY4) )
       rGPBDAT=rGPBDAT & ~LED4;
    
   }
 }  

使用特权

评论回复
12
gavin_li|  楼主 | 2009-6-28 13:40 | 只看该作者

我的按键是接在GPF0,1,2,4上

上面的程序可以验证啊。启动代码直接用南哥的。
搞了两天都没看出问题所在。

我对AXD调试器也不熟悉,只会看register.地址变量不知道怎么看。Memory窗口可以看吗?请顺便帮我看这个问题
https://bbs.21ic.com/club/bbs/list.asp?boardid=35&page=1&t=3359347&tp=%u8BF7%u6559%u5982%u4F55%u4F7F%u7528AXD%u67E5%u770B%u5B9A%u4E49%u53D8%u91CF%u7684%u503C%u548C%u8BBE%u7F6E%u65AD%u70B9

使用特权

评论回复
13
gavin_li|  楼主 | 2009-6-28 15:18 | 只看该作者

这几行代码看不懂?

ClearPending(BIT_EINT8_23);
//这里BIT_EINT8_23是固定的值(0x1<<5)吗?为什么要在_irq IRQ_KEY函数里执行。
#define ClearPending(bit) {
                rSRCPND = bit;   //设置中断源未决寄存器
                rINTPND = bit;   //设置中断源未决寄存器
                rINTPND;        //这是什么意思呢?
                }       
//Wait until rINTPND is changed for the case that the ISR is very short.

EINT_Init函数中
pISR_EINT8_23 = (unsigned int)IRQ_KEY;//这句话有什么作用?ClearPending(BIT_EINT8_23); // 清除中断标志位又清?


阿南的源代码如下:
#include "2410addr.h"

#define KEY1 (1 << 3)//GPG3,EINT11
#define KEY2 (1 << 6)//GPG6,EINT14//GPG7,EINT15
#define KEY3 (1 << 7)//GPG7,EINT15//GPG8,EINT16
#define KEY4 (1 << 11)//GPG11,EINT19

#define LED1 (1 << 4)//GPF4
#define LED2 (1 << 5)//GPF5
#define LED3 (1 << 6)//GPF6
#define LED4 (1 << 7)//GPF7

/*******************************************************************************************
函数原形:void __irq IRQ_KEY(void)
功能描述:键盘中断处理程序,当产生键盘中断后将读取键值,重新刷新LED显示
参    数:无            
*******************************************************************************************/
void __irq IRQ_KEY(void)
{
    unsigned int i;
    ClearPending(BIT_EINT8_23);
    rEINTPEND = 0xffffff;
    rGPGCON = rGPGCON & (~((3 << 6) | (3 << 12) | (3 << 14) | (3 << 22)));//设置为输入状态
    if (rGPGDAT & KEY1){//当KEY1被按下时,LED亮,否则灭
        rGPFDAT |= LED1;//熄灭LED1 
    }
    else {
        rGPFDAT &= ~LED1;//点亮LED1
    }
    if (rGPGDAT & KEY2){
        rGPFDAT |= LED2; 
    }
    else {
        rGPFDAT &= ~LED2; 
    }
    if (rGPGDAT & KEY3){
        rGPFDAT |= LED3; 
    }
    else {
        rGPFDAT &= ~LED3; 
    }
    if (rGPGDAT & KEY4){
        rGPFDAT |= LED4; 
    }
    else {
        rGPFDAT &= ~LED4; 
    }
    rGPGCON |= (2 << 6) | (2 << 12) | (2 << 14) | (2 << 22);//重新设置外部中断输入功能
}
 
/*******************************************************************************************
函数原形:void __irq IRQ_KEY(void)
功能描述:键盘中断初始化,将按键输入管脚设置成外部中断输入功能,双边沿触发,IRQ中断模式
参    数:无            
*******************************************************************************************/
void EINT_Init(void)
{
    rGPGCON &= (~((3 << 6) | (3 << 12) | (3 << 14) | (3 << 22)));
    rGPGCON |= (2 << 6) | (2 << 12) | (2 << 14) | (2 << 22);
    //rGPGCON[23:22],[15:14],[13:12],[7:6]=10b,即GPG[11,7,6,3]为外部中断输入功能
    rEXTINT1 = rEXTINT1 & (~((7 << 12) | (7 << 24) | (7 << 28))) | ((6 << 12) | (6 << 24) | (6 << 28));
    //EINT11,EINT14,EINT15下降沿触发中断    
    rEXTINT2 = rEXTINT2 & (~(7 << 12)) | (6 << 12);//EINT19下降沿触发中断    
    pISR_EINT8_23 = (unsigned int)IRQ_KEY;
    rPRIORITY = 0x00000000;        // 使用默认的固定的优先级
    ClearPending(BIT_EINT8_23); // 清除中断标志位
    rEINTPEND = 0xffffff;
    rINTMOD = 0x00000000;        // 所有中断均为IRQ中断
    rINTMSK &= (~BIT_EINT8_23); // 使能外部中断8_23 
    rEINTMASK &= (~((1 << 11) | (1 << 14) | (1 << 15) | (1 << 19)));//使用能EINT11,EINT14,EINT15,EINT17
}

void Main(void){ 
    rGPFCON = (rGPFCON & 0x00ff) | 0x5500;//设置GPF[7:4](LED[4:1])为输出功能
    rGPFDAT |= LED1 | LED2 | LED3 | LED4;
    EINT_Init();
    while (1);
}  

使用特权

评论回复
14
gavin_li|  楼主 | 2009-6-28 15:55 | 只看该作者

电路图如下

使用特权

评论回复
15
有风| | 2009-6-28 17:29 | 只看该作者

都是中断的一些寄存器设置而已

ClearPending(BIT_EINT8_23);//设置BIT_EINT8_23的中断寄存器啊
#define ClearPending(bit) {
                rSRCPND = bit;   //设置中断源未决寄存器
                rINTPND = bit;   //设置中断源未决寄存器
                rINTPND;        //没有用的
                }    
pISR_EINT8_23 = (unsigned int)IRQ_KEY;//指定中断函数的地址

使用特权

评论回复
16
gavin_li|  楼主 | 2009-6-28 22:13 | 只看该作者

修改TQ2440的按键中断代码

发现要加入MMU的ini函数才行。下面的代码调试通过

#include "def.h"
#include "2440addr.h"
#include "mmu.h"
#include "option.h"

#define LED1                (1<<5)                // rGPB[5] =1 ;
#define LED2                (1<<6)                // rGPB[6] =1 ;
#define LED3                (1<<7)                // rGPB[7] =1 ;
#define LED4                (1<<8)                // rGPB[8] =1 ;

void __irq IRQ_KEY(void){
   
   unsigned int r;
    EnterCritical(&r);
   if(rINTPND==BIT_EINT1)
    {
       ClearPending(BIT_EINT1);
    }
    if(rINTPND==BIT_EINT4_7)
    {
        ClearPending(BIT_EINT4_7);
        if(rEINTPEND&(1<<4))
        {        
            rEINTPEND |= 1<< 4;
        }
    }
    if(rINTPND==BIT_EINT0)
    {        
       ClearPending(BIT_EINT0);
    }
    if(rINTPND==BIT_EINT2)
    {        
       ClearPending(BIT_EINT2);
    }

    if( (rGPFDAT&(1<< 0)) == 0 )
    {
        rGPBDAT = rGPBDAT & ~(LED4);            //亮LED4
        
    }
    else if( (rGPFDAT&(1<< 2)) == 0 )
    {
        rGPBDAT = rGPBDAT & ~(LED3);            //亮LED3
        
    }
    else if( (rGPFDAT&(1<<4)) == 0 )
    {
        rGPBDAT = rGPBDAT & ~(LED2);            //亮LED2
        
    }
    else if( (rGPFDAT&(1<< 1)) == 0 )
    {
        rGPBDAT = rGPBDAT & ~(LED1);            //亮LED1
        
    }
    else
    {
        rGPBDAT = rGPBDAT & ~0x1e0|0x1e0;   //LED[8:5] => 1;
        
    }
     ExitCritical(&r);
}

void EINT_Init(void){
   rGPFCON = rGPFCON & (~((3<<4)|(3<<0)|(3<<8)|(3<<2))) | ((2<<4)|(2<<0)|(2<<8)|(2<<2)) ;        //GPF4,2,1,0 set EINT
    
    rEXTINT0 &= ~(7|(7<<4)|(7<<8)|(7<<16));    
    rEXTINT0 |= (0|(0<<4)|(0<<8)|(0<<16));        //set eint0,1,2,4 falling edge int


    rEINTPEND |= (1<<4);                            //clear eint 4
    rEINTMASK &= ~(1<<4);                        //enable eint 4
    ClearPending(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);
    pISR_EINT0 = pISR_EINT1 = pISR_EINT2 = pISR_EINT4_7 = (U32)IRQ_KEY;
    EnableIrq(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);
   
}
   
void Main(void){

    MMU_Init();
    
    rGPBCON = 0x015550;
    rGPBUP  = 0x7ff;   
   
    rGPBDAT = 0xfff;
    
    rGPFCON = 0x55aa;
    rGPFUP  = 0xff;
    
    rINTMOD=0x0;      // All=IRQ mode
    rINTMSK=BIT_ALLMSK;      // All interrupt is masked.
    
    EINT_Init();
    while (1); 
   
 } 

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

150

帖子

0

粉丝