S3C6410裸机中断终于搞定了,…

原文地址:S3C6410裸机中断终于搞定了,不需要汇编 ,使用VIC 作者:剑桥石

http://blog.csdn.net/cp1300/article/details/7341757

    经过几天的努力终于搞定了S3C6410裸机中断测试使用的是外部中断0组的PN0,使用定时器0。

        之前一直很郁闷的是网上的一些S3C6410使用的中断都是像51单片机那样的固定中断向量入口这种方式不仅需要汇编支持而且效率相当的低下既然S3C6410自带有中断处理协处理器VIC,那么我还是建议使用VIC来管理中断

 

        为了向下兼容,6410保留了2410的软件中断跳转方式,在三星的文档里被称为SystemBUS模式,默认的,而其特有的VIC Port模式则要手动开启,启动代码:

 

mrc p15,0,r0,c1,c0,0

orrr0,r0,#(1<<24)

mcr p15,0,r0,c1,c0,0

 

        将其加到启动文件的main函数入口点之前(start.s)即可开始VICPort模式,在这个模式下,中断的使用简单了不少,比如说我要用某个按键来实现外部中断,则相应的过程如下:

 

1. 初始化中断向量控制器:

      填充 rVICxINTENCLEAR ,清空VICxINTSELECT和VICxADDR,这步嘛没什么可说的,就是一个简单的重置工作。

2.  配置按键对应的GPIO脚为中断模式:

      GPxxCON 每一个脚的配置占此寄存器的2位,其中中断配置为10b,将对应的两位位设为10b即可使用中断功能。

 3. 开启中断:

     将VICxINTENABLE对应位置"1"即可开启对应的中断,比如要开启11号中断,就将此寄存器第11位置"1",注意此寄存器是32位的,x=0的时候开启0-31号中断,x=1时开启剩下的中断。

4. 设置外部中断类型:

    操作EINxCONy,中断分组对应的寄存器可以在三星的手册里查到,每两个中断占用寄存器的三位,换句话说,寄存器每三位控制两个中断的触发方式,其中中断号小的偶数的两倍对应起始位,中断号大的奇数的两倍对应结束位,例如EINT11、10,对应寄存器的[22:20]三位,这三位怎么配手册上有详细描述,不废话。

5. 装载中断伺服程序:

/////////////////////////////////////////////////////////////////////////

 

void led_init(void)

{

GPIOM->CON        =0x1111;

GPIOM->DAT        =0;

}

 

void Delay(u32 n)

{

u32i;

while(n--)

{

for(i= 0;i < 2000000;i ++);

}

}

 

void __irqIRQ_Exception(void)

{

EINT0PEND= 1;//写1清除中断标志

GPIOM->DAT^= BIT2;

ClearInterrupt(INT_EINT0);//中断结束

}

 

void Key_Init(void)

{

//PN0

GPION->CON= 2;//外部中断模式

EINT0CON0= 0x2;

EINT0PEND= 0xffffffff;

EINT0MASK&= ~(BIT0);//取消中断屏蔽

Set_IsrAddr(INT_EINT0,(u32)IRQ_Exception);        //设置中断矢量入口

Set_IntEnable(INT_EINT0,Enable);

}

 

 

void __irqIsr_Timer0(void)

{

TINT_CSTAT|= BIT5;//清除中断标志

GPIOM->DAT^= 1 << 3;

ClearInterrupt(INT_TIMER0);//中断结束

}

 

 

voidTIMER0_Init(void)

{

TCFG0=65;        //定时器0预分频65+1,由PCLK=66提供时钟,66分频产生1MHz的定时器时钟

TCON= BIT3;//定时器0自动更新使能

TCNTB0 = 200000;//重装值,200ms

TINT_CSTAT|= BIT5;//清除中断标志

TINT_CSTAT= 1;//使能定时器0中断

Set_IsrAddr(INT_TIMER0,(u32)Isr_Timer0);        //设置中断矢量入口

Set_IntEnable(INT_TIMER0,Enable);//使能定时器0全局中断

//以下操作启动定时器0

TCON|= BIT1;//手动更新

TCON&= ~BIT1;//结束手动更新

TCON|= BIT0;//启动定时器0

 

}

 

 

 

//主函数

void main(void)

{

u8i;

 

led_init();

Key_Init();

TIMER0_Init();

while(1)

{

for(i= 0;i < 2;i ++)

{

GPIOM->DAT^= 1 << i;

Delay(10);

}

}

}


//把下面的汇编加入到启动文件中,主要用来打开CPU中断和初始化VIC

;VIC Port模式,开启后就可以不用汇编使用中断,使用VIC控制中断
mrc p15,0,r0,c1,c0,0
orr r0,r0,#(1<<24)
mcr p15,0,r0,c1,c0,0

;允许中断,开启CPU总中断
MRS R0, CPSR         ;将CPSR保存至R0寄存器中
BIC R0, R0, #0x80    ;R0 = R0 & ~0x80,清除中断位
MSR CPSR_c, R0       ;将R0写回CPSR状态寄存

 

 

以上就是相关的代码因为大家的寄存器宏定义不同因此名字可能不同因为我写了注释的大家可以对着文档设置相应的寄存器就可以了,如果需要可以找我,邮箱:c[email protected]

代码:http://download.csdn.net/detail/cp1300/4266684,S3C6410裸机外部中断+定时器中断 

你可能感兴趣的:(S3C6410裸机中断终于搞定了,…)