JZ2440 裸機驅動 第9章 中斷體繫結構

来源:http://www.cnblogs.com/sz189981/archive/2017/10/22/7712034.html
-Advertisement-
Play Games

瞭解ARM體系CPU的7種工作模式 瞭解S3C2410/S3C2440中斷體繫結構 掌握S3C2410/S3C2440的中斷服務程式的編寫方法 ...


本章目標:     瞭解ARM體系CPU的7種工作模式     瞭解S3C2410/S3C2440中斷體繫結構     掌握S3C2410/S3C2440的中斷服務程式的編寫方法 9.1 S3C2410/S3C2440 中斷體繫結構 9.1.1 ARM體系CPU 的7種工作模式     ARM體系的CPU有以下7種工作模式:     ① 用戶模式(usr):ARM處理器正常的程式執行狀態;     ② 快速中斷模式(fiq):用於高速數據傳輸或通道處理;     ③ 中斷模式(irq):用於通用的中斷處理;     ④ 管理模式(svc):操作系統使用的保護模式;     ⑤ 數據訪問終止模式(abt):當數據或指令預取終止時進入該模式,可用於虛擬存儲及 存儲保護;     ⑥ 系統模式(sys):運行具有特權的操作系統任務;     ⑦ 未定義指令中止模式(und):當未定義的指令執行時進入該模式,可用於支持硬體協 處理器的軟體模擬。      可以通過軟體來進行模式切換,或者發生各類中斷、異常時CPU自動進入相應的模式。 除了用戶模式外,其他6種工作模式屬於特權模式。大多數程式運行與用戶模式,進入特權 模式是為了處理中斷、異常,或者訪問被保護的系統資源。     另外,ARM體系的CPU有以下兩種工作狀態。     ① ARM狀態:此時處理器執行32位的字對齊的ARM指令;     ② Thumb狀態:此時處理器執行16位的、半字對齊的Thumb指令。     實際上,本書所有程式都是在ARM狀態下運行的,而CPU一上電就處於ARM狀態,所 以無需關心CPU的狀態。     ARM920T有31個通用的32位寄存器和6個程式狀態寄存器。這37個寄存器分為7組,進 入某個工作模式時,就是用它那組的寄存器。有些寄存器,不同的工作模式下有自己的副 本,當切換到另一個模式時,那個模式的寄存器副本將被使用:這些寄存器被稱為備份寄 存器(圖9.1中使用灰色三角形標記的寄存器)。      圖中R0~R15可以直接訪問,這些寄存器中除R15外都是通用寄存器,即它們既可以 用於保存數據,也可以用於保存地址。另外,R13~R15稍有不同。     R13被稱為“ 棧指針 ”   寄存器,通常被用來保存棧指針;     R14被稱為“ 程式連接 ”寄存器或“ 連接 ”寄存器,當執行BL子程式調用指令時,R14中 得到R15(程式計數器PC)的備份。而發生中斷或異常時,對應的R14_svr、R14_irq、 R14_fiq、R14_abt或R14_und中保存R15返回值。     R15是程式計數器。     快速中斷模式有7個備份寄存器R8~R14(即R8_fiq~R14_fiq),這使得進入快速中斷模式 執行很大部分程式時(只要它們不改變R0~R7),甚至不需要保存任何寄存器。用戶模式、 管理模式、數據訪問終止模式和未定義指令中止模式都含有兩個獨占的寄存器副本R13和 R14,這樣可以令每個模式擁有自己的棧指針寄存器和連接寄存器。     每種工作模式除R0~R15共16個寄存器外,還有第17個寄存器——CPSR,即“當前程式 狀態寄存器”。其中一些位被用來標識各種狀態,一些位被用來標識當前處於什麼工作模式。     CPSR中各位意義如下,如圖9.2所示。     (1)T位:置位時,CPU處於Thumb狀態:否則處於ARM狀態。     (2)中斷禁止位:I位和F位屬於中斷禁止位。它們被置位時,IRQ中斷、FIQ中斷分別 被禁止。     (3)工作模式位:表明CPU當前處於什麼工作模式。可以編寫這些位,使CPU進入指 定的工作模式。     除CPSR外,還有快速中斷模式、中斷模式、管理模式、數據訪問終止模式和未定義指 令中止模式等5種工作模式和一個寄存器——SPSR(程式狀態保存寄存器)。當切換進這些 模式時,在SPSR中保存前一個模式的CPSR值,返回前一個模式時,將SPSR的值恢復到 CPSR中。     綜上所述,當一個異常發生時,將切換進入相應的工作模式(異常模式),這時ARM920T CPU核將自動完成如下事情:     (1)在異常模式的連接寄存器R14中保存前一個模式的下一條即將執行的指令地址。 對於ARM狀態,這個值是當前PC值加4或加8(參考表9.1);     (2)將CPSR的值複製到異常模式的SPSR;     (3)將CPSR的工作模式位設為這個異常對應的工作模式;     (4)令PC值等於這個異常模式在異常向量表中的地址,即跳轉去執行異常向量表中的相應指令。     相反地,從異常模式返回之前的工作模式時,需要通過軟體完成如下事情:     (1)將之前保存在連接寄存器中的前一工作模式的一個指令地址減去一個適當的值(參考 表9.1)後賦給PC寄存器;     (2)將SPSR的值複製回CPSR;    9.1.2 S3C2410、S3C2440中斷控制器     對於不同的CPU,中斷的處理只是細節不同。S3C2410/S3C2440的中斷控制器結構 如圖9.4所示,可以看出中斷的處理細節。      SUBSRCPND和SRCPND寄存器表明有哪些中斷被觸發了,正在等待處理(pending); SUBMASK(INTSUBMSK寄存器)和MASK(INTMSK寄存器)用於屏蔽某些中斷。     圖中“Request sources(with sub-register)”表示INT_RXD0、INT_TXD0等中斷源(S3C2410 中這類中斷有11個,而S3C2440中有15個)。它們不同於“Request sources(without sub-register)”。     (1)“Request sources(without sub-register)”中的中斷源被觸發之後,SRCPND寄存器中 相應位被置1,如果此中斷沒有被INTMSK寄存器屏蔽掉或快速中斷的話,它將被進一步處理。     (2)對於“Request sources(with sub-register)”中的中斷源被觸發之後,SUBSRCPND寄存器 中的相應位被置1,如果此中斷沒有被INTSUBMSK寄存器屏蔽的話,它在SRCPND寄存器中 的相應位也被置1,之後的處理過程就和Request sources(without sub-register)”一樣了。     繼續沿著圖9.4的箭頭前進:在SRCPND寄存器中,被觸發的中斷的相應位被置1,等待處理。
    (1)如果被觸發的中斷中有快速中斷(FIQ)——MODE (INTMOD寄存器)中為1的位對應的 中斷時FIQ,則CPU進入快速中斷模式(FIQ Mode)進行處理。 註意:FIQ只能分配一個,即INTMOD中只能有一位設為1。     (2)對於一般中斷IRQ,可能同時又幾個中斷觸發,未被INTMSK寄存器屏蔽的中斷經過比較 後,選出優先順序最高的中斷,此時中斷在INTPND寄存器中的相應位被置1,然後CPU進入中斷模 式(IRQ Mode)進行處理。中斷處理服務程式可以通過讀取INTPND寄存器或者INTOFFSET寄存器 來確定中斷源。     圖9.4中的“Priority”表示中斷的優先順序判斷,通過PRIORITY寄存器進行設置,這在9.1.3小節介紹。
    綜上所述,使用中斷的步驟如下:     (1)設置好中斷模式和快速終端模式下的棧:         當發生      中斷IRQ時,CPU進入      中斷模式,這時使用       中斷模式下的棧;         當發生快速中斷FIQ時,CPU進入快速中斷模式,這時使用快速中斷模式下的棧。     (2)準備好中斷處理函數。     ① 異常向量。     在異常向量表中設置好當進入中斷模式或快速中斷模式時的跳轉函數,它們的異常向量 地址分別為:0x0000 0018、0x0000 001c。     ② 中斷服務程式(ISR)。     IRQ、FIQ的跳轉函數,最終將調用具體中斷的服務函數。     對於IRQ,讀取INTPND寄存器或INTOFFSET寄存器的值來確定中斷源,然後分別處理。     對於FIQ,因為只有一個中斷可以設為FIQ,無須判斷中斷源。     ③ 清除中斷:如果不清除中斷,則CPU會誤認為有發生了一次這個中斷。     可以調用ISR之前清除中斷,也可以在調用ISR之後清除,這取決於在ISR執行過程中,這 個中斷是否可能繼續發生、是否能夠丟棄。     如果可能發生並不能丟棄,則在調用ISR之前清除中斷,這樣在ISR執行過程中發生的中斷 能夠被各寄存器再次記錄並通知CPU;     如果不會發生或者可以丟棄,則在調用ISR之後清除中斷。     (3)進入、退出中斷模式或快速中斷模式時,需要保存、恢復中斷程式的運行環境。     ① 對於IRQ,進入和退出的代碼如下:
1 sub     lr, lr, #4                    @計算返回地址
2 stmdb   sp!, {r0-r12, lr}     @保存使用的寄存器
3 ... ...                                   @處理中斷
4 ldmia   sp!, {r0-r12, pc}^   @中斷返回
5                                           @^表示將spsr的值賦給cpsr
進入和退出IRQ     ② 對於FIQ,進入和退出的代碼如下:
1 sub    lr, lr #4                       @計算計算返回地址
2 stmdb    sp!, {r0-r7, lr}        @保存使用到的寄存器
3 ... ...                                    @快速處理中斷
4 sdmia    sp!, {r0-r7, pc}^    @快速中斷返回
5                                            @^表示將spsr的值賦給cpsr
進入和退出FIQ     (4)根據具體中斷,設置相關外設。比如對於GPIO中斷,需要將相應引腳的功能設為 “外部中斷”、設置中斷觸發條件(低電平觸發、高電平觸發、下降沿觸發還是上升沿觸發) 等。一些中斷擁有自己的屏蔽寄存器,還要開啟它。     (5)對於“Request sources(without sub-register)”中的中斷,將INTSUBMSK寄存 器中相應位設為0。     (6)確定使用此中斷的方式:FIQ還是IRQ。         ① 如果是FIQ,則在INTMOD寄存器中設置相應位為1;         ② 如果是IRQ,則在RIOPITY寄存器中設置優先順序;     (7)如果是IRQ,將INTMSK寄存器中相應位設為0(FIQ不受INTMSK寄存器控制);     (8)設置CPSR寄存器中的I-bit(對於IRQ)或F-bit(對於FIQ)為0,使能IRQ或FIQ。 9.1.3 中斷控制寄存器     SUBSRCPND、INTSUBMSK這兩個寄存器中相同的位對應相同的中斷;     SRCPND、INTMSK、INTMOD、INTPND這4個寄存器中相同的位對應相同的中斷。     下麵沿著圖9.4的箭頭方向講解所涉及的寄存器。 1.SUBSRCPND寄存器(SUB SOURCE PENDING)     SUBSRCPND寄存器被用來標識INT_RXD0、INT_TXD0等中斷(S3C2410中這類中斷有11 個,而S3C2440中有15個)是否發生,每位對應一個中斷。當這些中斷發生並且被INTSUBMSK 寄存器(下麵介紹)屏蔽,則它們中的若幹位將“彙集”出現在SRCPND寄存器(下麵介紹)的 一位上。比如SUBSRCPND寄存器中的3個中斷INT_RXD0、INT_TXD0、INT_ERR0,只要有一個 發生了且沒有被屏蔽,則SRCPND寄存器中的INT_UART0位被置1。     要清除中斷時,向SUBSRCPND寄存器中某位寫入1即可令此位為0;寫入0無效,數據 不變。     SUBSRCPND寄存器中各位對應的中斷、SUBSRCPND寄存器中哪幾位“彙集”成SRCPND 寄存器中的哪一位,請參考數據手冊。 2.INTSUBMSK寄存器     被用來屏蔽SUBSRCPND寄存器所標識的中斷。其中的某位被設為1時,對應中斷被屏蔽。 3.SRCPND寄存器     其中的每一位被用來表示一個(或一類)中斷是否已經發生,即圖9.4中輸入“SRCPND” 的兩類中斷:使用SUBSRCPND/INTSUBMSK控制的中斷;不適用SUBSRCPND/INTSUBMSK控制的中 斷。     SRCPND寄存器的操作與SUBSRCPND寄存器類似,想相除某一位,向該位寫入1。     SRCPND中各位對應哪個(哪類)中斷,請參考數據手冊。 4.INTMSK寄存器    
    被用來屏蔽SRCPND寄存器所標識的中斷。其中某些位被設為1時,對應中斷被屏蔽。     本寄存器只能屏蔽被設為IRQ的中斷,不能屏蔽被設為FIQ的中斷,請參考下麵的 INTMOD寄存器。 5.INTMOD寄存器     本寄存器中某位被設為1時,對應中斷被設為FIQ,即此中斷發生時,CPU進入FIQ 模式,這通常用來處理特別緊急的中斷。 註意:同一時間內,INTMOD中只能有一位被設為1。 6.PRIORITY寄存器     上面INTMOD寄存器中,將設為1的中斷成為快速中斷(FIQ),其餘為0的中斷成為普通 中斷(IRQ)。     當有多個普通中斷同時發生時,中斷控制器將選出最高優先順序的中斷,首先處理它。 優先順序判斷通過7個仲裁器完成,包括6個一級和1個二級仲裁器,結構圖如圖9.5所示。     每個仲裁器含6個輸入引腳REQ0~REQ5。對於每個仲裁器,PRIORITY寄存器使用3位來 控制其行為:一位被用於選擇仲裁器的工作模式,被稱為ARB_MODE;兩位被用於控制各輸入 信號的優先順序,稱為ARB_SEL。     SRB_SEL的取值和REQ0~REQ5的優先順序如表9.2所示。     當某個仲裁器的ARB_MODE位被設為0時,它的ARB_SEL位是不會自動變化的,此時這個 仲裁器的6個輸入引腳的優先順序固定不變(當然,可以通過軟體修改ARB_SEL來改變它們的優 先級)。當ARB_MODE位被設為1時,ARB_SEL會隨著“已經被服務的REQx(x:1~4)”自動變化, 順序如表9.3所示。     結合表9.2、表9.3可知:當ARB_MODE為1時,某個REQx(x:1~4)被服務之後,它的 優先順序變為REQ0~REQ4中的最低。     PRIORITY寄存器中位[0:6]對應這7個仲裁器的ARB_MODE位(位[0]是ARB_MODE0,依 此類推),位[7:20]位對應這7個仲裁器的ARB_SEL位([7:8]是ARB_SEL0,依此類推)。 7.INTPND寄存器     經過中斷優先順序仲裁器選出優先順序最高的中斷後,這個中斷在本寄存器中的相應 位被置1,隨後,CPU進入中斷模式處理它。     同一時間內,此寄存器只有一位被置1;在ISR中,可以根據這個位確定是哪個中斷。 清除中斷時,向這個位寫入1。 8.INTOFFSET寄存器     這個寄存器被用來表示INTPND寄存器中哪位被置1了,即INTPND寄存器中位[x]為1時, INTOFFSET寄存器的值為x(x為0~31)。     在清除SRCPND、INTPND寄存器時,本寄存器被自動清除。 9.2 中斷控制器操作實例:外部中斷 9.2.1 按鍵中斷代碼詳解     開發板上,K1~K4四個按鍵所接的CPU引腳可以設成外部中斷功能。本程式的main 函數是一個不做任何事的無線迴圈,程式的功能完全靠中斷來驅動:當按下某個按鍵時, CPU調用其中斷服務程式來點亮對應的LED。     程式代碼在/work/hardware/int目錄下,有4個源文件:head.S、init.c、interrupt.c和 main.c,1個頭文件s3c24xx.h。 1.head.S代碼詳解 先看head.S文件:
 1 @*************************************
 2 @File:head.S
 3 @功能:初始化、設置中斷模式、系統模式的棧,設置好中斷處理函數
 4 @*************************************
 5 
 6 .extern main
 7 .text
 8 .global _start
 9 _start:
10 @*************************************
11 @中斷向量,本程式中,除了Reset和HandleIRQ外,其他異常都沒有使用
12 @*************************************
13     b    Reset
14     
15 @ 0x04:未定義指令終止模式的向量地址
16 HandleUndef:
17     b    HandleUndef
18     
19 @ 0x08:管理模式的向量地址,通過SWI指令進入此模式
20 HandleSWI:
21     b    HandleSWI
22     
23 @ 0x0c:指令預取終止導致的異常向量的向量地址
24 HandlePrefetchAbort:
25     b    HandlePrefetchAbort
26     
27 @ 0x10:數據訪問終止導致的異常向量地址
28 HandleDataAbort:
29     b    HandleDataAbort
30     
31 @ 0x14:保留
32 HandleNotUsed:
33     b    HandleNotUsed
34     
35 @ 0x18:中斷模式的向量地址
36     b    HandleIRQ
37     
38 @ 0x1c:快速中斷模式的向量地址
39 HandleFIQ:
40     b    HandleFIQ
41     
head.S     上面的第17、21、25、29、33、36和40行等共7條指令所在地址為0x00、0x04、......、 0x1c,這些地址上的指令被稱為“異常向量”。當發生各類異常時,CPU進入對應的工作模 式,並跳轉去執行它的“異常向量”。比如,當複位時,CPU進入系統模式,並跳轉到0x00 地址開始執行;當發生中斷時,CPU進入中斷模式,並跳到0x18地址開始執行。     本程式中,只使用到“複位”和“中斷”對應異常向量,其他異常向量沒有實際作用。     0x00地址處的指令為“ b Reset ”,在系統複位後,這條指令將跳去執行標號“Reset”開始 的代碼,它們完成一些初始化,代碼如下:
 1 接上面
 2 42行 Reset:
 3 43行     ldr   sp, =4096            @設置棧指針,以下都是C函數,需要在調用前設置好棧
 4 44行     bl    disable_watch_dog    @關閉看門狗
 5 45行     
 6 46行     msr    cpsr_c, #0xd2        @進入中斷模式
 7 47行     ldr    sp,    =3072        @設置中斷模式棧指針
 8 48行   
 9 49行     msr    cpsr_c, #0xdf        @進入系統模式
10 50行     ldr    sp,    =4096        @設置系統模式棧指針
11 51行                                 @起始複位之後,CPU就處於系統模式
12 52行                                 @前面的“ldr sp, =4096”完成同樣的功能,此句可省略
13 53行
Reset代碼     註意,這是還沒有完成所有初始化,所以還不能開中斷——第46、49行的代碼中,CPSR寄存 器的I位、F位都被設為1.第47、50行中sp寄存器並不是同一個寄存器,前者為sp_irq,後者為sp_sys。     繼續向下看代碼:
接上面
54行  bl init_led                @初始化LED的GPIO管腳
55行  bl init_irq                @調用中斷管腳初始化函數,在init.c中
56行  msr cpsr_c, #0x5f   @設置I-bit=0,開啟IRQ中斷
57行
58行  ldr lr, =halt_loop     @設置返回地址
59行  ldr pc, =main          @調用main函數
60行 halt_loop:
61行  b halt_loop
    main函數中不做任何事的無限迴圈,當按下按鍵時,這個迴圈被打斷,CPU進入中斷模式,執行 第36行的“ b HandleIRQ ”的指令。     標號“HandleIRQ”開始的代碼用於處理中斷,如下所示:
 1 接上面
 2 62行 HandleIRQ:
 3 63行  sub   lr, lr #4               @計算返回地址
 4 64行  stmdb sp!, {r0-r12, lr}     @保存使用到的寄存器
 5 65行                                @註意,此時的sp是中斷模式的sp
 6 66行                                @初始值是上面設置的3072
 7 67行 
 8 68行  ldr   lr, =int_return         @設置調用ISR即EINT_Handle函數後的返回地址,即為第71行指令的地址
 9 69行  ldr   pc, =EINT_Handle        @調用中斷服務函數,在interrupt.c中
10 70行 int_return:
11 71行  ldmia sp!, {r0-r12, pc}^    @中斷返回,^表示將spsr的值複製到cpsr
12 72行 
HandleIRQ     第63行請參考表9.1,lr寄存器的值等於被中斷指令的地址加4,所以返回地址為lr-4。     第64行用於保存被中斷程式的運行環境,即各個寄存器。其中的sp為中斷模式的棧。 在上面的47行初始化。這樣,r0~r12、lr這14個寄存器被保存在中斷模式的棧中。     第69行調用中斷服務函數EINT_Handle(代碼在interrupt.c中,下麵詳述)。     當EINT_Handle函數處理完所有發生的中斷後,返回71行的指令。它恢復前面第64行 保存的各個寄存器,即恢復被中斷程式的運行環境 :從棧中恢復r0~r12、pc這14個寄存器 的值,同時,將SPSR寄存器的值複製到CPSR(在進入中斷模式時,CPU自動將原來的 CPSR的值保存到SPSR中),這導致CPU切換到原來的工作模式。 2.init.c中與中斷相關的代碼詳解     下麵詳細講述前面略過的init_irq函數,它在init.c中
 1 37行 /*
 2 38行 * 初始化GPIO引腳為外部中斷
 3 39行 * GPIO引腳為外部中斷時,預設低電平觸發,IRQ方式(不用設置INTMOD)
 4 40行 */
 5 41行 void init_irq()
 6 42行 {
 7         // S2,S3對應的2根引腳設為中斷引腳 EINT0,ENT2
 8 43行     GPFCON &= ~(GPF0_msk | GPF2_msk);
 9 44行     GPFCON |= GPF0_eint | GPF2_eint;
10         // S4對應的引腳設為中斷引腳EINT11
11         GPGCON &= ~GPG3_msk;
12         GPGCON |= GPG3_eint;
13 45行 
14 46行     //對於EINT11,需要在EINTMASK寄存器中使能它們
15 47行     EINTMASK &= ~(1<<11);
16 48行 
17 49行     /*
18 50行      *設定優先順序
19 51行      *ARB_SEL0 = 00b,ARB_MODE0 = 0;REQ1 > REQ3,即EINT0 > EINT2
20 52行      *仲裁器1、6無須設置
21 53行      *最終:
22 54行      *EINT0 > EINT2 > EINT11, EINT19、即K4 > K3 > K1、K2
23 55行      *EINT11和EINT19的優先順序相同
24 56行      */
25 57行     PRIORITY = (PRIORITY & ((~0x01) | (0x3 << 7))) | (0x0 << 7);
26 58行 
27 59行     //EINT0、EINT2、EINT8_23使能
28 60行     INTMSK &= (~(1 << 0)) & (~(1 << 2)) & (~(1 << 5));
29 61行 }
init.c     使用GPIO的中斷功能時,需要確定它們的中斷觸發方式,我們使用預設的低電平觸發, 所以無須額外設置。     第47行在EINTMASK寄存器中開啟EINT11和19中斷,EINT0和EINT2中斷不受 EINTMASK寄存器控制。這個寄存器可以屏蔽的中斷請參考數據手冊。     第57行用於設置中斷優先順序。請參考圖9.5,EINT0和2被接到仲裁器0的REQ1、REQ3, 程式中設置ARB_SEL0為0(即0b00,參考表9.2),所以REQ1的優先順序高於REQ3。     程式中設置ARB_MODE0為0,所以仲裁器0中各優先順序保持不變。     EINT8~EINT23公用仲裁器1的REQ1。     仲裁器0、1的輸出接到仲裁器6的REQ0、REQ1,而仲裁器的REQ0優先順序總是高於REQ1, 所以這4個控制的優先順序如下:EINT0 > EINT2 > EINT11。     本程式使用GPIO預設的中斷模式——IRQ方式(不是FIQ),所以不用設置INTMOD寄存器。     最後,在第60行,將INTMSK寄存器中EINT0、2、8_23這3個(類)中斷對應的位設為0, 使能中斷(註意,即使在這裡,中斷仍未完全開啟,head.S第56行才打開最後一個開關)。 3.interrupt.c中的中斷處理函數     上面講解了有關的初始化、中斷的進入和退出,真正的處理函數為EINT_Handle,它被稱 為中斷服務程式(ISR),代碼在interrupt.c中,如下所示:
 1 #include "s3c24xx.h"
 2 
 3 void EINT_Handle()
 4 {
 5     unsigned long oft = INTOFFSET;
 6     unsigned long val;
 7     
 8     switch( oft )
 9     {
10         // S2被按下
11         case 0: 
12         {   
13             GPFDAT |= (0x7<<4);   // 所有LED熄滅
14             GPFDAT &= ~(1<<4);      // LED1點亮
15             break;
16         }
17         
18         // S3被按下
19         case 2:
20         {   
21             GPFDAT |= (0x7<<4);   // 所有LED熄滅
22             GPFDAT &= ~(1<<5);      // LED2點亮
23             break;
24         }
25 
26         // K4被按下
27         case 5:
28         {   
29             GPFDAT |= (0x7<<4);   // 所有LED熄滅
30             GPFDAT &= ~(1<<6);      // LED4點亮                
31             break;
32         }
33 
34         default:
35             break;
36     }
37 
38     //清中斷
39     if( oft == 5 ) 
40         EINTPEND = (1<<11);   // EINT8_23合用IRQ5
41     SRCPND = 1<<oft;
42     INTPND = 1<<oft;
43 }
interrupt.c     第5行用來讀取INTOFFSET寄存器,用來標識INTPND寄存器中哪位被設為1。此值位0時 表示INTPND寄存器的位[0]為1,即EINT0中斷發生了,這說明K4被按下,以此類推。     註意:清除中斷時,順序很重要,先EINTPEND,然後是SRCPND,最後是INTPND。 4.主函數     在main.c中什麼也不做,如下所示:
1 int main()
2 {
3     while(1);
4     return 0;
5 }
main.c     為了更形象地瞭解本程式,下麵用圖9.6.來演示代碼的執行過程,註意其中SP、PC寄存器的變化。    9.2.2 實例測試     在源碼目錄INT下執行make命令生成int.bin,燒入NAND Flash後,按下複位鍵啟動。輪流按下K1~K4, LED1~LED4被輪流點亮;同時按下K3、K4時,只有LED4被點亮。 附:代碼: 鏈接: https://pan.baidu.com/s/1kV24a9L 密碼: tfab
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、安裝包 先從網路上,下載Mysql安裝包,複製到U盤 下載地址:https://dev.mysql.com/downloads/mysql/ 二、掛載U盤 2.1查看分區 先輸入命令 cat /proc/partitions 插入U盤,重新輸入命令 cat /proc/partitions 結果 ...
  • 熟悉Oracle上機環境及Oracle客戶端的配置;熟練掌握和使用DDL語言,建立、修改和刪除資料庫表、主鍵、外鍵約束關係和索引。 (修改資料庫表名) 將資料庫表S1改名為Student_Temp。 在定義外鍵約束條件時,不能把其他表中沒有的屬性定義在本表的外鍵中,否則會生辰一個錯誤; 在建表時,因 ...
  • 一、流程式控制制語句 1) 迴圈語句 == loop .. end loop 簡單的迴圈,至少被執行一次 == while ... loop end loop == for 2) 控制語句 == goto 用於跳轉到指定的標號去執行,不建議使用 語法: goto 標號名 == null 語句 null語 ...
  • 一、概述 pl/sql (procedural lanaguage/sql)是 oracle 在標準 sql 上的擴展 。不僅允許嵌入sql 語言,還可以定義變數和常量,允許使用條件語句和迴圈語句,允許使用例外處理錯誤。 -- 可以用來編寫過程,函數,和觸發器 -- 上述對象是放在資料庫中的 //數 ...
  • 工作中遇到的數據更新,學習記錄。 1、使用update進行數據更新 1)最簡單的更新 update tablea a set a.price=1.00 2)帶條件的數據更新 update tablea a set a.price = 2.00 where a.id='02' 3)兩張表關聯更新為固定 ...
  • 瞭解UART原理; 掌握S3C2410/S3C2440中UART的使用 ...
  • Centos 7 安裝與配置 1. 安裝VMware。 2. 安裝centos7 首先右鍵“新建虛擬機”,選擇 “典型”安裝,如下圖: 點擊下一步,選擇“稍後安裝操作系統”,如圖: 選擇好對應的操作系統, 然後,選擇centos的目錄路徑,如圖: 指定磁碟容量,預設20g,可以調整。空間逐漸增加,上 ...
  • 瞭解S3C2410/S3C2440的時鐘體繫結構 掌握通過設置MPLL改變系統時鐘的方法 掌握在不同的頻率下設置存儲控制器的方法 掌握PWM定時器的用法 瞭解WATCHDOG定時器的用法 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...