在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM系統(tǒng)中斷產(chǎn)生流程

            ARM系統(tǒng)中斷產(chǎn)生流程

            作者: 時間:2016-11-20 來源:網(wǎng)絡(luò) 收藏

            中斷源按照硬件位置分為外部中斷源和內(nèi)部中斷源,外部中斷源和內(nèi)部中斷源又包含子外部中斷源和子內(nèi)部中斷源,如上圖所示(畫了一整天)。
            1.子內(nèi)部中斷源的產(chǎn)生
            以UART0接收數(shù)據(jù)產(chǎn)生INT_RXD0中斷為例,INT_RXD0產(chǎn)生后進入SUBSRCPND子中斷源暫存寄存器,設(shè)置INT_RXD0對應(yīng)的中斷位,中斷信號經(jīng)過INTSUBMSK子中斷屏蔽寄存器,如果INT_RXD0信號對應(yīng)位沒有被置位(屏蔽掉),中斷信號繼續(xù)向前傳遞,經(jīng)過子內(nèi)部中斷源聚合器,將INT_RXD0聚合成對應(yīng)的中斷源信號INT_UART0,設(shè)置SRCPND中斷源暫存寄存器里INT_UART0位,經(jīng)過INTMSK中斷屏蔽寄存器,如果INT_UART0信號沒有被屏蔽掉,中斷信號進入INTMOD中斷模式寄存器判斷是否為快速中斷,如果被編程為快速中斷,直接打斷ARM內(nèi)核,進入中斷處理,如果中斷信號為一般中斷,進入中斷優(yōu)先級仲裁器進入優(yōu)先級仲裁,如果INT_UART0信號為最高優(yōu)先級或只有INT_UART0中斷信號產(chǎn)生,則該中斷信號被記錄到INTPND最高優(yōu)先級中斷暫存寄存器,同時設(shè)置INTOFFSET的值為中斷號28,最終將中斷信號打斷ARM內(nèi)核進行中斷處理。如果同時產(chǎn)生多個中斷且INT_UART0不是最高優(yōu)先級,則該中斷信號不會被處理,等最高優(yōu)先級信號處理完后,再次進行優(yōu)先級仲裁,也就是說中斷信號不消失,一直保存在SRCPND里,只到被處理為止。
            2.內(nèi)部中斷源的產(chǎn)生
            該過程在子內(nèi)部中斷處理過程中已經(jīng)包含,中斷信號產(chǎn)生后直接進入SRCPND里,然后經(jīng)歷上述子內(nèi)部中斷后期處理過程。
            3.子外部中斷的產(chǎn)生
            外部中斷源共有24個,其中EINT0~EINT3為外部中斷源,EINT4_7,EINT8_23為復(fù)合中斷源,他們包含有子外部中斷源。
            由于外部硬件直接掛接到I/O Ports(詳見S3C2440A硬件手冊第9章)上的,我們要想讓外設(shè)硬件中斷得到處理,要先從EINT0~EINT23里選擇中斷信號,我們以EINT11為例,介紹子外部中斷處理過程。
            通常CPU內(nèi)部引出引腳都是復(fù)用的,也就是說一根CPU引腳可以有多種功能,可以設(shè)置其為輸入信號線,輸出信號線或中斷信號線,要想讓硬件產(chǎn)生中斷,首先要對可以產(chǎn)生中斷的引腳進行編程,設(shè)置該引腳為中斷信號線。EINT11中斷信號對應(yīng)CPU引腳為GPG3,通過設(shè)置GPGCON[7:6] = 0b10,可以設(shè)置該引腳為中斷信號線。
            表3-14 GPGCON寄存器



            設(shè)置了CPU管腳為中斷信號線之后,還要通過設(shè)置EXTINT0寄存器來指定中斷信號的觸發(fā)方式:高電平觸發(fā),低電平觸發(fā),電平上升沿,下除沿,雙沿觸發(fā)。


            圖3-9電平信號觸發(fā)示意圖
            由于按鍵按下時讓它產(chǎn)生中斷,也就是從高電平變?yōu)榈碗娖綍r產(chǎn)生(上節(jié)按鍵中斷原理),因此我們設(shè)置EINT11中斷信號的觸發(fā)方式為下降沿觸發(fā),EXTINT1[14:12] = 0b01x
            表3-15 EXTINT1寄存器



            設(shè)置完觸發(fā)方式之后,當外設(shè)中斷信號線上的電平達到觸發(fā)條件時,通過外部中斷產(chǎn)生器產(chǎn)生中斷信號,然后將子外部中斷暫存寄存器EINTPND中對應(yīng)的EINT11位置1,中斷信號再進入EINTMSK子外部中斷屏蔽寄存器,如果EINT11中斷源信號沒有被屏蔽,則EINT11中斷信號進入子外部中斷聚合器,復(fù)合成EINT8_23中斷信號,然后再經(jīng)歷與前面子內(nèi)部中斷信號一樣的處理機制。
            (1)EINTPEND外部中斷暫存寄存器
            表3-16外部中斷暫存寄存器(EINTPEND)
            寄存器名地址是否讀寫描述復(fù)位默認值
            EINTPEND0x560000A8R/W外部中斷信號暫存寄存器
            0:沒有中斷請求信號
            1:中斷請求信號產(chǎn)生
            0x0000000

            EINTPEND描述初始值
            EINT23[23]0 =未產(chǎn)生中斷1 =產(chǎn)生中斷0
            EINT4[4]0 =未產(chǎn)生中斷1 =產(chǎn)生中斷0
            保留位[3:0]0000

            (2)EINTMASK外部中斷屏蔽寄存器
            表3-17外部中斷屏蔽寄存器(EINTMASK)
            寄存器名地址是否讀寫描述復(fù)位默認值
            EINTMASK0x560000A4R/W外部中斷信號屏蔽寄存器
            0:未屏蔽,中斷可用
            1:屏蔽中斷信號
            0x000FFFFF

            EINTMASK描述初始值
            EINT23[23]0 =未屏蔽1 =屏蔽中斷1
            EINT4[4]0 =未屏蔽1 =屏蔽中斷1
            保留位[3:0]1111
            4.外部中斷源的產(chǎn)生
            外部中斷產(chǎn)生過程讀者可以根據(jù)上面中斷圖自行分析。

            按鍵控制LED燈實驗





            本實驗分三個版本,分別針對三種開發(fā)板:友善之臂QQ2440,友善之臂MINI2440,天嵌TQ2440。每種開發(fā)板對應(yīng)工程在:“sys_irq_開發(fā)板名”目錄下。下面實驗內(nèi)容為針對MINI2440開發(fā)板。
            head.s:
            主要實現(xiàn)安裝異常向量表,處理復(fù)位異常,初始化必要硬件,中斷入口處理等功能。
            ;**********************************************************************
            ;系統(tǒng)中斷實驗(MINI2440)
            ;**********************************************************************
            GPBCONEQU0x56000010
            GPBDATEQU0x56000014
            EXPORT SYS_IRQ
            AREASYS_IRQ,CODE,READONLY
            ENTRY
            ;**********************************************************************
            ;設(shè)置中斷向量,除Reset和HandleIRQ外,其它異常都沒有使用(如果不幸發(fā)生了,
            ;將導(dǎo)致死機)
            ;**********************************************************************
            ; 0x00:復(fù)位Reset異常
            bReset

            ; 0x04:未定義異常(未處理)
            HandleUndef
            bHandleUndef

            ; 0x08:軟件中斷異常(未處理)
            HandleSWI
            bHandleSWI

            ; 0x0c:指令預(yù)取異常(未處理)
            HandlePrefetchAbt
            bHandlePrefetchAbt

            ; 0x10:數(shù)據(jù)訪問中止異常(未處理)
            HandleDataAbt
            bHandleDataAbt

            ; 0x14:未使用異常(未處理)
            HandleNotUsed
            bHandleNotUsed

            ; 0x18:一般中斷異常,跳往HandleIRQ
            bHandleIRQ

            ; 0x1c:快速中斷異常(未處理)
            HandleFIQ
            bHandleFIQ

            Reset;復(fù)位異常處理入口
            ;關(guān)閉看門狗
            ldrr0, = 0x53000000
            movr1, #0
            strr1, [r0]

            blinitmem

            ldrsp,=0x32000000;設(shè)置管理模式棧指針

            IMPORT uart_init
            bluart_init; UART串口初始化

            IMPORT irq_init
            blirq_init;系統(tǒng)中斷初始化

            IMPORT key_init
            blkey_init;按鍵初始化

            IMPORT led_init
            blled_init; LED燈初始化

            msrcpsr_cxsf, #0xd2;切換到中斷模式下
            ldrsp,=0x31000000;設(shè)置中斷模式棧指針

            msrcpsr_cxsf, #0x13;返回管理模式

            ldrlr,=halt_loop;設(shè)置管理模式下返回地址
            IMPORT main
            ldrpc,=main;跳入主函數(shù)main里執(zhí)行
            ;***********************************************************************
            ;中斷處理
            ;***********************************************************************
            HandleIRQ
            sublr,lr,#4;修正返回地址
            stmdbsp!,{r0-r12,lr};保存程序執(zhí)行現(xiàn)場
            ldrlr,=int_return;設(shè)置中斷處理程序返回地址
            IMPORT handle_irq
            ldrpc,=handle_irq;跳入中斷處理程序

            int_return;中斷處理返回標簽
            ldmiasp!,{r0-r12,pc}^恢復(fù)程序執(zhí)行現(xiàn)場,返回繼續(xù)執(zhí)行

            halt_loop
            bhalt_loop

            initmem
            ldrr0, =0x48000000
            ldrr1, =0x48000034
            ;ldrr2, =memdata
            adrr2, memdata
            initmemloop
            ldrr3, [r2], #4
            strr3, [r0], #4
            teqr0, r1
            bneinitmemloop
            movpc,lr

            memdata
            DCD0x22000000;BWSCON
            DCD0x00000700;BANKCON0
            DCD0x00000700;BANKCON1
            DCD0x00000700;BANKCON2
            DCD0x00000700;BANKCON3
            DCD0x00000700;BANKCON4
            DCD0x00000700;BANKCON5
            DCD0x00018005;BANKCON6
            DCD0x00018005;BANKCON7
            DCD0x008e07a3;REFRESH
            DCD0x000000b1;BANKSIZE
            DCD0x00000030;MRSRB6
            DCD0x00000030;MRSRB7

            END;代碼結(jié)束
            該程序主要設(shè)置異常向量表,除了Reset異常和中斷處理被處理以外,其它異常都未被處理,如果發(fā)生時,會產(chǎn)生死循環(huán),Reset異常里主要實現(xiàn)了硬件的基本初始化,如:按鍵,LED燈等,設(shè)置棧指針,用于執(zhí)行C程序,最后跳入C程序的main函數(shù)。在中斷處理異常處理中首先修正返回地址,保存用戶執(zhí)行現(xiàn)場,跳入到中斷處理例程中執(zhí)行。
            sys_init.c:
            硬件初始化文件,里面包含LED,KEY的初始化函數(shù)。
            #include "register.h"
            #include "comm_fun.h"

            #defineTXD0READY(1<<2)//發(fā)送數(shù)據(jù)狀態(tài)OK
            #defineRXD0READY(1)//接收數(shù)據(jù)狀態(tài)OK

            /* UART串口初始化*/
            void uart_init()
            {
            GPHCON |= 0xa0;//GPH2,GPH3 used as TXD0,RXD0
            GPHUP= 0x0;//GPH2,GPH3內(nèi)部上拉
            ULCON0= 0x03;//8N1
            UCON0= 0x05;//查詢方式為輪詢或中斷;時鐘選擇為PCLK
            UFCON0 = 0x00;//不使用FIFO
            UMCON0 = 0x00;//不使用流控
            UBRDIV0 = 12;//波特率為57600,PCLK=12Mhz
            }

            /* UART串口單個字符打印函數(shù)*/
            extern void putc(unsigned char c)
            {
            while( ! (UTRSTAT0 & TXD0READY) );
            UTXH0 = c;
            }

            /* UART串口接受單個字符函數(shù)*/
            extern unsigned char getc(void)
            {
            while( ! (UTRSTAT0 & RXD0READY) );
            return URXH0;
            }

            /* UART串口字符串打印函數(shù)*/
            extern int printk(const char* str)
            {
            int i = 0;
            while( str[i] ){
            utc( (unsigned char) str[i++] );
            }
            return i;
            }

            /*按鍵初始化*/
            int key_init()
            {
            //設(shè)置K1,K2,K3,K4,K5,K6對應(yīng)控制寄存器為中斷模式
            GPGCON = (2<<0) | (2<<6) | (2<<10) | (2<<12) | (2<<14) | (2<<22);
            /*
            01x falling edge triggered下降沿觸發(fā)
            10x Rising edge triggered上升沿觸發(fā)
            11x Both edge triggered雙沿觸發(fā)
            */
            //設(shè)置K1,K2,K3,K4,K5按鍵中斷觸發(fā)方式為上升沿觸發(fā)
            EXTINT1 = (3<<0) | (3<<12) | (3<<20) | (3<<24) | (3<<28);
            EXTINT2 = (3<<12);//設(shè)置K6按鍵中斷觸發(fā)方式為上升沿觸
            printk("按鍵初始化OK/r/n");
            return 0;
            }

            /* Led1~Led4初始化*/
            #define LED1(1<<5)//LED1 GPBDAT[5]
            #define LED2(1<<6)//LED2 GPBDAT[6]
            #define LED3(1<<7)//LED3 GPBDAT[7]
            #define LED4(1<<8)//LED4 GPBDAT[8]

            /*點亮對應(yīng)num號led燈*/
            extern int led_on(int num)
            {
            switch(num)
            {
            case 1:
            GPBDAT = GPBDAT & ~LED1; break;
            case 2:
            GPBDAT = GPBDAT & ~LED2; break;
            case 3:
            GPBDAT = GPBDAT & ~LED3; break;
            case 4:
            GPBDAT = GPBDAT & ~LED4; break;
            default:
            return 0;
            }
            return num;
            }

            /*關(guān)閉num號led燈*/
            extern int led_off(int num)
            {
            switch(num)
            {
            case 1:
            GPBDAT = GPBDAT | LED1; break;
            case 2:
            GPBDAT = GPBDAT | LED2; break;
            case 3:
            GPBDAT = GPBDAT | LED3; break;
            case 4:
            GPBDAT = GPBDAT | LED4; break;
            default:
            return 0;
            }
            return num;
            }

            /*關(guān)閉全部led燈*/
            extern int all_led_off(void)
            {
            GPBDAT = GPBDAT | LED1 | LED2 | LED3 | LED4;
            return 0;
            }

            /* led燈初始化*/
            int led_init(void)
            {
            GPBCON = 0x15400;//設(shè)置GPB7為輸出口
            all_led_off();
            printk("led初始化OK/r/n");
            return 0;
            }

            /*中斷初始化*/
            void irq_init(void)
            {
            //打開KEY1~KEY6的屏蔽位
            INTMSK &= ~(1<<5);
            EINTMASK &= ~((1<<8) | (1<<11) | (1<<13) | (1<<14) | (1<<15) | (1<<19));
            printk("中斷初始化OK/r/n");
            }
            該文件是相關(guān)硬件初始化程序,主要包含了看門狗驅(qū)動,按鍵驅(qū)動,系統(tǒng)中斷驅(qū)動,LED驅(qū)動。
            handle_irq.c:
            中斷處理函數(shù),查出中斷源,中斷處理,清除中斷源。
            #include "register.h"
            #include "comm_fun.h"

            #define EINT_Key_REQUEST5// Key中斷源中斷號(6個按鍵全部使用外部子中斷)
            #define K1_EINT_BIT(1<<8)// K1外部子中斷位
            #define K2_EINT_BIT(1<<11)// K2外部子中斷位
            #define K3_EINT_BIT(1<<13)// K3外部子中斷位
            #define K4_EINT_BIT(1<<14)// K4外部子中斷位
            #define K5_EINT_BIT(1<<15)// K5外部子中斷位
            #define K6_EINT_BIT(1<<19)// K6外部子中斷位
            /*系統(tǒng)中斷處理函數(shù)*/
            void handle_irq()
            {
            unsigned long irqOffSet = INTOFFSET;//取得中斷號
            all_led_off();//關(guān)閉全部Led燈
            if(EINT_Key_REQUEST==irqOffSet){// Key中斷產(chǎn)生(6個按鍵使用一個總中斷號)
            if(K1_EINT_BIT & EINTPEND){
            led_on(1);//點亮Led1
            printk("Key1 pressed/r/n");
            EINTPEND &= K1_EINT_BIT;//清除外部子中斷源
            }else if(K2_EINT_BIT & EINTPEND){
            led_on(2);//點亮Led2
            printk("Key2 pressed/r/n");
            EINTPEND &= K2_EINT_BIT;//清除外部子中斷源
            }else if(K3_EINT_BIT & EINTPEND){
            led_on(3);//點亮Led3
            printk("Key3 pressed/r/n");
            EINTPEND &= K3_EINT_BIT;//清除外部子中斷源
            }else if(K4_EINT_BIT & EINTPEND){
            led_on(4);//點亮Led4
            printk("Key4 pressed/r/n");
            EINTPEND &= K4_EINT_BIT;//清除外部子中斷源
            }else if(K5_EINT_BIT & EINTPEND){
            all_led_off(1);//熄滅全部Led
            printk("Key5 pressed/r/n");
            EINTPEND &= K5_EINT_BIT;//清除外部子中斷源
            }else if(K6_EINT_BIT & EINTPEND){
            all_led_on();//點亮全部Led
            printk("Key6 pressed/r/n");
            EINTPEND &= K6_EINT_BIT;//清除外部子中斷源
            }
            }
            SRCPND &= (1<INTPND = INTPND;//清除中斷結(jié)果
            }
            main.c:
            包含主函數(shù)和延時函數(shù),主要實現(xiàn)字符串的循環(huán)打印。
            #include "register.h"
            #include "comm_fun.h"

            /*延時*/
            void delay(int msec)
            {
            int i, j;
            for(i = 1000; i > 0; i--)
            for(j = msec*10; j > 0; j--)
            /* do nothing */;
            }

            /*主函數(shù)*/
            int main()
            {
            while(1)
            {
            printk("main函數(shù)在運行.../r/n");
            delay(5);//delay
            }
            return 0;
            }



            評論


            技術(shù)專區(qū)

            關(guān)閉