色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

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

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

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


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

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

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

          @0x08:管理模式的向量地址,通過SWI指令進入此模式
          HandleSWI:
          b HandleSWI

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

          @0x10:數(shù)據(jù)訪問終止導(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è)好棧。棧是用 @來保存C函數(shù)的變量和返回地址
          bl disable_watch_dog @關(guān)閉WATCHDOG,否則CPU會不斷重啟

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

          msr cpsr_c,#0xdf @進入系統(tǒng)模式
          ldr sp,=4096 @設(shè)置系統(tǒng)模式的棧指針,這里的sp寄存器是sp_sys
          @其實復(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,開IRQ中斷

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

          HandleIRQ: @HandleIRQ開始的代碼用于處理中斷
          sub lr,lr,#4 @計算中斷處理完畢后的返回地址
          stmdb sp!,{r0-r12,lr} @保存使用到的寄存器
          @注意,此時的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熄滅,如果沒有這一句,LED燈默認是全亮的
          }



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

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

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

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

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

          if(val&(1<<14)) //K4被按下,LED4被點亮
          GPBDAT&=~(1<<8);
          //清除中斷
          if(oft==5)
          EINTPEND=(1<<8)|(1<<11)|(1<<13)|(1<<14); //清除EINTPEND寄存器,往某位寫入1即可清楚此位
          SRCPND=1< //清除SRCPND寄存器,往某位寫入1即可清楚此位
          INTPND=1< //清除INTPND寄存器,往某位寫入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中斷裸機代

          評論


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

          關(guān)閉