打印

学习OK6410的裸机外部中断出现问题,求解答

[复制链接]
3879|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
h516077808|  楼主 | 2012-11-4 00:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我在弄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);
}
}

相关帖子

沙发
h516077808|  楼主 | 2012-11-4 11:27 | 只看该作者
怎么没有人来顶一下的,求大神路过,这个中断搞了两天了,始终进不去中断,求解

使用特权

评论回复
板凳
h516077808|  楼主 | 2012-11-4 11:27 | 只看该作者
怎么没有人来顶一下的,求大神路过,这个中断搞了两天了,始终进不去中断,求解

使用特权

评论回复
地板
h516077808|  楼主 | 2012-11-18 00:31 | 只看该作者
自己搞定了!!

使用特权

评论回复
5
阿南| | 2012-11-19 14:13 | 只看该作者
搞定了就好。不能产生中断,要理清楚解决这个问题的思路

使用特权

评论回复
6
2005820037| | 2012-12-17 21:35 | 只看该作者
h516077808 发表于 2012-11-4 11:27
怎么没有人来顶一下的,求大神路过,这个中断搞了两天了,始终进不去中断,求解 ...

是什么原因啊

使用特权

评论回复
7
huangzh198| | 2013-5-22 22:47 | 只看该作者
是不是这句的问题?VIC0VECTADDR_00=(unsigned int)int0_proc; //安装中断处理函数

使用特权

评论回复
8
544892012| | 2013-12-17 16:49 | 只看该作者
阿南 发表于 2012-11-19 14:13
搞定了就好。不能产生中断,要理清楚解决这个问题的思路

版主。我这几天也在写这个程序。和他的程序差不多。版主。求指点。他这个程序怎么产生不了中断呢?感觉寄存器的设置都对啊。

使用特权

评论回复
9
pdjdm| | 2013-12-28 10:59 | 只看该作者
同样问题
中断函数非普通函数 ,进出中断需要自己处理现场
裸机RVDS集成环境中中断函数只需加__IRQ标识就行了,
而gcc编译器中 并没有对中断函数做处理,中断函数非普通函数 ,进出中断需要自己处理现场,arm9中对于irq 进出代码如下
sub ldr,ldr,#4
stmdb sp!,{r0-r12,lr}
......
ldmia sp!,{r0-12,pc}^

arm11出现了vic机制  若用vic, 中断末尾是 rVIC0ADDR =  0返回,此时返回出现矛盾,请问楼主如何解决的?

使用特权

评论回复
10
saosaoplayer| | 2013-12-28 15:34 | 只看该作者
哎,这么多年了,人们还是分不清6410和2440的看门狗寄存器位置。

使用特权

评论回复
11
Rain_King| | 2016-12-6 20:08 | 只看该作者
问一下你的裸机程序是用什么下载的啊!!!

使用特权

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

本版积分规则

4

主题

46

帖子

2

粉丝