<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          第5課:ARM的中斷

          作者: 時間:2016-11-11 來源:網(wǎng)絡(luò) 收藏
          中斷分為硬件中斷和軟件中斷SWI

          而硬件中斷有內(nèi)部中斷,即中斷控制器中所列出的那些中斷。而外部中斷在中斷控制器里列的是EINT。

          本文引用地址:http://www.ex-cimer.com/article/201611/316802.htm

          總共有60個中斷源,而在中斷控制器中列出32個,還有一些子中斷在子中斷控制器里列出。這些控制器我們都是通過寄存器的某一位來控制。

          中斷發(fā)生之后的流程:

          1把下一條指令的地址放入LR,不過PC是5級流水線,所以LR的值要減去4才是正真的下一條指令的地址。

          2把cpsr復(fù)制到中斷模式的spsr

          3pc設(shè)置到0x18的位置,這個位置是中斷向量表,他指引程序跳轉(zhuǎn)到中斷處理程序。而中斷處理程序的作用是1:保存上下文2:繼續(xù)跳轉(zhuǎn)到中斷服務(wù)程序。

          4退出的時候要恢復(fù)上下文,最重要的是把中斷的spsr復(fù)制到cpsr

          以下介紹下用到的寄存器:

          1 SRCPND 它只要發(fā)送一次中斷,該相應(yīng)位就變成1。即使那個中斷源被屏蔽了,這個位還是置1.

          2 SUBSRCPND 子中斷源未決寄存器。

          3 INTMSK 中斷源屏蔽

          4 INTSUBMSK 子中斷源屏蔽

          5 INTOFFSET 讀這個寄存器 方便讀出是哪個中斷,用10進(jìn)制表示。

          以下來做個例子:

          在主程序中小燈一直閃,然后串口接受到數(shù)據(jù),產(chǎn)生中斷,然后回顯數(shù)據(jù)。

          這個crt0.s 是文件的入口,該程序放在0x0的位置,所以一開始進(jìn)入的是中斷向量表

          .extern main
          .extern EINT_Handle
          .externinit_irq
          .text
          .global _start
          _start:
          bReset
          HandleUndef:
          bHandleUndef
          HandleSWI:
          bHandleSWI
          HandlePrefetchAbort:
          bHandlePrefetchAbort
          HandleDataAbort:
          bHandleDataAbort
          HandleNotUsed:
          bHandleNotUsed

          bHandleIRQ@0x18

          HandleFIQ:
          bHandleFIQ

          Reset:
          ldr r0, =0x53000000 @ WATCHDOG close
          mov r1, #0x0
          str r1, [r0]
          msr cpsr_c, #0xd2 @進(jìn)入中斷模式
          ldr sp, =3072 @設(shè)置中斷模式的sp
          msr cpsr_c, #0xd3 @進(jìn)入svc模式
          ldr sp, =4096
          bl init_irq
          msr cpsr_c, #0x53 @把svc的i位置0

          ldr lr, =halt_loop @設(shè)置返回地址
          ldr pc, =main @ 進(jìn)入主程序

          HandleIRQ:@中斷處理程序
          sub lr, lr, #4
          stmdb sp!, { r0-r12,lr } @ 保存環(huán)境
          ldr lr, =int_return

          ldr pc, =ISR_Handle @進(jìn)入中斷服務(wù)程序
          int_return:
          ldmia sp!, { r0-r12,pc }^ @恢復(fù)環(huán)境
          halt_loop:
          bhalt_loop
          這個是程序的主框架。

          以下是中斷服務(wù)程序int.c

          #include "addr.h"

          void init_irq()
          {
          INTMSK = ~(1<<28);
          INTMOD = 0;
          INTSUBMSK = 0xfffffffe;
          }

          void EINT_Handle()
          {
          unsigned long oft = INTOFFSET;
          if(oft == 28){
          if(SUBSRCPND & 1){
          UTXH0 = URXH0;//這里RX里面的數(shù)據(jù)一定要讀走,不然中斷有問題。不然會根據(jù)RX interpute type 選擇模式的不同有不同的效果。
          SUBSRCPND |= 1;//這里清中斷,要置1,清中斷有一定順序。從src子到src再到int
          SRCPND |= 1< INTPND |= 1<}
          }

          }

          以下是main主程序:主要初始化燈和串口,執(zhí)行小燈閃

          #include"addr.h"
          #define UART_CLK 50000000
          #define UART_BAUD_RATE 115200
          #define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1
          void wait(int time)
          {
          do{
          time--;
          }
          while(time>0);
          }

          void init_uart()
          {
          GPHCON |=0xa0;
          GPHUP = 0x0c;
          ULCON0 = 0x3;
          UCON0 = 0x5+ (1<<8);
          UFCON0 = 0;
          UMCON0 = 0;
          UBRDIV0 = UART_BRD;
          }

          void init_led()
          {
          GPECON = GPE12_out|GPE13_out;
          }

          void uart_write(char *data)
          {
          while (*data != 看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();