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里面去,还有试过对中断地址映射,都毫无反应(在调试的时候蜂鸣器曾经响过)
[解决办法]你说到“网上说可能是因为调试的地址原因”,我觉得不应该把程序下到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,看这篇文章吧