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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 根據(jù)韋東山修改的mini2440中斷的裸機(jī)代碼

          根據(jù)韋東山修改的mini2440中斷的裸機(jī)代碼

          作者: 時(shí)間:2016-11-21 來(lái)源:網(wǎng)絡(luò) 收藏
          這是根據(jù)韋東山的關(guān)于中斷的代碼改成在mini2440板子上可以運(yùn)行的代碼。
          以下是5個(gè)文件的所有內(nèi)容:
          @是注釋符?。?br />
          head.S文件內(nèi)容:


          @**************************************************************************
          @ File:head.S
          @ 功能:初始化,設(shè)置中斷模式、系統(tǒng)模式的棧,設(shè)置好中斷處理函數(shù)
          @**************************************************************************

          .extern main
          .text
          .global _start
          _start:
          @**************************************************************************
          @ 中斷向量,本程序中,除Reset和HandleIRQ外,其他異常都沒(méi)有使用
          @**************************************************************************
          @0x00地址處的指令為"b Reset",在系統(tǒng)復(fù)位后,這條指令將跳去執(zhí)行標(biāo)號(hào)"Reset"開(kāi)始的代碼
          b Reset

          @0x04:未定義指令終止模式的向量地址
          HandleUndef:
          b HandleUndef

          @0x08:管理模式的向量地址,通過(guò)SWI指令進(jìn)入此模式
          HandleSWI:
          b HandleSWI

          @0x0c:指令預(yù)取終止導(dǎo)致的異常的向量地址
          HandlePrefetchAbort:
          b HandlePrefetchAbort

          @0x10:數(shù)據(jù)訪問(wèn)終止導(dǎo)致的異常的向量地址
          HandleDataAbort:
          b HandleDataAbort

          @0x14:保留
          HandleNotUsed:
          b HandleNotUsed

          @0x18:中斷模式的向量地址
          b HandleIRQ

          @0x1c:快中斷模式的向量地址
          HandleFIQ:
          b HandleFIQ

          Reset:
          ldr sp,=4096
          @設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧。棧是用 @來(lái)保存C函數(shù)的變量和返回地址
          bl disable_watch_dog @關(guān)閉WATCHDOG,否則CPU會(huì)不斷重啟

          msr cpsr_c,#0xd2 @進(jìn)入中斷模式
          ldr sp,=3072 @設(shè)置中斷模式的棧指針,這里的sp寄存器是sp_irq

          msr cpsr_c,#0xdf @進(jìn)入系統(tǒng)模式
          ldr sp,=4096 @設(shè)置系統(tǒng)模式的棧指針,這里的sp寄存器是sp_sys
          @其實(shí)復(fù)位之后,CPU就處于系統(tǒng)模式
          @前面的"ldr sp,=4096"完成同樣的功能,此句可省略

          bl init_led @初始化LED的GPIO管腳,在init.c中
          bl init_irq @調(diào)用中斷初始化函數(shù),在init.c中
          msr cpsr_c,#0x5f @設(shè)置I-bit=0,開(kāi)IRQ中斷

          ldr lr,=halt_loop @設(shè)置返回地址
          ldr pc,=main @調(diào)用main函數(shù),main函數(shù)是個(gè)不做任何事的無(wú)限循環(huán)。當(dāng)按下按鍵時(shí),這個(gè)循環(huán)被打斷,CPU進(jìn)入
          @中斷模式,執(zhí)行“b HandleIRQ”的指令
          halt_loop:
          b halt_loop

          HandleIRQ: @HandleIRQ開(kāi)始的代碼用于處理中斷
          sub lr,lr,#4 @計(jì)算中斷處理完畢后的返回地址
          stmdb sp!,{r0-r12,lr} @保存使用到的寄存器
          @注意,此時(shí)的sp是中斷模式的sp
          @初始值是上面設(shè)置的3072

          ldr lr,=int_return @設(shè)置調(diào)用ISR即EINT_Handle函數(shù)后的返回地址
          ldr pc,=EINT_Handle @調(diào)用中斷服務(wù)函數(shù),在interrupt.c中

          int_return:
          ldmia sp!,{r0-r12,pc}^ @中斷返回,^表示將spsr的值復(fù)制到cpsr


          init.c文件內(nèi)容:








          #define EINTMASK (*(volatile unsigned long*)0x560000a4)//外部中斷屏蔽寄存器
          #define INTMSK (*(volatile unsigned long*)0x4a000008)


          #define GPBCON (*(volatile unsigned long*)0x56000010)
          #define GPBDAT (*(volatile unsigned long*)0x56000014)

          #define GPB5_out (1<<(5*2))
          #define GPB6_out (1<<(6*2))
          #define GPB7_out (1<<(7*2))
          #define GPB8_out (1<<(8*2))


          #define GPGCON (*(volatile unsigned long*)0x56000060)
          #define GPGDAT (*(volatile unsigned long*)0x56000064)

          #define GPG0_eint (2<<(0*2)) //K1,EINT8
          #define GPG3_eint (2<<(3*2)) //K2,EINT11
          #define GPG5_eint (2<<(5*2)) //K3,EINT13
          #define GPG6_eint (2<<(6*2)) //K4,EINT14



          #define WTCON (*(volatile unsigned long*)0x53000000)

          void disable_watch_dog(void)
          {
          WTCON=0;
          }

          void init_led(void)
          {
          GPBCON=GPB5_out|GPB6_out|GPB7_out|GPB8_out;
          GPBDAT|=(0x0f<<5); //所有LED熄滅,如果沒(méi)有這一句,LED燈默認(rèn)是全亮的
          }



          void init_irq()
          {
          GPGCON=GPG0_eint|GPG3_eint|GPG5_eint|GPG6_eint;

          //對(duì)于EINT8,EINT11,EINT13,EINT14,需要在EINTMASK寄存器使能它們
          EINTMASK&=(~(1<<8))&(~(1<<11))&(~(1<<13))&(~(1<<14));
          //這4個(gè)外部中斷的優(yōu)先級(jí)是相同的,EINT8_23都接仲裁器的REQ1引腳
          //所以不用像韋東山程序里那樣再設(shè)置優(yōu)先級(jí)了

          //EINT8,EINT11,EINT13,EINT14使能
          INTMSK&=(~(1<<5));
          }



          interrupt.c文件內(nèi)容:


          #define GPBDAT (*(volatile unsigned long*)0x56000014)
          #define INTOFFSET (*(volatile unsigned long*)0x4A000014)
          #define EINTPEND (*(volatile unsigned long*)0x560000a8)
          #define SRCPND (*(volatile unsigned long*)0x4a000000)
          #define INTPND (*(volatile unsigned long*)0x4a000010)

          void EINT_Handle()
          {
          unsigned long oft=INTOFFSET;
          unsigned long val;


          GPBDAT|=(0x0f<<5); //所有LED熄滅,如果沒(méi)有這一句,那么會(huì)出現(xiàn)一個(gè)結(jié)果,就是將程序下到板子里運(yùn)行時(shí),
          //4個(gè)LED燈都是滅的,因?yàn)樵趇nit.c函數(shù)里設(shè)置它為全滅。然后你按下K1,LED1亮了,
          //再按下K2,LED2亮了,但是LED1卻沒(méi)熄滅,知道你按到K4,4個(gè)LED全亮,再按就沒(méi)變化了
          //加上這一句就不一樣了,每按一個(gè)鍵,只亮相應(yīng)的燈,這也說(shuō)明中斷的執(zhí)行情況
          val=EINTPEND; //EINT寄存器,它的位x為1時(shí),表示EINT已經(jīng)發(fā)生(x為4——23)。
          if(val&(1<<8)) //K1被按下,LED1被點(diǎn)亮
          GPBDAT&=~(1<<5);

          if(val&(1<<11)) //K2被按下,LED2被點(diǎn)亮
          GPBDAT&=~(1<<6);

          if(val&(1<<13)) //K3被按下,LED3被點(diǎn)亮
          GPBDAT&=~(1<<7);

          if(val&(1<<14)) //K4被按下,LED4被點(diǎn)亮
          GPBDAT&=~(1<<8);
          //清除中斷
          if(oft==5)
          EINTPEND=(1<<8)|(1<<11)|(1<<13)|(1<<14); //清除EINTPEND寄存器,往某位寫(xiě)入1即可清楚此位
          SRCPND=1< //清除SRCPND寄存器,往某位寫(xiě)入1即可清楚此位
          INTPND=1< //清除INTPND寄存器,往某位寫(xiě)入1即可清楚此位
          //注意:清除順序很重要:先是EINTPEND,然后是SRCPND,最后是INTPND
          }



          main.c文件內(nèi)容:



          int main()
          {
          while(1);
          return 0;
          }

          Makfile文件內(nèi)容:

          objs:=head.o init.o interrupt.o main.o

          int.bin:$(objs)
          arm-linux-ld -Ttext 0x00000000 -o int_elf $^
          arm-linux-objcopy -O binary -S int_elf $@
          arm-linux-objdump -D -m arm int_elf > int.dis

          %.o:%.c
          arm-linux-gcc -Wall -O2 -c -o $@ $<

          %.o:%.S
          arm-linux-gcc -Wall -O2 -c -o $@ $<

          clean:
          rm -f int.bin int_elf int.dis *.o


          關(guān)鍵詞: mini2440中斷裸機(jī)代

          評(píng)論


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

          關(guān)閉
          看屁屁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); })();