嵌入式系統(tǒng)原理與應用實驗報告_第1頁
嵌入式系統(tǒng)原理與應用實驗報告_第2頁
嵌入式系統(tǒng)原理與應用實驗報告_第3頁
嵌入式系統(tǒng)原理與應用實驗報告_第4頁
嵌入式系統(tǒng)原理與應用實驗報告_第5頁
已閱讀5頁,還剩48頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

嵌入式系統(tǒng)原理與應用實驗報告實驗報告-20-目錄軟件仿真實驗實驗一ARM匯編指令1--簡單數(shù)據(jù)搬移實驗 3實驗二ARM匯編指令2--字符串拷貝實驗 5實驗三ARM匯編指令3--ARM處理器工作模式實驗 9實驗四ARM匯編與C混合編程實驗--ARM啟動過程控制實驗 16硬件接口實驗實驗五ARM硬件接口實驗1--基本IO實驗 23實驗六ARM硬件接口實驗2--外部中斷實驗 35實驗總結 45實驗一ARM匯編指令1--簡單數(shù)據(jù)搬移實驗實驗目的熟悉實驗開發(fā)環(huán)境,掌握簡單ARM匯編指令的使用方法實驗環(huán)境硬件:PC機。軟件:ADS1.2集成開發(fā)環(huán)境實驗內(nèi)容熟悉開發(fā)環(huán)境并使用LDR/STR,MOV等指令訪問寄存器或存儲單元;使用ADD/SUB/LSL/LSR/AND/ORR等指令,完成基本數(shù)學/邏輯運算。實驗要求(1)按照2.3節(jié)介紹的方法,在ADS下創(chuàng)建一個工程asmlab1,定義兩個變量x,y和堆棧地址0x1000,將變量x的內(nèi)容存到堆棧頂,然后計算x+y,并將和存到堆棧的下一個單元。通過AXD查看寄存器和memory和寄存器中數(shù)據(jù)變化。(2)在指令后面加上適當注釋,說明指令功能。(3)指出程序執(zhí)行完成后各相關寄存器及存儲器單元的具體內(nèi)容。參考程序:AREAInit,CODE,READONLY;AREA用于聲明一個只讀或讀寫的代碼或數(shù)據(jù)段ENTRY;ENTRY聲明程序入口,CODE32用于申明以下代碼為32位ARM指令CODE32 xEQU45 ;x=45 yEQU64 ;y=64stack_topEQU0x1000;definethetopaddressforstacks棧頂為0x1000startMOVSP,#stack_top;SP=0x1000MOVR0,#x;R0=45STRR0,[SP];[1000]存放45MOVR0,#y;R0=64LDRR1,[SP];LDR加載指令,STR存儲指令.ADDR0,R0,R1;將R0與R1相加賦值給R0;STRR0,[SP,#4];STRR0,[SP,#4];先執(zhí)行SP+4,再將寄存器R0B.;無限循環(huán)跳轉到當前地址END;程序結束。單步調(diào)試過程:通過觀察,本實驗中內(nèi)存采用大端模式初始寄存器及各內(nèi)存運行情況:運行MOVR0,#x后運行STRR0,[SP]后運行MOVR0,#y后運行LDRR1,[SP]后運行ADDR0,R0,R1后運行STRR0,[SP,#4]后練習題編寫程序?qū)崿F(xiàn)對一段數(shù)據(jù)的最大值最小值搜索,最大值存于max變量之中,最小值存于min變量之中。提示:數(shù)據(jù)的定義采用偽指令:DCD來實現(xiàn),如:DataBufDCD11,-2,35,47,96,63,128,-23搜索最大值和最小值可以利用兩個寄存器R1,R2來存放。用到的比較指令為CMP,用到的條件標識符小于為LT,大于為GT?;舅悸窞椋豪肦0做基地址,將R1,R2分別存入第一個單元的內(nèi)容,利用R3做循環(huán)計數(shù)器,利用R4遍歷讀取第2至最后一個數(shù)據(jù),如果R1的數(shù)據(jù)小于新讀入的R4數(shù)據(jù)則將R4的內(nèi)容存入R1,如果R2的內(nèi)容大于R4的內(nèi)容則將R4的內(nèi)容存入R2。遍歷完成之后,R1將存放最大數(shù)據(jù),R2將存放最小數(shù)據(jù)。練習題實驗源程序:AREAInit,CODE,READONLYENTRYCODE32startLDRr0,=DataBuf;r0取數(shù)據(jù)段的首地址MOVr3,#0x08;用r3存循環(huán)次數(shù)LDRr1,[r0];用r1存最大值LDRr2,[r0];用r2存最小值LDRr4,[r0]loopSUBr3,r3,#1CMPr3,#0;結束條件BLEQCONTINUEADDr0,r0,#0x04;分支語句LDRr4,[r0]CMPr4,r1BGTbigCMPr4,r2BLTsmallBloopbigMOVr1,r4BloopsmallMOVr2,r4BloopAREAArray,DATA,READWRITEDataBufDCD11,-2,35,47,96,63,128,-23CONTINUEEND實驗截圖:相關解釋:最后成功搜索到最大值,放到了R1中,搜索到的最小值放到了R2中。實驗二ARM匯編指令2--字符串拷貝實驗實驗目的通過實驗掌握使用LDB/STB,b等指令完成較為復雜的存儲區(qū)訪問和程序分支,學習使用條件碼。實驗環(huán)境硬件:PC機。軟件:ADS1.2集成開發(fā)環(huán)境。實驗內(nèi)容熟悉開發(fā)環(huán)境的使用并完成一塊存儲區(qū)的拷貝。完成分支程序設計,要求判斷參數(shù),根據(jù)不同參數(shù),調(diào)用不同的子程序。實驗要求(1)按照2.3節(jié)介紹的方法,在ADS下創(chuàng)建一個工程asmlab2,定義兩個數(shù)據(jù)存儲區(qū)Src和Dst,Src用于存放原字符串,Dst用于存放目的字符串。堆棧地址0x400,將變量原字符串的內(nèi)容拷貝到目的字符串中,要能判斷原字符串的結束符(0),并統(tǒng)計字符串中字符的個數(shù)。通過AXD查看寄存器和memory和寄存器中數(shù)據(jù)變化。(2)在指令后面加上適當注釋,說明指令功能。(3)指出程序執(zhí)行完成后各相關寄存器及存儲器單元的具體內(nèi)容。參考程序:AREAInit,CODE,READONLY;AREA用于聲明一個只讀或讀寫的代碼或數(shù)據(jù)段,這里是只讀代碼段ENTRY ;ENTRY聲明程序入口CODE32 ;CODE32用于申明以下代碼為32位ARM指令START ;標號“start”MOVSP,#0x400 ;SP=0x400LDRR0,=Src ;LDR偽指令將源字符串的地址值讀取到R0寄存器中LDRR1,=Dst ;LDR偽指令將目的字符串的地址值讀取到R1寄存器中MOVR3,#0 ;R3=0進行初始化,用來統(tǒng)計字符串中字符的個數(shù)strcopy ;標號“strcopy”LDRBR2,[R0],#1 ;將源地址起始位置的一個字節(jié)數(shù)據(jù)裝入R2中,且R0=R0+1CMPR2,#0 ;比較R2和結束符0的大小BEQendcopy ;若R2==0表示跳轉到endcopy處STRBR2,[R1],#1 ;若R2!=0,把寄存器R2中的字數(shù)據(jù)(32位)保存到目的地址的內(nèi)存地址中,且R1=R1+1ADDR3,R3,#1 ;R3=R3+1用來統(tǒng)計字符串中字符的個數(shù)Bstrcopy ;跳轉回標號“strcopy”處endcopy ;標號“endstrcopy”LDRR0,=ByteNum ;LDR偽指令將ByteNum的地址值讀取到R0寄存器中STRR3,[R0] ;將統(tǒng)計得到的字符個數(shù)存儲到ByteNum內(nèi)存單元中B. ;無限循環(huán)跳轉到當前地址AREADatapool,DATA,READWRITE;AREA用于聲明一個只讀或讀寫的代碼或數(shù)據(jù)段,這里是讀寫數(shù)據(jù)段SrcDCB"string",0 ;源字符串數(shù)據(jù)存儲地址DstDCB0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;目的字符串存儲地址ByteNumDCD0 ;字符個數(shù)統(tǒng)計單元存儲地址END ;程序結束參考程序?qū)嶒灲貓D運行前內(nèi)存情況:運行至復制前,得知源地址在0x8040,目標地址在0x8047單步調(diào)試運行中

ByteNum的地址:最終結果:練習題編寫程序循環(huán)對R4~R11進行累加8次賦值,R4~R11起始值為1~8,每次加操作后把R4~R11的內(nèi)容放入SP棧中,SP初始設置為0x800。最后把R4~R11清空賦值為0。提示:多字的加載與存儲使用多寄存器尋址,使用的指令為LDM和STM。如:LDMIAR0!,{R4-R11}STMIAR1!,{R4-R11}練習題程序:AREAInit,CODE,READONLYENTRYCODE32Start;設置起始值MOVSP,#0X800LDRR0,=srcMOVR1,#8MOVR4,#1MOVR5,#2MOVR6,#3MOVR7,#4MOVR8,#5MOVR9,#6MOVR10,#7MOVR11,#8loopADDR4,R4,#1ADDR5,R5,#1ADDR6,R6,#1ADDR7,R7,#1ADDR8,R8,#1ADDR9,R9,#1ADDR10,R10,#1ADDR11,R11,#1STMFDSP!,{R4-R11}SUBSR1,R1,#1;循環(huán)判別條件BNEloopLDMIAR0!,{R4-R11}HALTBHALTsrcDCD0,0,0,0,0,0,0,0END練習題實驗截圖:實驗三ARM匯編指令3--ARM處理器工作模式實驗實驗目的(1)通過實驗掌握學會使用msr/mrs指令實現(xiàn)ARM處理器工作模式的切換,觀察不同模式下的寄存器,加深對CPU結構的理解;(2)通過實驗掌握ld中如何使用命令行指定代碼段起始地址。實驗設備硬件:PC機。軟件:ADS1.2集成開發(fā)環(huán)境實驗內(nèi)容通過ARM匯編指令,在各種處理器模式下切換并觀察各種模式下寄存器的區(qū)別;掌握ARM不同模式的進入與退出。實驗要求(1)按照2.3節(jié)介紹的方法,在ADS下創(chuàng)建一個工程asmmodelab,完成各個模式下的堆棧初始化工作,并將R1-R12的內(nèi)容存入當前模式下堆棧。通過AXD運用單步執(zhí)行方式調(diào)試程序,驗證工作模式的切換,注意觀察CPSR寄存器中的變化。隨著程序調(diào)試過程中在模式間的切換,使用寄存器觀察器切換到不同的工作模式下觀察SP(R13)的變化情況。(2)實驗過程中請記錄并思考以下內(nèi)容:1)程序復位之后系統(tǒng)處于什么模式?2)記錄每種模式下的初始堆棧指針,以及執(zhí)行R1-R12內(nèi)容壓棧后本模式堆棧相關內(nèi)存單元的數(shù)值。并分析快速中斷FIQ模式與其他模式存入的R1-R12有什么不同。3)切換成用戶模式之后還能否從用戶模式切換到其他模式(如系統(tǒng)模式)?4)用戶模式下能否執(zhí)行堆棧壓棧操作?如果能得話,觀察用戶模式下壓棧之前和壓棧之后其堆棧區(qū)域的變化情況。5)觀察本程序模式切換過程中SPSR有無變化,并解釋其原因。參考程序:;定義堆棧大小usr_stack_legthequ64 ;用戶模式svc_stack_legthequ32 ;管理模式fiq_stack_legthequ16 ;快速中斷模式irq_stack_legthequ64 ;中斷模式abt_stack_legthequ16 ;中止模式und_stack_legthequ16 ;未定義模式 areareset,code,readonly ;

聲明只讀代碼段reset entry ;ENTRY聲明程序入口 code32 ;CODE32用于申明以下代碼為32位ARM指令startmovr0,#0 movr1,#1 movr2,#2 movr3,#3 movr4,#4 movr5,#5 movr6,#6 movr7,#7 movr8,#8 movr9,#9 movr10,#10 movr11,#11 movr12,#12 blinitstack ;初始化各模式下的堆棧指針BL(BranchwithLink跳轉將PC拷入LR,用于子程序返回) ;打開irq中斷(將cpsr寄存器的i位清0) mrsr0,cpsr ;r0<--cpsr bicr0,r0,#0x80 ;開IRQ中斷 msrcpsr_cxsf,r0 ;cpsr<--r0;切換到用戶模式(CPSR[4:0]=10000,同時CPSR[7:6]=11,CPSR[5]=0保留,即CPSR[7:0]=11010000=0xd0) msrcpsr_c,#0xd0;保存一下當前CPSR,將CPSR傳入R0 mrsr0,cpsr;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;觀察由用戶模式能否切換到其他模式 ;切換到管理模式 msrcpsr_c,#0xdf;保存一下當前CPSR,將CPSR傳入R0 mrsr0,cpsr;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12}haltbhalt ;留在此處Initstack ;初始化各模式下的堆棧子程序;子程序內(nèi)容r0<--lr,因為各種模式下r0是相同的而各個模式movr0,lr ;R0<-LR,各模式下的R0是相同的 ;設置管理模式堆棧,先切換到管理模式下再設置該模式下的SP

msrcpsr_c,#0xd3 ;11010011cpsr[4:0] ldrsp,stacksvc ;將StackSvc代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;設置中斷模式堆棧,先切換到中斷模式下再設置該模式下的SP,;中斷模式CPSR[7:0]=110,10010 msrcpsr_c,#0xd2 ;11010010 ldrsp,stackirq ;將stackirq代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;設置快速中斷模式堆棧 msrcpsr_c,#0xd1 ;11010001 ldrsp,stackfiq ;將stackfiq代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;設置中止模式堆棧,先切換到中斷模式下再設置SP msrcpsr_c,#0xd7 ;11010111 ldrsp,stackabt ;將stackabt代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;設置未定義模式堆棧 msrcpsr_c,#0xdb ;11011011 ldrsp,stackund ;將stackund代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} ;設置系統(tǒng)模式堆棧 msrcpsr_c,#0xdf ;11011111 ldrsp,stackusr ;將stackusr代表的地址裝入SP;STM指令把寄存器列表中索引最小的寄存器存在最低地址,所以R1在最低地址,向上依次是R1,R2,...R12,LR。完成后SP指向保存R1的地址。 stmfdsp!,{r1-r12} movpc,r0 ;返回;定義堆棧首地址,即最高地址處stackusrdcdusrstackspace+(usr_stack_legth-1)*4stacksvcdcdsvcstackspace+(svc_stack_legth-1)*4stackirqdcdirqstackspace+(irq_stack_legth-1)*4stackfiqdcdfiqstackspace+(fiq_stack_legth-1)*4stackabtdcdabtstackspace+(abt_stack_legth-1)*4stackunddcdundstackspace+(und_stack_legth-1)*4 areareset,data,noinit,align=2 ;分配棧堆空間usrstackspacespaceusr_stack_legth*4 ;分配USR_STACK_LENGTH*4個字節(jié)svcstackspacespacesvc_stack_legth*4 ;同上irqstackspacespaceirq_stack_legth*4fiqstackspacespacefiq_stack_legth*4abtstackspacespaceabt_stack_legth*4undstackspacespaceund_stack_legth*4 end ;END程序結束實驗截圖:運行前,用戶模式各寄存器狀態(tài)如圖,其他模式R13寄存器值均為0:1、usr_stack_legthequ64 ;用戶模式之后用戶模式各寄存器賦初值:2、svc_stack_legthequ32 ;管理模式3、fiq_stack_legthequ16 ;快速中斷模式4、irq_stack_legthequ64 ;中斷模式5、abt_stack_legthequ16 ;中止模式6、und_stack_legthequ16 ;未定義模式實驗練習題答案1)程序復位之后系統(tǒng)處于什么模式?程序復位后CPSR的值是SVC,故系統(tǒng)處于管理模式。2)記錄每種模式下的初始堆棧指針,以及執(zhí)行R1-R12內(nèi)容壓棧后本模式堆棧相關內(nèi)存單元的數(shù)值。并分析快速中斷FIQ模式與其他模式存入的R1-R12有什么不同。這是管理模式中斷模式,初始化堆棧指針式0x8340 快速中斷模式,初始化堆棧指針式0x8380 只到r7就停了,快速中斷模式有自己的分組寄存器R8_fiqR14_fiq中止模式,初始化堆棧指針式0x8c0 未定義模式,初始化堆棧指針式8400系統(tǒng)模式,初始化堆棧指針式81c03)切換成用戶模式之后還能否從用戶模式切換到其他模式(如系統(tǒng)模式)?切換成用戶模式之后還能從用戶模式進入其他模式,例如中斷模式。4)用戶模式下能否執(zhí)行堆棧壓棧操作?如果能得話,觀察用戶模式下壓棧之前和壓棧之后其堆棧區(qū)域的變化情況。用戶模式下能執(zhí)行壓棧操作。堆棧的變化情況如圖所示(紅色部分之前是00)。5)觀察本程序模式切換過程中SPSR有無變化,并解釋其原因。SPSR無變化,因為程序運行沒有發(fā)生異常,無異常狀態(tài)。實驗四ARM匯編與C混合編程實驗--ARM啟動過程控制實驗實驗目的(1)掌握建立基本完整的ARM工程,包含啟動代碼,C語言程序等;(2)了解ARM啟動過程,學會編寫簡單的C語言程序和匯編啟動代碼并進行調(diào)試;(3)掌握如何指定代碼入口地址與入口點;(4)掌握通過memory/register/watch/variable窗口分析判斷結果。實驗設備硬件:PC機。軟件:ADS1.2集成開發(fā)環(huán)境實驗內(nèi)容使用匯編語言編寫初始化程序,并引導至C語言main函數(shù),用匯編語言編寫延時函數(shù)實現(xiàn)毫秒級的延時,在C語言中調(diào)用延時函數(shù),實現(xiàn)1s鐘定時。實驗要求(1)按照2.3節(jié)介紹的方法,在ADS下創(chuàng)建一個工程armasmc,編寫3個文件,如下圖3-1所示:圖3-1實驗工程文件管理其中一個初始化匯編語言文件Init.s,該文件中主要完成異常矢量表的建立,模式堆棧初始化,并將程序引導至C語言的main函數(shù)。C語言程序保存為armasmc.c。C語言中調(diào)用匯編語言文件delay.s中的毫秒延時程序delayxms,C語言將延時的毫秒數(shù)通過參數(shù)傳遞到匯編語言,匯編語言完成延時,然后返回C語言函數(shù)。通過AXD運用單步執(zhí)行方式調(diào)試程序。觀察程序執(zhí)行過程中的寄存器及存儲器的變化情況。(2)實驗過程中請記錄并思考以下內(nèi)容:1)如何建立異常矢量入口表?

2)如何在匯編語言中切換至C語言的main函數(shù)?。

3)如何在C語言中調(diào)用匯編語言函數(shù),并完成參數(shù)傳遞?

4)匯編語言函數(shù)中用到的寄存器如何保護與恢復,為什么要保護參考程序中的

R11?

5)將delay.s中的R11改成R4,并將兩條R11的保護與恢復語句stmfdsp!,{r12}

和ldmfdsp!,{r11}刪掉,在C語言程序中的語句i--處設置端點,觀察運行

過程中變量i的變化情況,并解釋其中的原因。參考程序:;***************************************************************;NAME:entry.s;Author:lihua;History:2014-4-10;***************************************************************IMPORTmain ;用IMPORT偽操作來聲明即將調(diào)用的C程序。areaInit,code,readonly ;AREA用于聲明一個只讀或讀寫的代碼或數(shù)據(jù)段,這里是只讀代碼段entry ;ENTRY聲明程序入口code32 ;CODE32用于申明以下代碼為32位ARM指令;***********Setupinterrupt/exceptionvectors*************************;建立異常矢量入口表start bReset_Handler ;Reset入口,即為整個程序的實際入口點Undefined_Handler bUndefined_HandlerSWI_Handler bSWI_HandlerPrefetch_handler bPrefetch_handlerAbort_Handler bAbort_Handlernop;ReservedvectoIRQ_Handler bIRQ_HandlerFIQ_Handler bFIQ_HandlerReset_Handlerblinitstack ;通過BL指令來調(diào)用initstack子程序,將PC拷入LR,用于子程序返回,初始化各模式下的堆棧指針;切換至用戶模式堆msrcpsr_c,#0xd0;11010000blmain ;通過BL指令來調(diào)用main.chalt bhalt ;無限循環(huán)跳轉到當前地址initstack movr0,lr;r0<--lr,因為各種模式下r0是相同的而各個模式?;設置管理模式堆棧,先切換到管理模式下再設置該模式下的SP

msrcpsr_c,#0xd3;11010011ldrsp,stacksvc ;將StackSvc代表的地址裝入SP;設置中斷模式堆棧msrcpsr_c,#0xd2;11010010ldrsp,stackirq ;將stackirq代表的地址裝入SP

;設置快速中斷模式堆棧msrcpsr_c,#0xd1;11010001ldrsp,stackfiq ;將stackfiq代表的地址裝入SP;設置中止模式堆棧 msrcpsr_c,#0xd7;11010111ldrsp,stackabt ;將stackabt代表的地址裝入SP;設置未定義模式堆棧msrcpsr_c,#0xdb;11011011ldrsp,stackund ;將stackund代表的地址裝入SP;設置系統(tǒng)模式堆棧msrcpsr_c,#0xdf;11011111ldrsp,stackusr ;將stackusr代表的地址裝入SPmovpc,r0;返回LTORG ;LTORG用于聲明一個文字池,在使用LDR偽指令的時候,要在適當?shù)牡刂芳尤隠TORG聲明文字池,這樣就會把要加載的數(shù)據(jù)保存在文字池內(nèi),再用ARM的加載指令讀出數(shù)據(jù);定義堆棧首地址,即最高地址處stackusr dcdusrstackspace+128Stacksvc dcdsvcstackspace+128stackirq dcdirqstackspace+128stackfiq dcdfiqstackspace+128stackabt dcdabtstackspace+128stackund dcdundstackspace+128areaInterrupt,data,READWRITE ;分配棧堆空間usrstackspacespace128 ;分配128個字節(jié)svcstackspacespace128 ;同上irqstackspacespace128fiqstackspacespace128abtstackspacespace128undstackspacespace128end/********************************************************************File:armasmc.c*Author:lihua2014.4.10*History:********************************************************************/#include<stdio.h>intmain(){externvoiddelayxms(intxms);//使用extern關鍵詞來聲明即將調(diào)用的匯編程序inti=100;while(1){delayxms(1000);//延時1si--;if(i==0)i=100;}return0;};***************************************************************;NAME:delay.s;Author:lihua;History:2014-4-10;***************************************************************EXPORTdelayxms ;使用EXPORT偽操作來聲明,使得本程序可以被其它程序調(diào)用areadelay,code,readonly ;AREA用于聲明一個只讀或讀寫的代碼或數(shù)據(jù)段,這里是只讀代碼段code32 ;CODE32用于申明以下代碼為32位ARM指令;下面是延時若干ms的子程序delayxms ;調(diào)用時參數(shù)傳遞給R0寄存器stmfdsp!,{r11}; ;STM指令把寄存器列表中索引最小的寄存器存在最低地址,R1、LR依次入棧,完成后SP指向保存R1的地址。subr0,r0,#1 ;r0=r0-1ldrr11,=1000 ;r11=1000loop2subr11,r11,#1 ;r11=r11-1cmpr11,#0x0 ;比較R11和0,設置標志位bneloop2 ;R11不等于0,調(diào)轉到Loop2標號cmpr0,#0x0 ;r11==0,繼續(xù)將r0與0比較bnedelayxms ;比較的結果不為0,則繼續(xù)調(diào)用delayxmsldmfdsp!,{r11}; ;r0==0,lr、r1依次出棧movpc,lr ;返回程序調(diào)用入口處end截圖程序運行初始狀態(tài):初始化各模式堆棧:初始化完畢,調(diào)用main函數(shù):局部變量i的值傳遞給R4寄存器:恢復r11的值:由main.c調(diào)用delay.asm:返回main.c:實驗練習題如何建立異常矢量入口表?我們在編寫代碼的時候,一般地,我們使用下面的代碼,這樣建立異常矢量表:startbReset_HandlerUndefined_HandlerbUndefined_HandlerSWI_HandlerbSWI_HandlerPrefetch_handlerbPrefetch_handlerAbort_HandlerbAbort_Handlernop;ReservedvectoIRQ_HandlerbIRQ_HandlerFIQ_HandlerbFIQ_Handler2)如何在匯編語言中切換至C語言的main函數(shù)?在asm文件中用IMPORT偽操作來聲明即將調(diào)用的C程序,通過BL指令來調(diào)用main.c。如何在C語言中調(diào)用匯編語言函數(shù),并完成參數(shù)傳遞?在C文件中使用extern關鍵詞來聲明即將調(diào)用的匯編程序,在ASM文件中使用EXPORT偽操作來聲明,使得本程序可以被其它程序調(diào)用。4)匯編語言函數(shù)中用到的寄存器如何保護與恢復,為什么要保護參考程序中的R11?通過命令stmfdsp!,{r11}保護 ;STM指令把寄存器列表中索引最小的寄存器存在最低地址,R1、LR依次入棧,完成后SP指向保存R1的地址。通過命令ldmfdsp!,{r11}恢復 ;r0==0,lr、r1依次出棧因為R11=1000在程序調(diào)用過程中被用到,這樣做是為了保存程序被調(diào)用前的數(shù)值。5)將delay.s中的R11改成R4,并將兩條R11的保護與恢復語句stmfdsp!,{r12}和ldmfdsp!,{r11}刪掉,在C語言程序中的語句i--處設置端點,觀察運行過程中變量i的變化情況,并解釋其中的原因。因為在程序調(diào)用過程中局部變量i的值傳給了R4,經(jīng)過這一步,更改的效果是,運行到i--時候,i從100變到0。硬件接口實驗實驗五ARM硬件接口實驗1--基本IO實驗實驗目的(1)GPIO的功能配置方法;(2)通過寄存器訪問引腳的方法;(3)實現(xiàn)GPIO輸入輸出功能的基本編程方法。實驗設備硬件:北京博創(chuàng)UP-TECH三合一實驗箱,J-Link仿真器套件,PC機軟件:ADS1.2集成開發(fā)環(huán)境實驗內(nèi)容編寫S3C2440X處理器的端口控制程序,實現(xiàn)利用按鍵控制的跑馬燈程序。GPC5,GPC6,GPC7三個引腳連接發(fā)光二極管,按鈕開關連接在GPF5引腳,如下圖4-13所示:圖4-13上電之后,GPC5、GPC6、GPC7按照如下圖所示的方向,輪流顯示,當按鈕開關按下去,方向反向,如下圖所示:實驗過程中要注意按鍵去抖動和每個發(fā)光二極管顯示一定的時間(至少100ms)。實驗原理1、S3C2440的GPIO功能簡介S3C2440有130個多功能輸入輸出接口(GPIO),它們被分成9組,分別是:—PortA(GPA):25-outputport—PortB(GPB):11-input/outport—PortC(GPC):16-input/outputport—PortD(GPD):16-input/outputport—PortE(GPE):16-input/outputport—PortF(GPF):8-input/outputport—PortG(GPG):16-input/outputport—PortH(GPH):9-input/outputport—PortJ(GPJ):13-input/outputport每個端口的功能可由軟件進行配置。GPIO特殊功能寄存器對GPIO進行配置和控制的特殊功能寄存器,主要有3類,分別是:端口控制寄存器GPxCON寄存器,端口數(shù)據(jù)寄存器GPxDAT寄存器和端口上拉寄存器GPxUP。2、(1)GPxCON寄存器GPxCON寄存器是為了配置引腳功能的,每一個引腳都可以配置成為輸入、輸出、外部中斷組、特殊功能引腳中的至少三種情況。(2)GPxDAT寄存器GPxDAT是用來讀/寫引腳狀態(tài)的:當引腳設置為輸出時,向該寄存器的對應位寫“1”可輸出高電平,寫“0”可輸出低電平;當引腳設置為輸入時,讀此寄存器便可得知相應引腳的電平狀態(tài);引腳被設置成為特殊功能時,讀寫此寄存器無效。(3)GPxUP寄存器GPxPUD寄存器是用來設置引腳的內(nèi)部上/下拉電阻的,寄存器每兩位控制一個引腳的上下拉電阻。當引腳對應的兩位為“00”時,禁止上/下拉,為“01”時,下拉使能,為“10”時上拉使能。上拉電阻和下拉電阻的作用是:當GPIO引腳處于第三態(tài)(高阻態(tài),相當于沒接芯片)時,它的電平狀態(tài)由上拉電阻或下拉電阻確定。本實驗中將用到的GPC和GPF兩組端口,因此我們將這兩個組的端口進行詳細介紹。3、端口配置(1)GPC5,GPC6和GPC7三個管腳定義為輸出口,輸出低電平時相應的LED燈點亮。#definerGPCCON(*(volatileunsigned*)(0x56000020))#definerGPCDAT(*(volatileunsigned*)(0x56000024))#definerGPCUP(*(volatileunsigned*)(0x56000028))#defineGPC5_ONrGPCDAT&~(1<<5)#defineGPC5_OFFrGPCDAT|(1<<5)#defineGPC6_ONrGPCDAT&~(1<<6)#defineGPC6_OFFrGPCDAT|(1<<6)#defineGPC7_ONrGPCDAT&~(1<<7)#defineGPC7_OFFrGPCDAT|(1<<7)rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口設置為輸出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引腳上拉(2)GPF5定義為輸入,用于實現(xiàn)按鍵識別#definerGPFCON(*(volatileunsigned*)(0x56000050))#definerGPFDAT(*(volatileunsigned*)(0x56000054))#definerGPFUP(*(volatileunsigned*)(0x56000058))rGPFCON=rGPFCON&~(0x3<<10);//將GPF的5端口設置為輸入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引腳上拉charKey_Scan()//按鍵掃描程序{if(!(rGPFDAT&(1<<5)))//如果GPF5被按下,讀取到低電平{delay(20);//延時去抖動,由于ARM11為流水線結構,這里只//是一個大概的延時值if(!(rGPFDAT&(1<<5)))//再次判斷return1;//返回“1”elsereturn0;}elsereturn0;}voiddelay(inttime)//延時函數(shù),用于掃描按鍵時去軟件抖動{U8i,j,k;for(i=0;i<time;i++)for(j=0;j<255;j++)}參考程序:(1)初始化程序;********************************************************************;Description:Thisisainitprogramdesignedbycompilelanguage;NAME:entry.s;History:2014-5-4;********************************************************************IMPORTmainareaInit,code,readonlyentrycode32;*****Setupinterrupt/exceptionvectors***********************startbReset_HandlerUndefined_HandlerbUndefined_HandlerSWI_HandlerbSWI_HandlerPrefetch_handlerbPrefetch_handlerAbort_HandlerbAbort_Handlernop;ReservedvectoIRQ_HandlerbIRQ_HandlerFIQ_HandlerbFIQ_HandlerReset_Handlerblinitstack;初始化各模式下的堆棧指針;切換至用戶模式堆msrcpsr_c,#0xd0;11010000blmainhaltbhaltinitstackmovr0,lr;r0<--lr,因為各種模式下r0是相同的而各個模式?;設置管理模式堆棧msrcpsr_c,#0xd3;11010011ldrsp,stacksvc;設置中斷模式堆棧msrcpsr_c,#0xd2;11010010ldrsp,stackirq;設置快速中斷模式堆棧msrcpsr_c,#0xd1;11010001ldrsp,stackfiq;設置中止模式堆棧msrcpsr_c,#0xd7;11010111ldrsp,stackabt;設置未定義模式堆棧msrcpsr_c,#0xdb;11011011ldrsp,stackund;設置系統(tǒng)模式堆棧msrcpsr_c,#0xdf;11011111ldrsp,stackusrmovpc,r0;返回LTORGstackusrdcdusrstackspace+128stacksvcdcdsvcstackspace+128stackirqdcdirqstackspace+128stackfiqdcdfiqstackspace+128stackabtdcdabtstackspace+128stackunddcdundstackspace+128areaInterrupt,data,READWRITEusrstackspacespace128svcstackspacespace128irqstackspacespace128fiqstackspacespace128abtstackspacespace128undstackspacespace128end(2)C語言控制程序為:/******************************************************************Description:ThisisaGPIOcontrolprogram*File:GPIO.c*Author:lihua2014.5.4*History:*******************************************************************/#definerGPCCON(*(volatileunsigned*)(0x56000020))#definerGPCDAT(*(volatileunsigned*)(0x56000024))#definerGPCUP(*(volatileunsigned*)(0x56000028))#definerGPFCON(*(volatileunsigned*)(0x56000050))#definerGPFDAT(*(volatileunsigned*)(0x56000054))#definerGPFUP(*(volatileunsigned*)(0x56000058))#defineGPC5_ON~(1<<5)#defineGPC5_OFF(1<<5)#defineGPC6_ON~(1<<6)#defineGPC6_OFF(1<<6)#defineGPC7_ON~(1<<7)#defineGPC7_OFF(1<<7)voiddelay(inttime)//延時函數(shù),用于掃描按鍵時去軟件抖動{inti,j;for(i=0;i<time;i++)for(j=0;j<255;j++);}voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口設置為輸出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引腳上拉rGPFCON=rGPFCON&~(0x3<<10);//將GPF的5端口設置為輸入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引腳上拉delay(10);rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口滅掉}charKey_Scan()//按鍵掃描程序{charkey=rGPFDAT&(1<<5);if(!key)//如果GPF5被按下,讀取到低電平{delay(100);//延時去抖動,這里只是一個大概的延時值if(!key)//再次判斷return1;//返回"1"elsereturn0;}elsereturn0;}intmain(){intcount=0;chardirection=0;//charolddir=0;port_init();while(1){if(Key_Scan())direction=1;elsedirection=0;switch(count){case0:rGPCDAT=rGPCDAT&GPC5_ON;rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;delay(1000);break;case1:rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;delay(1000);break;case2:rGPCDAT=rGPCDAT&GPC7_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC6_OFF;delay(1000);break;default:break;}if(!direction){if(count==2)count=-1;count++;}else{if(count==0)count=3;count--;};}}實驗要求(1)按照前面介紹的方法,在ADS下創(chuàng)建一個工程GPIO,并將前面示例程序加入工程。(注意將實驗箱中的JP1402設置為2-3短接,即選擇ARMICE模式)。運行AXD加載生成的image文件,點擊按鈕,運用程序。觀察程序執(zhí)行的效果。并觀察按鍵按下和松開跑馬燈輪換的方向。(2)實驗過程中請記錄并思考以下內(nèi)容:1)如何訪問寄存器并修改其中的1位或多位數(shù)據(jù)?2)如何配置S3C2440的PIO端口?3)在C語言中如何實現(xiàn)按鍵處理程序?4)如何初始化DRAM,從而實現(xiàn)程序下載并在線調(diào)試?5)嘗試實現(xiàn)利用按鍵切換控制跑馬燈的順序輪換(不是控制其輪換方向,而是在有按鍵按下并松開后實現(xiàn)一次跑馬燈切換)。實驗截圖:實驗練習題如何訪問寄存器并修改其中的1位或多位數(shù)據(jù)?rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;如代碼所示用與,非,或操作寄存器的1位或多位數(shù)據(jù)。如何配置S3C2440的PIO端口?配置IO如下所示voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口設置為輸出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引腳上拉rGPFCON=rGPFCON&~(0x3<<10);//將GPF的5端口設置為輸入rGPFUP=rGPCUP&~(1<<5);//GPF的5端口引腳上拉//delay(10);rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口滅掉}在C語言中如何實現(xiàn)按鍵處理程序?C語言按鍵程序如下所示voidKey_Scan()//按鍵掃描程序{charkey=rGPFDAT&(1<<5);if(!key)//如果GPF5被按下,讀取到低電平{delay(100);//延時去抖動,這里只是一個大概的延時值if(!key)//再次判斷flag=1;//返回"1"elseflag=0;}elseflag=0;}4)如何初始化DRAM,從而實現(xiàn)程序下載并在線調(diào)試?配置SDRAM的代碼如下所示setmem0x53000000,0x00000000,32setmem0x4a000008,0xffffffff,32setmem0x4a00001c,0x00007fff,32setmem0x48000000,0x2212d110,32setmem0x48000004,0x00000f40,32setmem0x48000008,0x00002e50,32setmem0x4800000c,0x00002e50,32setmem0x48000010,0x00002e50,32setmem0x48000014,0x00002e50,32setmem0x48000018,0x00002e50,32setmem0x4800001c,0x00018005,32setmem0x48000020,0x00018005,32setmem0x48000024,0x00960542,32setmem0x48000028,0x00000032,32setmem0x4800002c,0x00000030,32setmem0x48000030,0x00000030,325)嘗試實現(xiàn)利用按鍵切換控制跑馬燈的順序輪換(不是控制其輪換方向,而是在有按鍵按下并松開后實現(xiàn)一次跑馬燈切換)。代碼如下:intmain(){intcount=0;charkey=rGPFDAT&(1<<5);//charolddir=0;port_init();while(1){key=rGPFDAT&(1<<5);//只有當按過以后flag才=1if(!key) flag=1; if(flag==1)//如果按過了下去 { switch(count){case0:rGPCDAT=rGPCDAT&GPC5_ON;rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;delay(400);break;case1:rGPCDAT=rGPCDAT&GPC6_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;delay(400);break;case2:rGPCDAT=rGPCDAT&GPC7_ON;rGPCDAT=rGPCDAT|GPC5_OFF|GPC6_OFF;delay(400);break;default:break;}}if(count==2){count=-1; flag=0;//標志位清零燈就不亮了 } count++;}}實驗六ARM硬件接口實驗2外部中斷實驗實驗目的(1)通過實驗掌握ARM處理器的中斷方式和中斷處理。(2)熟悉S3C2440X的中斷控制寄存器的使用;(3)理解S3C2440X的中斷處理機制(4)熟練掌握如何進行ARM處理器中斷處理的軟件編程方法。(5)掌握生成離線運行(Release模式)程序的開發(fā)環(huán)境設置方法。(6)掌握通過J-link向Norflash燒些程序的方法。實驗設備硬件:北京博創(chuàng)UP-TECH三合一實驗箱,J-Link仿真器套件,PC機軟件:ADS1.2集成開發(fā)環(huán)境實驗內(nèi)容硬件電路和前面的實驗五完全相同。這里將按鈕開關所連接的GPF5引腳設定為外部中斷EINT5,中斷模式位IRQ,在中斷服務程序中完成LED燈的切換,即正常狀態(tài)時LED5燈亮,按下按鈕開關時LED6燈亮。參考程序:(1)初始化匯編程序;**************************************************************;File:head.S;功能:初始化,設置中斷模式、系統(tǒng)模式的棧,設置好中斷處理函數(shù);****************************************************************IMPORTMain;聲明外部函數(shù)IMPORTport_initIMPORTeint_initIMPORTEINT_HandleIMPORTdisable_watch_dogAREAhead,CODE,READONLYENTRYCODE32start;程序入口點;****************************************************************;中斷向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用;****************************************************************;0x00:復位中斷向量地址bReset;0x04:未定義指令中止模式的向量地址HandleUndefbHandleUndef;0x08:管理模式的向量地址,通過SWI指令進入此模式HandleSWIbHandleSWI;0x0c:指令預取終止導致的異常的向量地址HandlePrefetchAbortbHandlePrefetchAbort;0x10:數(shù)據(jù)訪問終止導致的異常的向量地址HandleDataAbortbHandleDataAbort;0x14:保留HandleNotUsedbHandleNotUsed;0x18:中斷模式的向量地址bHandleIRQ;0x1c:快中斷模式的向量地址HandleFIQbHandleFIQResetldrsp,=4096;設置棧指針,以下都是C函數(shù),調(diào)用前需要設好棧bldisable_watch_dog;關閉WATCHDOG,否則CPU會不斷重啟;切換至用戶模式;msrcpsr_c,#0xd0;11010000msrcpsr_c,#0xd2;進入中斷模式ldrsp,=3072;設置中斷模式棧指針msrcpsr_c,#0xd3;進入管理模式ldrsp,=4096;設置管理模式棧指針,;其實復位之后,CPU就處于管理模式,;前面的“l(fā)drsp,=4096”完成同樣的功能,此句可省略blport_init;初始化LED的GPIO管腳,在main.c中bleint_init;調(diào)用中斷初始化函數(shù),在main.c中msrcpsr_c,#0x5f;設置I-bit=0,開IRQ中斷l(xiāng)drlr,=halt_loop;設置返回地址ldrpc,=Main;調(diào)用main函數(shù)halt_loopbhalt_loopHandleIRQsublr,lr,#4;計算返回地址stmdbsp!,{r0-r12,lr};保存使用到的寄存器;注意,此時的sp是中斷模式的sp;初始值是上面設置的3072ldrlr,=int_return;設置調(diào)用ISR即EINT_Handle函數(shù)后的返回地址ldrpc,=EINT_Handle;調(diào)用中斷服務函數(shù),在interrupt.c中int_returnldmiasp!,{r0-r12,pc}^;中斷返回,^表示將spsr的值復制到cpsrEND(2)C語言處理程序/***************************************************************File:main.c*功能:主函數(shù),端口初始化,中斷初始化、中斷處理等函數(shù)****************************************************************/#include"s2440addr.h"#defineGPC5_ON~(1<<5)#defineGPC5_OFF(1<<5)#defineGPC6_ON~(1<<6)#defineGPC6_OFF(1<<6)#defineGPC7_ON~(1<<7)#defineGPC7_OFF(1<<7)/**********KEY對應GPF5************/#defineGPF5_eint(0x2<<(5*2))#defineGPF5_mask(3<<(5*2))/*************端口初始化***************/voidport_init(){rGPCCON=rGPCCON&~(0x3f<<10)|(0x15<<10);//GPC5~7端口設置為輸出rGPCUP=rGPCUP|(7<<5);//禁止GPC的5~7端口引腳上拉rGPCDAT=rGPCDAT|(GPC5_OFF|GPC6_OFF|GPC7_OFF);//GPC5-7端口滅掉}/********關閉WATCHDOG,否則CPU會不斷重啟******************/voiddisable_watch_dog(){rWTCON=0;//關閉WATCHDOG很簡單,往這個寄存器寫0即可}/********************中斷初始化***************************/voideint_init(){//key0對應的引腳設為中斷引腳EINT5rGPFCON&=~GPF5_mask;rGPFCON|=GPF5_eint;//對于EINT5,需要在EINTMASK寄存器中使能它rEINTMASK&=~(1<<5);rINTMSK&=~(1<<4);//EnableEINT4_7interrupt}/********************中斷處理***************************/voidEINT_Handle()//中斷處理函數(shù){//清中斷rEINTPEND|=(1<<5);//EINT4_7合用IRQ4rSRCPND|=1<<4;rINTPND|=1<<4;//點亮LED6rGPCDAT=rGPCDAT|GPC5_OFF|GPC7_OFF;rGPCDAT=rGPCDAT&GPC6_ON;}/********************main函數(shù)***************************/intMain(){while(1){rGPCDAT=rGPCDAT|GPC6_OFF|GPC7_OFF;rGPCDAT=rGPCDAT&GPC5_ON;};return(0);}實驗要求(1)按照2.3節(jié)介紹的方法,在ADS下創(chuàng)建一個工程ext_interrupt,并將前面示例程序加入工程。按照上面的介紹進行環(huán)境設置,并進行程序?qū)懭搿jP掉實驗箱電源,將其核心板上的撥動開關撥到右邊Nor的位置,觀察程序運行結果。按下INTKEY按鈕,再次觀察程序運行效果。(2)實驗過程中請記錄并思考以下內(nèi)容:1)打開s2440addr.h頭文件,觀察并分析其內(nèi)容。2)分析中斷控制程序的結構。3)仔細分析中斷初始化程序和中斷處理程序中寄存器的設置方法,并理解其含義。4)總結中斷程序的設計方法。實驗截圖:實驗練習題答案打開s2440addr.h頭文件,觀察并分析其內(nèi)容。S2440.h的部分代碼如下圖所示#ifndef__2440ADDR_H__#define__2440ADDR_H__#ifdef__cplusplusextern"C"{#endif//#include"option.h"http://Memorycontrol#definerBWSCON(*(volatileunsigned*)0x48000000)//Buswidth&waitstatus#definerBANKCON0(*(volatileunsigned*)0x48000004)//BootROMcontrol#definerBANK

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論