S3C6410裸機(jī)中斷終于搞定了,不需要匯編 ,使用VIC
經(jīng)過(guò)幾天的努力,期間遇到很多的麻煩,終于搞定了S3C6410裸機(jī)中斷,測(cè)試使用的是外部中斷0組的PN0,定時(shí)器使用的是定時(shí)器0.
?
之前一直很郁悶的是網(wǎng)上的一些S3C6410使用的中斷都是像51單片機(jī)那樣的固定中斷向量入口,這種方式不僅需要匯編支持,而且效率相當(dāng)?shù)牡拖?既然S3C6410自帶有中斷處理協(xié)處理器VIC,那么我還是建議使用VIC來(lái)管理中斷.
?
下面這段話摘自網(wǎng)上,不知道是誰(shuí)寫的,但是要謝謝他,讓我搞清楚了如何使用裸機(jī)中斷.
///////////////////////////////////////////////////////////////////////////////
為了向下兼容,6410保留了2410的軟件中斷跳轉(zhuǎn)方式,在三星的文檔里被稱為SystemBUS模式,默認(rèn)的,而其特有的VIC Port模式則要手動(dòng)開啟,啟動(dòng)代碼:
?
mrc p15,0,r0,c1,c0,0
orrr0,r0,#(1<<24)
mcr p15,0,r0,c1,c0,0
?
將其加到啟動(dòng)文件的main函數(shù)入口點(diǎn)之前即可開始VICPort模式,在這個(gè)模式下,中斷的使用簡(jiǎn)單了不少,比如說(shuō)我要用某個(gè)按鍵來(lái)實(shí)現(xiàn)外部中斷,則相應(yīng)的過(guò)程如下:
?
初始化中斷向量控制器:
?
????? 填充?rVICxINTENCLEAR ,清空VICxINTSELECT和VICxADDR,這步嘛沒什么可說(shuō)的,就是一個(gè)簡(jiǎn)單的重置工作。
?
配置按鍵對(duì)應(yīng)的GPIO腳為中斷模式:
?
???? GPxxCON?每一個(gè)腳的配置占此寄存器的2位,其中中斷配置為10b,將對(duì)應(yīng)的兩位位設(shè)為10b即可使用中斷功能。
?
開啟中斷:
?
??將VICxINTENABLE對(duì)應(yīng)位置一即可開啟對(duì)應(yīng)的中斷,比如要開啟11號(hào)中斷,就將此寄存器第11位置一,注意此寄存器是32位的,x=0的時(shí)候開啟0-31號(hào)中斷,x=1時(shí)開啟剩下的中斷。
?
設(shè)置外部中斷類型:
?
???操作EINxCONy,中斷分組對(duì)應(yīng)的寄存器可以在三星的手冊(cè)里查到,每?jī)蓚€(gè)中斷占用寄存器的三位,換句話說(shuō),寄存器每三位控制兩個(gè)中斷的觸發(fā)方式,其中中斷號(hào)小的偶數(shù)的兩倍對(duì)應(yīng)起始位,中斷號(hào)大的奇數(shù)的兩倍對(duì)應(yīng)結(jié)束位,例如EINT11、10,對(duì)應(yīng)寄存器的[22:20]三位,這三位怎么配手冊(cè)上有詳細(xì)描述,不廢話。
?
裝載中斷伺服程序:
?
/////////////////////////////////////////////////////////////////////////
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清除中斷標(biāo)志
GPIOM->DAT^= BIT2;
ClearInterrupt(INT_EINT0);//中斷結(jié)束
}
?
void Key_Init(void)
{
//PN0
GPION->CON= 2;//外部中斷模式
EINT0CON0= 0x2;
EINT0PEND= 0xffffffff;
EINT0MASK&= ~(BIT0);//取消中斷屏蔽
Set_IsrAddr(INT_EINT0,(u32)IRQ_Exception);????????//設(shè)置中斷矢量入口
Set_IntEnable(INT_EINT0,Enable);
}
?
?
void __irqIsr_Timer0(void)
{
TINT_CSTAT|= BIT5;//清除中斷標(biāo)志
GPIOM->DAT^= 1 << 3;
ClearInterrupt(INT_TIMER0);//中斷結(jié)束
}
?
?
voidTIMER0_Init(void)
{
TCFG0=65;????????//定時(shí)器0預(yù)分頻65+1,由PCLK=66提供時(shí)鐘,66分頻產(chǎn)生1MHz的定時(shí)器時(shí)鐘
TCON= BIT3;//定時(shí)器0自動(dòng)更新使能
TCNTB0 = 200000;//重裝值,200ms
TINT_CSTAT|= BIT5;//清除中斷標(biāo)志
TINT_CSTAT= 1;//使能定時(shí)器0中斷
Set_IsrAddr(INT_TIMER0,(u32)Isr_Timer0);????????//設(shè)置中斷矢量入口
Set_IntEnable(INT_TIMER0,Enable);//使能定時(shí)器0全局中斷
//以下操作啟動(dòng)定時(shí)器0
TCON|= BIT1;//手動(dòng)更新
TCON&= ~BIT1;//結(jié)束手動(dòng)更新
TCON|= BIT0;//啟動(dòng)定時(shí)器0
?
}
?
?
?
//主函數(shù)
void main(void)
{
u8i;
?
led_init();
Key_Init();
TIMER0_Init();
while(1)
{
for(i= 0;i < 2;i ++)
{
GPIOM->DAT^= 1 << i;
Delay(10);
}
}
}
//把下面的匯編加入到啟動(dòng)文件中,主要用來(lái)打開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狀態(tài)寄存
?
?
以上就是相關(guān)的代碼,因?yàn)榇蠹业募拇嫫骱甓x不同,因此名字可能不同,因?yàn)槲覍懥俗⑨尩?大家可以對(duì)著文檔,設(shè)置相應(yīng)的寄存器就可以了,如果需要可以找我,郵箱:cp1300@139.com
?
由于我也是剛學(xué)裸機(jī)操作,希望大家多多指導(dǎo).