经过几天的努力,期间遇到很多的麻烦,终于搞定了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函数入口点之前即可开始VICPort模式,在这个模式下,中断的使用简单了不少,比如说我要用某个按键来实现外部中断,则相应的过程如下:
初始化中断向量控制器:
填充 rVICxINTENCLEAR ,清空VICxINTSELECT和VICxADDR,这步嘛没什么可说的,就是一个简单的重置工作。
配置按键对应的GPIO脚为中断模式:
GPxxCON 每一个脚的配置占此寄存器的2位,其中中断配置为10b,将对应的两位位设为10b即可使用中断功能。
开启中断:
将VICxINTENABLE对应位置一即可开启对应的中断,比如要开启11号中断,就将此寄存器第11位置一,注意此寄存器是32位的,x=0的时候开启0-31号中断,x=1时开启剩下的中断。
设置外部中断类型:
操作EINxCONy,中断分组对应的寄存器可以在三星的手册里查到,每两个中断占用寄存器的三位,换句话说,寄存器每三位控制两个中断的触发方式,其中中断号小的偶数的两倍对应起始位,中断号大的奇数的两倍对应结束位,例如EINT11、10,对应寄存器的[22:20]三位,这三位怎么配手册上有详细描述,不废话。
装载中断伺服程序:
/////////////////////////////////////////////////////////////////////////
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]
由于我也是刚学裸机操作,希望大家多多指导.