www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 電源 > 功率器件
[導(dǎo)讀]按鍵和中斷部分以按鍵觸發(fā)中斷為例,談?wù)凷5PV210的中斷體系要使用中斷,首先要做好兩個(gè)部分的工作:CPU中斷的初始化和相應(yīng)器件的中斷的初始化。CPU中斷初始化:就是要設(shè)置好

按鍵和中斷部分

以按鍵觸發(fā)中斷為例,談?wù)凷5PV210的中斷體系

要使用中斷,首先要做好兩個(gè)部分的工作:CPU中斷的初始化和相應(yīng)器件的中斷的初始化。CPU中斷初始化:就是要設(shè)置好CPU有關(guān)中斷的東西。相關(guān)器件的中斷初始化:譬如我們的按鍵,就要設(shè)置好按鍵,使其一按下按鍵,就觸發(fā)中斷。

(1)我們先來說說按鍵的相關(guān)的中斷設(shè)置

 

 

先看看按鍵的硬件接法:我們可以看到,按鍵是接在EINT2和EINT3處,還有KP_COL0-3,一共是6個(gè)按鍵,然后我們看SOC的接口處,可以看到EINT2和EINT3接在了GPH0_2,3處,KP_COL0-3接在了GPH2_0-3處

 

 

然后,我們就查找GPH0和GPH2的數(shù)據(jù)手冊,全部將其設(shè)置為外部中斷模式(EXT_INT)模式,也就是1111,KP_COL模式是用來做矩陣鍵盤的。

 

 

設(shè)置好寄存器GPH0和GPH2之后,我們下面設(shè)置和外部中斷相關(guān)的寄存器:EXT_INT_0_CON,EXT_INT_2_CON,EXT_INT_0_MASK,EXT_INT_2_MASK,EXT_INT_0_PEND,EXT_INT_2_PEND.

總結(jié):也就是說按鍵這邊,一個(gè)按鍵的話只需要設(shè)置好四個(gè)寄存器就可以工作了。

GPH0CON選擇外部中斷模式,

EXT_INT_0_CON選擇怎樣就觸發(fā)中斷(是高電平就觸發(fā)中斷,還是低電平,上升沿,下降沿,上升/下降沿觸發(fā)中斷),

EXT_INT_0_MASK:向該寄存器寫0來使能中斷;

EXT_INT_O_PEND:我們初始化的時(shí)候可以通過寫1來進(jìn)行清除中斷,中斷處理完之后,我們也要向這個(gè)寄存器寫1來清除中斷。設(shè)置好上面這些寄存器,我們按鍵部分的中斷初始化就設(shè)置好了。

 

 

1 // 以中斷方式來處理按鍵的初始化

2 void key_init_interrupt(void)

3 {

4 // 1. 外部中斷對應(yīng)的GPIO模式設(shè)置

5 rGPH0CON |= 0xFF《《8; // GPH0_2 GPH0_3設(shè)置為外部中斷模式

6

7 // 2. 中斷觸發(fā)模式設(shè)置

8 rEXT_INT_0_CON &= ~(0xFF《《8); // bit8~bit15全部清零

9 rEXT_INT_0_CON |= ((2《《8)|(2《《12)); // EXT_INT2和EXT_INT3設(shè)置為下降沿觸發(fā)

10

11 // 3. 中斷允許

12 rEXT_INT_0_MASK &= ~(3《《2); // 外部中斷允許

13

14 // 4. 清掛起,清除是寫1,不是寫0

15 rEXT_INT_0_PEND |= (3《《2);

16 }

(2)設(shè)置CPU的中斷模式

1.中斷產(chǎn)生的時(shí)候,CPU所做的工作的大致過程

 

 

圖片:http://blog.csdn.net/mr_raptor/arTIcle/details/6556195

需要注意的是:1.外部中斷發(fā)生,EXT_INT_O_PEND寄存器(按鍵那邊的寄存器)置為1,中斷掛起,這就相當(dāng)于告訴了CPU中斷發(fā)生了,然后CPU就發(fā)生了上面圖所對應(yīng)的這些響應(yīng)

2.中斷發(fā)生后,cpsr寄存器中的IRQ中斷位就置1了,所以,CPU進(jìn)來處理中斷后,其他硬件在這段時(shí)間內(nèi)發(fā)生了中斷的話,CPU是一概不理的。

根據(jù)上圖:我們要完成的的東西就是:

1.把我們的異常處理入口地址放到我們的異常向量表所對應(yīng)的內(nèi)存處:0x00000018

2.上面的異常處理入口那張圖所對應(yīng)的過程,具體實(shí)現(xiàn)的代碼如下。

1 IRQ_handle:

2 // 設(shè)置IRQ模式下的棧

3 ldr sp, =IRQ_STACK

4 // 保存LR

5 // 因?yàn)锳RM有流水線,所以PC的值會比真正執(zhí)行的代碼+8,

6 sub lr, lr, #4

7 // 保存r0-r12和lr到irq模式下的棧上面

8 stmfd sp!, {r0-r12, lr}

9 // 在此調(diào)用真正的isr來處理中斷

10 bl irq_handler

11 // 處理完成開始恢復(fù)現(xiàn)場,其實(shí)就是做中斷返回,關(guān)鍵是將r0-r12,pc,cpsr一起回復(fù)

12 ldmfd sp!, {r0-r12, pc}^

2.設(shè)置中斷相關(guān)的寄存器,讓CPU找到相應(yīng)的執(zhí)行程序,然后執(zhí)行它(這是中斷的目的:執(zhí)行中斷處理程序)

 

 

圖片:http://www.docin.com/p-961251144.html

相關(guān)的寄存器有:VICnADDR VICnINTENCLEAR  VICnINTSELECT  VICnIRQSTATUS VIC0VECTADDRn VICnINTENABLE

1.VICnADDR :一共有四個(gè)寄存器,VIC(0-3)一人一個(gè),用來存放我們想要的執(zhí)行的中斷處理程序(isr)的地址,它里面的地址是從VIC0VECTADDRn這個(gè)寄存器里面來的,當(dāng)中斷發(fā)生之后,VIC0VECTADDRn里面的地址就會硬件自動刷到這個(gè)寄存器上。(中斷處理完成之后,我們要清除這個(gè)寄存器)

1 // 清除需要處理的中斷的中斷處理函數(shù)的地址

2 void intc_clearvectaddr(void)

3 {

4 // VICxADDR:當(dāng)前正在處理的中斷的中斷處理函數(shù)的地址

5 VIC0ADDR = 0;

6 VIC1ADDR = 0;

7 VIC2ADDR = 0;

8 VIC3ADDR = 0;

9 }

2.VICnINTENCLEAR ?。呵逯袛嗉拇嫫?,也就是中斷處理完成之后,我們要往這個(gè)寄存器里面寫1,把中斷清理掉。我們也可以通過相應(yīng)的中斷號,來禁止那個(gè)中斷。

1 // 禁止中斷

2 // 通過傳參的intnum來禁止某個(gè)具體的中斷源,中斷號在int.h中定義,是物理中斷號

3 void intc_disable(unsigned long intnum)

4 {

5 unsigned long temp;

6

7 if(intnum《32)

8 {

9 temp = VIC0INTENCLEAR;

10 temp |= (1《《intnum);

11 VIC0INTENCLEAR = temp;

12 }

13 else if(intnum《64)

14 {

15 temp = VIC1INTENCLEAR;

16 temp |= (1《《(intnum-32));

17 VIC1INTENCLEAR = temp;

18 }

19 else if(intnum《96)

20 {

21 temp = VIC2INTENCLEAR;

22 temp |= (1《《(intnum-64));

23 VIC2INTENCLEAR = temp;

24 }

25 else if(intnum《NUM_ALL)

26 {

27 temp = VIC3INTENCLEAR;

28 temp |= (1《《(intnum-96));

29 VIC3INTENCLEAR = temp;

30 }

31 // NUM_ALL : disable all interrupt

32 else

33 {

34 VIC0INTENCLEAR = 0xFFFFFFFF;

35 VIC1INTENCLEAR = 0xFFFFFFFF;

36 VIC2INTENCLEAR = 0xFFFFFFFF;

37 VIC3INTENCLEAR = 0xFFFFFFFF;

38 }

39

40 return;

41 }

3.VICnINTSELECT ?。褐袛噙x擇寄存器,我們在這里選擇FIQ模式還是IRQ模式

1 // 初始化中斷控制器

2 void intc_init(void)

3 {

4 // 禁止所有中斷

5 // 為什么在中斷初始化之初要禁止所有中斷?

6 // 因?yàn)橹袛嘁坏┐蜷_,因?yàn)橥獠炕蛘哂布约旱脑虍a(chǎn)生中斷后一定就會尋找isr

7 // 而我們可能認(rèn)為自己用不到這個(gè)中斷就沒有提供isr,這時(shí)它自動拿到的就是亂碼

8 // 則程序很可能跑飛,所以不用的中斷一定要關(guān)掉。

9 // 一般的做法是先全部關(guān)掉,然后再逐一打開自己感興趣的中斷。一旦打開就必須

10 // 給這個(gè)中斷提供相應(yīng)的isr并綁定好。

11 VIC0INTENCLEAR = 0xffffffff;

12 VIC1INTENCLEAR = 0xffffffff;

13 VIC2INTENCLEAR = 0xffffffff;

14 VIC3INTENCLEAR = 0xffffffff;

15

16 // 選擇中斷類型為IRQ

17 VIC0INTSELECT = 0x0;

18 VIC1INTSELECT = 0x0;

19 VIC2INTSELECT = 0x0;

20 VIC3INTSELECT = 0x0;

21

22 // 清VICxADDR

23 intc_clearvectaddr();

24 }

4.VIC0VECTADDRn ?。阂还灿?28個(gè)這樣的寄存器,一個(gè)中斷號對應(yīng)一個(gè)這樣的寄存器,我們可以通過中斷號和VICnADDR這個(gè)基地址來計(jì)算VIC0VECTADDRn這個(gè)寄存器的地址,然后把我們的執(zhí)行程序放到這個(gè)寄存器中,這樣我們就不需要定義太多的宏了。

1 // 綁定我們寫的isr到VICnVECTADDR寄存器

2 // 綁定過之后我們就把isr地址交給硬件了,剩下的我們不用管了,硬件自己會處理

3 // 等發(fā)生相應(yīng)中斷的時(shí)候,我們直接到相應(yīng)的VICnADDR中去取isr地址即可。

4 // 參數(shù):intnum是int.h定義的物理中斷號,handler是函數(shù)指針,就是我們寫的isr

5

6 // VIC0VECTADDR定義為VIC0VECTADDR0寄存器的地址,就相當(dāng)于是VIC0VECTADDR0~31這個(gè)

7 // 數(shù)組(這個(gè)數(shù)組就是一個(gè)函數(shù)指針數(shù)組)的首地址,然后具體計(jì)算每一個(gè)中斷的時(shí)候

8 // 只需要首地址+偏移量即可。

9 void intc_setvectaddr(unsigned long intnum, void (*handler)(void))

10 {

11 //VIC0

12 if(intnum《32)

13 {

14 *( (volaTIle unsigned long *)(VIC0VECTADDR + 4*(intnum-0)) ) = (unsigned)handler;

15 }

16 //VIC1

17 else if(intnum《64)

18 {

19 *( (volaTIle unsigned long *)(VIC1VECTADDR + 4*(intnum-32)) ) = (unsigned)handler;

20 }

21 //VIC2

22 else if(intnum《96)

23 {

24 *( (volaTIle unsigned long *)(VIC2VECTADDR + 4*(intnum-64)) ) = (unsigned)handler;

25 }

26 //VIC3

27 else

28 {

29 *( (volatile unsigned long *)(VIC3VECTADDR + 4*(intnum-96)) ) = (unsigned)handler;

30 }

31 return;

32 }

5.VICnIRQSTATUS ?。篒RQ模式下的中斷狀態(tài)寄存器(一共有4個(gè)),中斷發(fā)生后,這個(gè)寄存器就會自動置1了,然后我們是通過判斷這4個(gè)寄存器中哪個(gè)寄存器寫了1,然后得知我們的中斷執(zhí)行程序的地址是放到了哪個(gè)VICnADDR寄存器上,最后在相應(yīng)的VICADDR寄存器上找到中斷執(zhí)行程序的地址。(自己補(bǔ)充:經(jīng)過推理分析我覺著該位在中斷響應(yīng)后該位自動由硬件清零,因?yàn)樘幚碇袛嗟倪^程中我們并么有清零該位,只是查詢的時(shí)候用了,并且軟件沒有清零該位并不影響程序的運(yùn)行,但是一定要清零PEND相應(yīng)和4個(gè)VICnADDR寄存器,至于為什么要清零VICnADDR寄存器,還沒有搞清楚,如果不清除這幾個(gè)寄存器,中斷會響應(yīng)一次,然后就不再響應(yīng)了)

1 unsigned long vicaddr[4] = {VIC0ADDR,VIC1ADDR,VIC2ADDR,VIC3ADDR};

2 int i=0;

3 void (*isr)(void) = NULL;

4

5 for(i=0; i《4; i++)

6 {

7 // 發(fā)生一個(gè)中斷時(shí),4個(gè)VIC中有3個(gè)是全0,1個(gè)的其中一位不是0

8 if(intc_getvicirqstatus(i) != 0)

9 {

10 isr = (void (*)(void)) vicaddr[i];

11 break;

12 }

13 }

14 (*isr)(); // 通過函數(shù)指針來調(diào)用函數(shù)

6.VICnINTENABLE  :中斷使能寄存器,通過中斷號,來向中斷使能寄存器的相應(yīng)位寫1,就可以使能相應(yīng)的中斷了

1 // 使能中斷

2 // 通過傳參的intnum來使能某個(gè)具體的中斷源,中斷號在int.h中定義,是物理中斷號

3 void intc_enable(unsigned long intnum)

4 {

5 unsigned long temp;

6 // 確定intnum在哪個(gè)寄存器的哪一位

7 // 《32就是0~31,必然在VIC0

8 if(intnum《32)

9 {

10 temp = VIC0INTENABLE;

11 temp |= (1《《intnum); // 如果是第一種設(shè)計(jì)則必須位操作,第二種設(shè)計(jì)可以

12 // 直接寫。

13 VIC0INTENABLE = temp;

14 }

15 else if(intnum《64)

16 {

17 temp = VIC1INTENABLE;

18 temp |= (1《《(intnum-32));

19 VIC1INTENABLE = temp;

20 }

21 else if(intnum《96)

22 {

23 temp = VIC2INTENABLE;

24 temp |= (1《《(intnum-64));

25 VIC2INTENABLE = temp;

26 }

27 else if(intnum《NUM_ALL)

28 {

29 temp = VIC3INTENABLE;

30 temp |= (1《《(intnum-96));

31 VIC3INTENABLE = temp;

32 }

33 // NUM_ALL : enable all interrupt

34 else

35 {

36 VIC0INTENABLE = 0xFFFFFFFF;

37 VIC1INTENABLE = 0xFFFFFFFF;

38 VIC2INTENABLE = 0xFFFFFFFF;

39 VIC3INTENABLE = 0xFFFFFFFF;

40 }

41

42 }

至此,全部準(zhǔn)備工作處理完成,只需要在main函數(shù)那里調(diào)用相應(yīng)的函數(shù)就可以了

1 int main(void)

2 {    //串口初始化    uart_init();

3 //按鍵的中斷初始化

4 key_init_interrupt();

5

6 // 如果程序中要使用中斷,就要調(diào)用中斷初始化來初步初始化中斷控制器

7 system_init_exception();

8

9 // 綁定isr到中斷控制器硬件

10 intc_setvectaddr(KEY_EINT2, isr_eint2);

11

12 // 使能中斷

13 intc_enable(KEY_EINT2);

14

15 return 0;

16 }

終極目標(biāo):執(zhí)行中斷處理程序,只要我們一按下按鍵,就會在串口那里打印”isr_eint2_LEFT“這句話了

1 // EINT2通道對應(yīng)的按鍵,就是GPH0_2引腳對應(yīng)的按鍵,就是開發(fā)板上標(biāo)了LEFT的那個(gè)按鍵

2 void isr_eint2(void)

3 {

4 // 真正的isr應(yīng)該做2件事情。

5 // 第一,中斷處理代碼,就是真正干活的代碼

6 printf(“isr_eint2_LEFT.n”);

7 // 第二,清除中斷掛起

8 rEXT_INT_0_PEND |= (1《《2);

9 intc_clearvectaddr();

10 }

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉