首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 单片机 >

mini2440中止进不去

2013-08-01 
mini2440中断进不去调试环境mini2440+jlink+keil程序1、S3C2440.s是keil默认的启动文件2、interrupt.c如下/*

mini2440中断进不去
调试环境mini2440+jlink+keil
程序
1、S3C2440.s是keil默认的启动文件
2、interrupt.c如下

/*
* 功能:实现按键点亮
* LED1--GPB5
* LED2--GPB6
* LED3--GPB7
* LED4--GPB8

* K1--EINT8
* K2--EINT11
* K3--EINT13
* K4--EINT14
*/
#define GPBCON  (*(volatile unsigned long*)0x56000010)
#define GPBDAT  (*(volatile unsigned long*)0x56000014)
#define GPBUP   (*(volatile unsigned long*)0x56000018)

#define GPGCON    (*(volatile unsigned long*)0x56000060)
#define GPGUP     (*(volatile unsigned long*)0x56000068)
#define GPGDAT    (*(volatile unsigned long*)0x56000064)

#define EINTMASK  (*(volatile unsigned long*)0x560000a4) //使能
#define INTMSK    (*(volatile unsigned long*)0x4A000008) //使能
#define INTOFFSET (*(volatile unsigned long*)0x4A000014)//查看是哪个中断
#define INTMOD    (*(volatile unsigned long*)0x4A000004) //IRQ

#define EINTPEND  (*(volatile unsigned long*)0x560000A8)//清除中断相关
#define SRCPND    (*(volatile unsigned long*)0x4A000000)
#define INTPND    (*(volatile unsigned long*)0x4A000010)



#define MPLL_400MHz ((92<<12)|(1<<4)|(1<<0))
#define MPLL_200MHz ((92<<12)|(4<<4)|(1<<0))
#define MPLLCON   (*(volatile unsigned long*)0x4c000004)
#define CLKDIVN  (*(volatile unsigned long*)0x4c000014)//其实最重要的初始化工作可以用2440.s搞定(时间短)

//#define U32 unsigned int
#define pISR_EINT8_23 (*(volatile unsigned long*)0x33ffff34)

#define Led1_On      ~(1<<5)
#define Led1_Off      (1<<5)
#define Led2_On      ~(1<<6)
#define Led2_Off      (1<<6)
#define Led3_On      ~(1<<7)
#define Led3_Off      (1<<7)
#define Led4_On      ~(1<<8)
#define Led4_Off      (1<<8)
void __irq IRQ_Handler(void);
void Led_Port_Init(void);
void delay(int times);
void Clock_Init(void);
void Interrupt_init(void);

void delay(int times)
{
    int i,j;


for(i=0;i<times;i++)
 for(j=0;j<400;j++);
}
void Led1_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT |= 0xFFFFFFFF;
}
void Led2_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT |= 0xFFFFFFFF;
}
void Led3_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT |= 0xFFFFFFFF;
}
void Led4_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT |= 0xFFFFFFFF;
}


int main(void)
{
 Clock_Init();
 Led_Port_Init();
 Interrupt_init();
 
 while(1);

}

/*
* 函数名称:Led_Port_Init()
* 全局变量:无
* 参    数:无
* 返 回 值:无
* 说    明:实现Led1灯的寄存器初始化
*/
void Led_Port_Init(void)
{
    //设置GPB5\6\7\8为输出端口
GPBCON =1<<0;// 设置GPB0为输出端口
GPBUP=1<<0;//禁止GPB0上拉功能

GPBDAT =0x1;//蜂鸣器响
delay(300);
GPBDAT=0x0;//蜂鸣器不响
//delay(3000);

    GPBCON =(1<<9)| (1<<11)|(1<<13)|(1<<15);
GPBDAT |= 0xFFFFFFFF;
}
/*
* 函数名称:Clock_Init()
* 全局变量:无
* 参    数:无
* 返 回 值:无
* 说    明:实现时钟寄存器初始化
*/
void Clock_Init(void)
{
 //设置变频锁定时间
// MPLLCON=MPLL_400MHz;
 //设置分频比FCLK:HCLK:PCLK=1:4:8
// CLKDIVN=5;
}

void Interrupt_init(void)
{
 GPGCON=0xFFFFFFFF &((2<<0)|(2<<3)|(2<<5)|(2<<6));         //将GPG0、3、5、6、7、11设为外部中断输入功能
 GPGUP&=~((1<<0)|(1<<3)|(1<<5)|(1<<6));
 //GPGDAT|=(1<<0)|(1<<3)|(1<<5)|(1<<6);     //因为按下按键后,相应的GPIO口为0,所以初始化为
 
 //对于EINT8,EINT11,EINT13,EINT14,需要在EINTMASK寄存器使能它们
 EINTMASK =0xFFFFFFFF & (~(0x1<<8))&(~(1<<11))&(~(1<<13))&(~(1<<14));
 //这4个外部中断的优先级是相同的,EINT8_23都接仲裁器的REQ1引脚
 //所以不用像韦东山程序里那样再设置优先级了
 
 //EINT8,EINT11,EINT13,EINT14使能
 INTMSK&=(~(1<<5));

 INTMOD &=~(1<<5);//把GPG0中断设为IRQ模式
 //pISR_EINT8_23 = (unsigned int)IRQ_Handler;//将中断服务函数的地址传给对应的中断向量表位置
}

/****************************************************
* 函数名称:void __irq IRQ_Handler(void)  
* 全局变量:无 
* 参数说明:无


* 返 回 值;无
* 功    能:中断服务函数,必须加__irq
*****************************************************/
void __irq IRQ_Handler(void)       
{
 unsigned long oft=INTOFFSET;
 unsigned long val;
 
 val=EINTPEND; //EINT寄存器,它的位x为1时,表示EINT已经发生(x为4--23)。          
 if(val&(1<<8))    //K1被按下,LED1被点亮
 { 
   Led1_delay_On();
 }
  
 if(val&(1<<11))    //K2被按下,LED2被点亮
 {
  Led2_delay_On();
 }
  
 if(val&(1<<13))    //K3被按下,LED3被点亮
 {
  Led3_delay_On();
 } 
 //if(val&(1<<14))    //K4被按下,LED4被点亮
 else
 {
  Led4_delay_On();
 }
  //清除中断
 if(oft==5)
  EINTPEND=(1<<8)|(1<<11)|(1<<13)|(1<<14); //清除EINTPEND寄存器,往某位写入1即可清楚此位
 SRCPND=1<<oft;       //清除SRCPND寄存器,往某位写入1即可清楚此位
 INTPND=1<<oft;      //清除INTPND寄存器,往某位写入1即可清楚此位
 //注意:清除顺序很重要:先是EINTPEND,然后是SRCPND,最后是INTPND
}


网上说可能是因为调试的地址原因所以我就把程序下载到nor flash还有nand flash里面去,还有试过对中断地址映射,都毫无反应(在调试的时候蜂鸣器曾经响过)
[解决办法]
引用:
调试环境mini2440+jlink+keil
程序
1、S3C2440.s是keil默认的启动文件
2、interrupt.c如下
/*
* 功能:实现按键点亮
* LED1--GPB5
* LED2--GPB6
* LED3--GPB7
* LED4--GPB8

* K1--EINT8
* K2--EINT11
* K3--EINT13
* K4--EINT14
*/
#define GPBCON  (*(volatile unsigned long*)0x56000010)
#define GPBDAT  (*(volatile unsigned long*)0x56000014)
#define GPBUP   (*(volatile unsigned long*)0x56000018)

#define GPGCON    (*(volatile unsigned long*)0x56000060)
#define GPGUP     (*(volatile unsigned long*)0x56000068)
#define GPGDAT    (*(volatile unsigned long*)0x56000064)



#define EINTMASK  (*(volatile unsigned long*)0x560000a4) //使能
#define INTMSK    (*(volatile unsigned long*)0x4A000008) //使能
#define INTOFFSET (*(volatile unsigned long*)0x4A000014)//查看是哪个中断
#define INTMOD    (*(volatile unsigned long*)0x4A000004) //IRQ

#define EINTPEND  (*(volatile unsigned long*)0x560000A8)//清除中断相关
#define SRCPND    (*(volatile unsigned long*)0x4A000000)
#define INTPND    (*(volatile unsigned long*)0x4A000010)



#define MPLL_400MHz ((92<<12)
[解决办法]
(1<<4)
[解决办法]
(1<<0))
#define MPLL_200MHz ((92<<12)
[解决办法]
(4<<4)
[解决办法]
(1<<0))
#define MPLLCON   (*(volatile unsigned long*)0x4c000004)
#define CLKDIVN  (*(volatile unsigned long*)0x4c000014)//其实最重要的初始化工作可以用2440.s搞定(时间短)

//#define U32 unsigned int
#define pISR_EINT8_23 (*(volatile unsigned long*)0x33ffff34)

#define Led1_On      ~(1<<5)
#define Led1_Off      (1<<5)
#define Led2_On      ~(1<<6)
#define Led2_Off      (1<<6)
#define Led3_On      ~(1<<7)
#define Led3_Off      (1<<7)
#define Led4_On      ~(1<<8)
#define Led4_Off      (1<<8)
void __irq IRQ_Handler(void);
void Led_Port_Init(void);
void delay(int times);
void Clock_Init(void);
void Interrupt_init(void);

void delay(int times)
{
    int i,j;
for(i=0;i<times;i++)
 for(j=0;j<400;j++);
}
void Led1_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT 
[解决办法]
= 0xFFFFFFFF;
}
void Led2_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT 
------解决方案--------------------


= 0xFFFFFFFF;
}
void Led3_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT 
[解决办法]
= 0xFFFFFFFF;
}
void Led4_delay_On(void)
{
GPBDAT &= 0x00000000;
delay(500);
GPBDAT 
[解决办法]
= 0xFFFFFFFF;
}


int main(void)
{
 Clock_Init();
 Led_Port_Init();
 Interrupt_init();
 
 while(1);

}

/*
* 函数名称:Led_Port_Init()
* 全局变量:无
* 参    数:无
* 返 回 值:无
* 说    明:实现Led1灯的寄存器初始化
*/
void Led_Port_Init(void)
{
    //设置GPB5\6\7\8为输出端口
GPBCON =1<<0;// 设置GPB0为输出端口
GPBUP=1<<0;//禁止GPB0上拉功能

GPBDAT =0x1;//蜂鸣器响
delay(300);
GPBDAT=0x0;//蜂鸣器不响
//delay(3000);

    GPBCON =(1<<9)
[解决办法]
 (1<<11)
[解决办法]
(1<<13)
[解决办法]
(1<<15);
GPBDAT 
[解决办法]
= 0xFFFFFFFF;
}
/*
* 函数名称:Clock_Init()
* 全局变量:无
* 参    数:无
* 返 回 值:无
* 说    明:实现时钟寄存器初始化
*/
void Clock_Init(void)
{
 //设置变频锁定时间
// MPLLCON=MPLL_400MHz;
 //设置分频比FCLK:HCLK:PCLK=1:4:8
// CLKDIVN=5;
}

void Interrupt_init(void)
{
 GPGCON=0xFFFFFFFF &((2<<0)
[解决办法]
(2<<3)
[解决办法]
(2<<5)
[解决办法]
(2<<6));         //将GPG0、3、5、6、7、11设为外部中断输入功能
 GPGUP&=~((1<<0)
[解决办法]
(1<<3)
[解决办法]
(1<<5)
[解决办法]
(1<<6));


 //GPGDAT
[解决办法]
=(1<<0)
[解决办法]
(1<<3)
[解决办法]
(1<<5)
[解决办法]
(1<<6);     //因为按下按键后,相应的GPIO口为0,所以初始化为
 
 //对于EINT8,EINT11,EINT13,EINT14,需要在EINTMASK寄存器使能它们
 EINTMASK =0xFFFFFFFF & (~(0x1<<8))&(~(1<<11))&(~(1<<13))&(~(1<<14));
 //这4个外部中断的优先级是相同的,EINT8_23都接仲裁器的REQ1引脚
 //所以不用像韦东山程序里那样再设置优先级了
 
 //EINT8,EINT11,EINT13,EINT14使能
 INTMSK&=(~(1<<5));

 INTMOD &=~(1<<5);//把GPG0中断设为IRQ模式
 //pISR_EINT8_23 = (unsigned int)IRQ_Handler;//将中断服务函数的地址传给对应的中断向量表位置
}

/****************************************************
* 函数名称:void __irq IRQ_Handler(void)  
* 全局变量:无 
* 参数说明:无
* 返 回 值;无
* 功    能:中断服务函数,必须加__irq
*****************************************************/
void __irq IRQ_Handler(void)       
{
 unsigned long oft=INTOFFSET;
 unsigned long val;
 
 val=EINTPEND; //EINT寄存器,它的位x为1时,表示EINT已经发生(x为4--23)。          
 if(val&(1<<8))    //K1被按下,LED1被点亮
 { 
   Led1_delay_On();
 }
  
 if(val&(1<<11))    //K2被按下,LED2被点亮
 {
  Led2_delay_On();
 }
  
 if(val&(1<<13))    //K3被按下,LED3被点亮
 {
  Led3_delay_On();
 } 
 //if(val&(1<<14))    //K4被按下,LED4被点亮
 else
 {
  Led4_delay_On();
 }
  //清除中断
 if(oft==5)
  EINTPEND=(1<<8)
[解决办法]
(1<<11)
[解决办法]
(1<<13)
[解决办法]
(1<<14); //清除EINTPEND寄存器,往某位写入1即可清楚此位
 SRCPND=1<<oft;       //清除SRCPND寄存器,往某位写入1即可清楚此位
 INTPND=1<<oft;      //清除INTPND寄存器,往某位写入1即可清楚此位
 //注意:清除顺序很重要:先是EINTPEND,然后是SRCPND,最后是INTPND


}


网上说可能是因为调试的地址原因所以我就把程序下载到nor flash还有nand flash里面去,还有试过对中断地址映射,都毫无反应(在调试的时候蜂鸣器曾经响过)


你说到“网上说可能是因为调试的地址原因”,我觉得不应该把程序下到flash中,因为S3C2440发生中断和异常时都是跳转到0x0-0x20处,当然,前提是没有开始MMU。

你这里应该把地址定义到0x00处,S3C2440的stonestepping会把flash的前4KB重映射到SRAM中,地址从0开始。如果你把程序下载flash中感觉也可以,但是这样会把然来在这块的程序擦掉,这块原来存放的程序应该是bootloader程序。

你用的是keil,应该配置一下加载脚本sct文件就可以了。
LR_IROM1 0x00000000 0x00001000  {    ; load region size_region
  ER_IROM1 0x00000000 0x00001000    {  ; load address = execution address
   *.o (Vector, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 +0  {  ; RW data
   .ANY (+RW +ZI)
  }
}

这样的话,程序等于是通过jtag直接下载到SRAM中,下载速度快,调试也快。断电后,flash中的程序没动,不会影响到原来的系统,小心把flash中的bootloader擦出了,以后不能像以前那样通过bootloader来烧写调试程序了。

我一般是采用上面在SRAM中调试的方法,以后有把握了再把程序烧写到flash中,不然要是老在flash中调试,需要每次都烧写,很麻烦。不知道擦写、烧写多了会不会把flash弄出坏块来。


当然程序不能太大了,放不下也会出问题,运行时栈也不能溢出。如果确实不行,把SDRAM初始化了,那你就可以用SDRAM了,这个可就够大了,加载脚本你也可以改到SDRAM区。
nor flash和nand flash你就看着需要要不要初始化吧。


[解决办法]
http://blog.csdn.net/mybelief321/article/details/9417003,看这篇文章吧

热点排行