打印

关于S3C2440中断请教

[复制链接]
2761|13
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
prodigals|  楼主 | 2012-2-29 19:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//=============================================================================
// File Name : 2440addr.h
// Function  : TQ2440 Define Address Register
// Revision  : 1.0
//=============================================================================
//#define _RAM_STARTADDRESS   0x30000000
#define _ISR_STARTADDRESS   0x33ffff00     
//#define _MMUTT_STARTADDRESS   0x33ff8000
//#define _STACK_BASEADDRESS   0x33ff8000
//#define HEAPEND     0x33ff0000
//#define _NONCACHE_STARTADDRESS   0x31000000

#ifndef __2440ADDR_H__
#define __2440ADDR_H__

#define rGPBCON    (*(volatile unsigned *)0x56000010) //Port B control
#define rGPBDAT    (*(volatile unsigned *)0x56000014) //Port B data
#define rGPBUP     (*(volatile unsigned *)0x56000018) //Pull-up control B
#define rGPFCON    (*(volatile unsigned *)0x56000050) //Port F control
#define rGPFDAT    (*(volatile unsigned *)0x56000054) //Port F data
#define rGPFUP     (*(volatile unsigned *)0x56000058) //Pull-up control F
#define rEINTPEND  (*(volatile unsigned *)0x560000a8) //External interrupt pending
#define rEXTINT0   (*(volatile unsigned *)0x56000088)
#define BIT_EINT0  (0x1)
#define BIT_EINT1  (0x1<<1)
#define BIT_EINT2  (0x1<<2)
#define BIT_EINT4_7  (0x1<<4)
#define rSRCPND     (*(volatile unsigned *)0x4a000000) //Interrupt request status
#define rINTMSK     (*(volatile unsigned *)0x4a000008)
#define rINTPND     (*(volatile unsigned *)0x4a000010) //Interrupt request status
__inline void ClearPending(int bit)
{
register i;
rSRCPND = bit;
rINTPND = bit;
i = rINTPND;
}

#define pISR_EINT0  (*(unsigned *)(_ISR_STARTADDRESS+0x20))
#define pISR_EINT1  (*(unsigned *)(_ISR_STARTADDRESS+0x24))
#define pISR_EINT2  (*(unsigned *)(_ISR_STARTADDRESS+0x28))
#define pISR_EINT4_7  (*(unsigned *)(_ISR_STARTADDRESS+0x30))
#define EnableIrq(bit)  rINTMSK &= ~(bit)
#define rEINTMASK  (*(volatile unsigned *)0x560000a4) //External interrupt mask

#endif

/*****************启动程序Init.s******************
WTCON EQU 0x53000000
IMPORT ledMain
AREA Init,CODE,READONLY
CODE32
ENTRY

;打开IQR
mrs r2,CPSR
bic r2,r2,#0x80
msr CPSR_cxsf,r2

ldr r0, =WTCON  ; WATCHDOG寄存器,R/W,复位值0x8021
mov r1, #0x0   
str r1, [r0]    ; 写入0,禁止WATCHDOG复位,否则CPU会不断重启
LDR SP, =1024*4   ; 设置栈。注意:不能超过4K,因为是在SRAM上运行
      ; NAND FLASH中的代码,在复位后,硬件自动将其复制到内部SRAM
      
bl ledMain     ; 调用C函数
halt_loop
b halt_loop   
END

/*********************C程序部*******************************
#include "2440addr.h"      //头文件,包含宏定义及清除挂起寄存器的ClearPending()函数
#define TEST
static void __irq Key_ISR( void );//中断函数声明
static void led_init(void );
static void key_init( void);
void ledMain(void)
{  
  led_init(  );
  key_init();
  while(1);//等待中断发生
}
static void led_init(void )
{
//01  0101 0100    0000 0000;GPB5,GPB6,GPB7,GPB8设置为输出
  rGPBCON = 0x15400;
  // 4个LED全亮
  rGPBDAT =0x0;
}
static void key_init( void)
{
  
  //ClearPending(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);//清外部中断0,1,2,4
  
   //K1->GPF1,K2->GPF4,K3->GPF2,K4->GPF0工作在第二功能状态,即中断
rGPFCON &=~((3<<(0*2))|(3<<(1*2))|(3<<(2*2))|(3<<(2*4))) ;
//( <<)  11 0011 11 11
//( ~ )  00 1100 00 00
//( &=)  00 XX00 00 00
  rGPFCON |= ((2<<(0*2))|(2<<(1*2))|(2<<(2*2))|(2<<(2*4))) ;
  //( <<)  10 0010 10 10
  //( |=)  10 XX10 10 10
  
  rEXTINT0=0x0;//低电平触发
  rEINTPEND=(1<<4); //清外部中断挂起寄存器,清的是外部中断4
  rEINTMASK=~(1<<4); //使能外部中断4
  pISR_EINT0= pISR_EINT1 =pISR_EINT2 = pISR_EINT4_7=(unsigned int )Key_ISR;//设中断服务函数地址
  EnableIrq(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);//使能中断,即使INTMSK相应位为0  
}

static void __irq Key_ISR()//中断服务函数,__irq用来声明通用中断函数
{

  char key;//用来标识是哪一个按键按下
  
#ifdef TEST
  rGPBDAT =0x20;
#endif

  rINTMSK=0xffffffff;//这是屏蔽所有中断
  if(rINTPND==BIT_EINT0) {          //因为4个中断用的是同一个中断服务函数,所以判断是哪一个中断发生
    ClearPending(BIT_EINT0);         //并清除挂起寄存器,获得键值
    key=1;
  }else if(rINTPND==BIT_EINT1) {
     ClearPending(BIT_EINT2);
     key=2;
   }else if(rINTPND==BIT_EINT2) {
      ClearPending(BIT_EINT2);
      key=3;
    }else if(rINTPND==BIT_EINT4_7){
       rEINTPEND=(1<<4);
       ClearPending(BIT_EINT4_7);
       key=4;
     }
switch(key){      //根据键值控制4个LED亮灭变化
    case 1:  rGPBDAT = (1<<5);
         break;
    case 2:  rGPBDAT = (1<<6);
        break;
    case 3:  rGPBDAT = (1<<7);
        break;
    case 4:  rGPBDAT = (1<<8);
        break;
  }
EnableIrq(BIT_EINT0|BIT_EINT1|BIT_EINT2|BIT_EINT4_7);//再打开中断   
}


出现问题:无**常中断,我没分析出原因,求指教....谢谢

相关帖子

沙发
ycz9999| | 2012-2-29 22:22 | 只看该作者
LZ  你好像没有异常向量表的

使用特权

评论回复
板凳
prodigals|  楼主 | 2012-3-1 12:24 | 只看该作者
外部中断也得建立中断向量表??

使用特权

评论回复
地板
ycz9999| | 2012-3-1 13:06 | 只看该作者
3# prodigals 嗯  外部中断也是异常的一种

使用特权

评论回复
5
prodigals|  楼主 | 2012-3-1 14:29 | 只看该作者
刚学裸机,不明白为什么要建立这个中断向量表?能告诉下吗?

使用特权

评论回复
6
ycz9999| | 2012-3-1 14:47 | 只看该作者
本帖最后由 ycz9999 于 2012-3-1 14:49 编辑

5# prodigals 当发生各类异常时,CPU会进入相应的工作模式,并跳转去执行它的“异常向量”(为何要跳转,这应该是硬件决定了的)。比如,CPU复位时,就会进入系统模式,跳转到0x00地址处执行,一般,启动代码会在该地址处放置一条跳转指令。同理,发生中断时,CPU进入中断模式,且会跳转到0x18处执行指令。
PS:我也在学习嵌入式,理解可能有不对的地方,希望对你有帮助。

使用特权

评论回复
7
prodigals|  楼主 | 2012-3-1 15:23 | 只看该作者
你又没有自己做的关于中断程序啊,就是没有多余程序的,能给一份吗??具体怎么实现,我还是不会,我看看到底怎么用,谢谢...

使用特权

评论回复
8
ycz9999| | 2012-3-1 16:53 | 只看该作者
7# prodigals 推荐你看看韦东山的书   觉得讲的挺不错的

int.zip

39.35 KB

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
prodigals + 1 谢谢
9
prodigals|  楼主 | 2012-3-1 18:17 | 只看该作者
谢谢啊,裸奔阶段,我想法是边实践的基础上了解原理,并且将过程整理以及原理成册。

使用特权

评论回复
10
ycz9999| | 2012-3-1 18:23 | 只看该作者
9# prodigals 不客气

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
prodigals + 1
11
prodigals|  楼主 | 2012-3-1 19:09 | 只看该作者
请问下:
比如,CPU复位时,就会进入系统模式,跳转到0x00地址处执行
CPU进入中断模式,且会跳转到0x18处执行指令。

这是再那里查的啊??我怎么没看见过

使用特权

评论回复
12
prodigals|  楼主 | 2012-3-1 19:19 | 只看该作者
你的程序,我改了一下(因为使用的外部中断不一样),但改后下到板子没反映。

是不是中断跳转地址也得修改??

使用特权

评论回复
13
prodigals|  楼主 | 2012-3-1 20:08 | 只看该作者
所有问题已经解决。。。谢谢

使用特权

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

本版积分规则

个人签名:心有多高,路有多长...

1

主题

147

帖子

1

粉丝