我在弄OK6410,可是一直进不了外部按键中断,谁可以帮我看看什么原因么?
汇编启动代码是:
.global _start
_start:
ldr r0,=0x53000000 ;//看门狗地址
mov r1,#0x0 ;//关闭看门狗
str r1,[r0] ;//把0写入看门狗地址,即关闭看门狗
ldr sp,=1024*8; //设置堆栈
;//打开VIC
mrc p15,0,r0,c1,c0,0
orr r0,r0,#(1<<24); //enable VE bit
mcr p15,0,r0,c1,c0,0
;//打开CPU总中断
mrs r0,cpsr //mrs用于读取状态寄存器CPSR或SPSR,记录在通用寄存器r0
bic r0,r0,#0x80 ;//设置IRQ中断的总开关,0x90既是1000,0000 即CPSR状态寄存器I位用bic 1000,0000,清0(那个为1清哪个)
msr cpsr,r0 ;//把r0写入到cpsr状态寄存器里面
bl main
halt_loop:
b halt_loop
/********************************C函数********************/
/*******************key****************************/
#define GPNCON (*(volatile unsigned *)(0x7F008830))
#define GPNDAT (*(volatile unsigned *)(0x7F008834))
#define GPNPUD (*(volatile unsigned *)(0x7F008838))
/**************LED*********************/
#define Register_GPMCON (*(volatile unsigned *)(0x7F008820))
#define Register_GPMDAT (*(volatile unsigned *)(0x7F008824))
#define Register_PUDCON (*(volatile unsigned *)(0x7F008828))
/////////////////////////////////////////////////////////
[url=]/*@2VIC[/url]的设置,这里主要是VICXINTSELECT,VICXVECTADDR,VICXINTENABLE*/
#define VIC0VECTADDR_00 (*(volatile unsigned *)(0x71200100)) //设置中断处理程序的地址
#define VIC0INTSELECT (*(volatile unsigned *)(0x7120000C)) //选择中断方式是FIQ还是IRQ
#define VIC0INTENABLE (*(volatile unsigned *)(0x71200010)) //使能GPIO穿过来的中断信号,使能INT_EINT0
/*------------------------------------------------*/
#define VICINTENCLEAR (*(volatile unsigned *)(0x71200014)) //中断使能清除寄存器(VIC0)
#define VIC0IRQSTATUS (*(volatile unsigned *)(0x71200000)) //中断第一组选择
#define VIC0ADDRESS (*(volatile unsigned *)(0x71200F00)) //地址寄存器(VIC0)
#define EINT0CON0 (*(volatile unsigned *)(0x7F008900))
[url=]/*******@1[/url]即是要使管脚设置为外部中断的寄存器extern interrupt***主要是EINTXCON*EINTXPEND*EINTXMASK*EINTXFLTCON*************************8*/
#define EINT0CON0 (*(volatile unsigned *)(0x7F008900)) //配置触发方式
#define EINT0FLTCON0 (*(volatile unsigned *)(0x7F008910)) //这个是设置滤波方式,可以去毛刺
#define EINT0MASK (*(volatile unsigned *)(0x7F008920)) //使能管脚发送中断信号,既是屏蔽管脚中断
#define EINT0PEND (*(volatile unsigned *)(0x7F008924)) //外部中断暂存寄存器,判断有无中断
/*------------------------------------------------------------------------------*/
unsigned int bit0,bit1,bit2,bit3;
void GPIO_IntInit(void);
void Int_Init(void);
void msDelay(int time);
void GPIO_Init(void);
void LED_Test(void);
void int0_proc(void);
//中断处理函数
void int0_proc(void)
{
printf("hello extern interrupt./n");
if(EINT0PEND&0x1!=0) //EINTnPEND外部中断暂存寄存器
{
bit0=1;
}
else
{
if(EINT0PEND&(0x1<<1)!=0)
{
bit1=1;
}
else
if(EINT0PEND&(0x1<<2)!=0)
{
bit2=1;
}
else
bit3=1;
}
/*************第一个按键对应第一个led*****************/
if((1<<0)&EINT0PEND)
{
Register_GPMDAT=0xf; /*****/
}
else
{
Register_GPMDAT=~(1<<0);
}
/*************第二个按键对应第二个led*****************/
if((1<<1)&EINT0PEND)
{
Register_GPMDAT=0xf;
}
else
{
Register_GPMDAT=~(1<<1);
}
/************第三个按键对应第三个led******************/
if((1<<2)&EINT0PEND)
{
Register_GPMDAT=0xf;
}
else
{
Register_GPMDAT=~(1<<2);
}
/***********第四个按键对应第四个led*******************/
if((1<<3)&EINT0PEND)
{
Register_GPMDAT=0xf;
}
else
{
Register_GPMDAT=~(1<<3);
}
EINT0PEND=0x00001111; //该位写入1表示清除,写0无影响
//清除VICXADDRESS
VIC0ADDRESS=0x0000FFFF; //向寄存器写入任何值都可以清除当前中断。只有在终端服务快要结束的时候才可以进行写入操作。
}
void main()
{
bit0=0;
//中断设置
GPIO_IntInit();
Int_Init();
GPIO_Init();
while(1)
{
if(bit0==1)
{
LED_Test();
}
}
}
void GPIO_IntInit()
{
GPNCON=GPNCON&0x00;
GPNCON=GPNCON|0xaa; //先把外部引脚设为中断
GPNPUD=GPNPUD&0X00;
GPNPUD=GPNPUD|0xaa; //设置上拉电阻保护作用
}
//初始化中断
void Int_Init()
{
EINT0CON0&=(~0xff);
EINT0CON0=EINT0CON0|0x22; //开EINT0中的0~4,0x22下降沿触法,0x00低电平触发
EINT0FLTCON0=EINT0FLTCON0&(~0xffff);
EINT0FLTCON0=EINT0FLTCON0|0x0c0c0; //数字过滤器
EINT0MASK=EINT0MASK&(~0x0f); //ent0--4使能,0为Enable interrupt,EINT0即为0x0
EINT0PEND=EINT0PEND|(0x0f); //要写1清除,ent0--4标志位清除 1=occur interrupt
VIC0INTSELECT=VIC0INTSELECT&(~0x0f); //选irq中断,IRQ=0,FIQ=1;
VIC0INTENABLE=VIC0INTENABLE&0x00; //关中断中断
VIC0VECTADDR_00=(unsigned int)int0_proc; //安装中断处理函数
VIC0INTENABLE=VIC0INTENABLE|0x3; //启动中断/*启动中断bit0,bit1*/
}
void msDelay(int time)
{
volatile unsigned int i,j;
for(i=0;i<2000000;i++)
for(j=0;j<time;j++);
}
void GPIO_Init(void)
{
Register_GPMCON=0x111111; //将GPM设置成输出
Register_GPMDAT=0x1f; //初始时点亮LED1
Register_PUDCON=0x00; //无上下拉电阻
}
void LED_Test(void)
{
int i;
for(i=0;i<4;i++)
{
Register_GPMDAT=~(1<<i);
msDelay(5);
}
} |