版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第五章匯編語言程序設(shè)計及
系統(tǒng)初分別化5.1ARM匯編語言程序框架5.2浮點(diǎn)數(shù)據(jù)處理5.3系統(tǒng)初始化5.4中斷服務(wù)程序本章小結(jié)5.1ARM匯編語言程序框架
在MDK環(huán)境下,新建一個工程ex5_1,拷貝工程ex4_3中的文件S3C2410A.s和initmemcon.s,然后,編寫一個新的匯編語言程序ledflash.s,其代碼如下:
1 AREALEDLIGHT,CODE,READONLY
2 EXPORT__main;LedFlash
3 EXPORT__use_two_region_memory
4GPCDAT_ADDR EQU0x56000024
5LED_ON EQU0x0000
6LED_OFF EQU0x00E0
7 ENTRY
8;LedFlash
9__main
10 LDR R0,=GPCDAT_ADDR
11 MOV R1,#LED_ON
12 STR R1,[R0] ;LEDON
13
14 BL Delay
15
16 MOV R1,#LED_OFF
17 STR R1,[R0];LEDOFF
18
19 BL Delay
20
21 B __main
22Delay
23 MOV R3,#0x0F0000
24 MOV R4,#0x0F0000
25subcycle1
26 SUB R3,R3,#1
27subcycle2
28
SUB R4,R4,#1
29 CMP R4,#0
30 BGE subcycle2
31
32 CMP R3,#0
33 BGE subcycle1
34 BX LR
35
36__use_two_region_memory;nowarning
37 END
將ledflash.s添加到工程ex5_1中,當(dāng)前工作主窗口如圖5-1所示。先不要編譯連接這個工程文件,在5.1.2小節(jié)時才能正確地編譯連接并執(zhí)行該工程。圖5-1工程ex5_1工作界面5.1.1通用輸入輸出C口配置
在圖5-1中,雙擊S3C2410A.s打開它,保持其他設(shè)置不變(相對于工程ex4_3)的情況下,對I/OConfiguration進(jìn)行配置,如圖5-2所示。
圖5-2中將PC5、PC6和PC7配置為輸出特性(Output),對應(yīng)于S3C2410A.s的第0606~0608行代碼如下:
PIOC_SETUP EQU1
PCONC_Val EQU0xAAAA56AA
PUPC_Val EQU0x00000000圖5-2通用I/O口配置
PIOC_SETUP為1表示圖5-2中的PortC被勾選;當(dāng)設(shè)置PC0~PC15如圖5-2時,端口C的控制寄存器的值為0xAAAA56AA;端口C所有上拉電阻都是使能的,端口C上拉控制寄存器的值為0x00000000。
圖5-2中的I/OConfiguration勾選,對應(yīng)于S3C2410A.s中的第0510行代碼如下:
PIO_SETUP EQU1
如圖5-2設(shè)置好之后,下面羅列出啟動代碼文件S3C2410A.s中與通用I/O口配置相關(guān)的代碼,如表5-1所示。表5-1S3C2410A.s中與I/O口配置相關(guān)的代碼序號行號注釋或語句10488;I/OPortsdefinitions20489PIO_BASEEQU0x56000000;PIOBaseAddress30490PCONA_OFSEQU0x00;PCONAOffset40491PCONB_OFSEQU0x10;PCONBOffset50492PCONC_OFSEQU0x20;PCONCOffset60493PCOND_OFSEQU0x30;PCONDOffset70494PCONE_OFSEQU0x40;PCONEOffset80495PCONF_OFSEQU0x50;PCONFOffset90496PCONG_OFSEQU0x60;PCONGOffset100497PCONH_OFSEQU0x70;PCONHOffset110498PCONJ_OFSEQU0xD0;PCONJOffset120499PUPB_OFSEQU0x18;PUPBOffset130500PUPC_OFSEQU0x28;PUPCOffset140501PUPD_OFSEQU0x38;PUPDOffset150502PUPE_OFSEQU0x48;PUPEOffset160503PUPF_OFSEQU0x58;PUPFOffset170504PUPG_OFSEQU0x68;PUPGOffset180505PUPH_OFSEQU0x78;PUPHOffset190506PUPJ_OFSEQU0xD8;PUPJOffset200509;//<e>I/OConfiguration210510PIO_SETUPEQU1220512~0536A口注釋230537PIOA_SETUPEQU0240538PCONA_ValEQU0x000003FF250540~0565B口注釋260566PIOB_SETUPEQU0270567PCONB_ValEQU0x000007FF280568PUPB_ValEQU0x00000000290570~0605C口注釋300606PIOC_SETUPEQU1310607PCONC_ValEQU0xAAAA56AA320608PUPC_ValEQU0x00000000330610~0645D口注釋340646PIOD_SETUPEQU0350647PCOND_ValEQU0x00000000360648PUPD_ValEQU0x00000000370650~0685E口注釋380686PIOE_SETUPEQU0390687PCONE_ValEQU0x00000000序號行號注釋或語句400688PUPE_ValEQU0x00000000410690~0709F口注釋420710PIOF_SETUPEQU0430711PCONF_ValEQU0x0000511A440712PUPF_ValEQU0x00000000450714~0749G口注釋460750PIOG_SETUPEQU0470751PCONG_ValEQU0x00000000480752PUPG_ValEQU0x00000000490754~0779H口注釋500780PIOH_SETUPEQU0510781PCONH_ValEQU0x000007FF520782PUPH_ValEQU0x00000000530922;I/OConfiguration540923IFPIO_SETUP<>0550924PIOA_CFG560925DCDPCONA_Val570926PIOB_CFGDCDPCONB_Val580927DCDPUPB_Val590928PIOC_CFGDCDPCONC_Val600929DCDPUPC_Val610930PIOD_CFGDCDPCOND_Val620931DCDPUPD_Val630932PIOE_CFGDCDPCONE_Val640933DCDPUPE_Val650934PIOF_CFGDCDPCONF_Val660935DCDPUPF_Val670936PIOG_CFGDCDPCONG_Val680937DCDPUPG_Val690938PIOH_CFGDCDPCONH_Val700939DCDPUPH_Val710940ENDIF720981~1038S3C2410A.s有誤,將在下面說明。
S3C2410A.s中的第0981~1038行原始代碼如下:
IF
PIO_SETUP<>0
LDRR14,=PIO_BASE
IFPIOA_SETUP<>0
ADR R0,PIOA_CFG
STR R0,[R14,#PCONA_OFS]
ENDIF
IF PIOB_SETUP<>0
ADRR0,PIOB_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONB_OFS]
STR R1,[R14,#PUPB_OFS]
ENDIF
IF PIOC_SETUP<>0
ADR R0,PIOC_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONC_OFS]
STR R1,[R14,#PUPC_OFS]
ENDIF
IF PIOD_SETUP<>0
ADR R0,PIOD_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCOND_OFS]
STR R1,[R14,#PUPD_OFS]
ENDIF
IF
PIOE_SETUP<>0
ADR R0,PIOE_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONE_OFS]
STR R1,[R14,#PUPE_OFS]
ENDIF
IF PIOF_SETUP<>0
ADR R0,PIOF_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONF_OFS]
STR R1,[R14,#PUPF_OFS]
ENDIF
IF PIOG_SETUP<>0
ADR R0,PIOG_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONG_OFS]
STR R1,[R14,#PUPG_OFS]
ENDIF
IF PIOH_SETUP<>0
ADR R0,PIOH_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONH_OFS]
STR R1,[R14,#PUPH_OFS]
ENDIF
ENDIF
修正后的代碼如下,其中,添加了注釋的為補(bǔ)充和修正的代碼行:
IF
PIO_SETUP<>0
LDRR14,=PIO_BASE
IFPIOA_SETUP<>0
ADR R0,PIOA_CFG
LDR R2,[R0];AddedbyZY
STR R2,[R14,#PCONA_OFS];ChangedbyZY
ENDIF
IFPIOB_SETUP<>0
ADR R0,PIOB_CFG
LDRR2,[R0];AddedbyZY
LDRR1,[R0,#4]
STR R2,[R14,#PCONB_OFS];ChangedbyZY
STR R1,[R14,#PUPB_OFS]
ENDIF
IFPIOC_SETUP<>0
ADR R0,PIOC_CFG
LDR R2,[R0];AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONC_OFS]
;R0,[R14,#PCONC_OFS]ChangedbyZY
STR R1,[R14,#PUPC_OFS]
ENDIF
IFPIOD_SETUP<>0
ADR R0,PIOD_CFG
LDR R2,[R0]
;AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCOND_OFS]
;ChangedbyZY
STR R1,[R14,#PUPD_OFS]
ENDIF
IFPIOE_SETUP<>0
ADR R0,PIOE_CFG`
LDR R2,[R0];AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONE_OFS]
;
ChangedbyZY
STR R1,[R14,#PUPE_OFS]
ENDIF
IFPIOF_SETUP<>0
ADR R0,PIOF_CFG
LDR
R2,[R0];AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONF_OFS]
;ChangedbyZY
STR R1,[R14,#PUPF_OFS]
ENDIF
IFPIOG_SETUP<>0
ADR R0,PIOG_CFG
LDR R2,[R0];AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONG_OFS];ChangedbyZY
STR R1,[R14,#PUPG_OFS]
ENDIF
IFPIOH_SETUP<>0
ADR R0,PIOH_CFG
LDR R2,[R0] ;AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONH_OFS];ChangedbyZY
STR R1,[R14,#PUPH_OFS]
ENDIF
ENDIF
MDK軟件雖然是個極其優(yōu)秀的軟件包,但是,此處的錯誤是很明顯的,由于具有8個IO口,相同的錯誤連續(xù)出現(xiàn)了8次以上。例如對于C口,代碼如下:
IF PIOC_SETUP<>0
ADR R0,PIOC_CFG
LDR R1,[R0,#4]
STR R0,[R14,#PCONC_OFS]
STR R1,[R14,#PUPC_OFS]
ENDIF結(jié)合第二章,可知條件滿足,執(zhí)行完ADR指令后,R0裝入的是PIOC_CFG的標(biāo)號,即一個地址,這個地址內(nèi)的值為配置字,但是這個地址本身不能作為配置字,所以,后面的“STRR0,[R14,#PCONC_OFS]”語句就是完全錯誤的了。改正的方法很簡單,代碼如下:
IF PIOC_SETUP<>0
ADR R0,PIOC_CFG
LDR R2,[R0] ;AddedbyZY
LDR R1,[R0,#4]
STR R2,[R14,#PCONC_OFS]
;R0,[R14,#PCONC_OFS]ChangedbyZY
STR R1,[R14,#PUPC_OFS]
ENDIF像上述代碼一樣,將R0值指向的地址處的值賦給R2,然后,再使用“STRR2,[R14,#PCONC_OFS]”就可以了。對于一個商業(yè)軟件,其評估版的S3C2410芯片啟動代碼出現(xiàn)問題,一方面說明了這部分代碼沒有經(jīng)過嚴(yán)格測試,另一方面也警告我們,匯編語言編程相對于C語言來說,確有一些劣勢。
下面解釋一下表5.1和啟動代碼中關(guān)于IO口配置的方法。
序號2~19:定義了IO口存儲器映射寄存器的基地址0x56000000,然后定義了A~H口的偏移地址,這些IO口寄存器的地址可參考附表1-1。例如,C口的控制寄存器地址為0x56000020,相當(dāng)于基址0x56000000+偏移地址PCONC_OFS(0x20)。這里沒有J口,可以刪除。序號21:當(dāng)勾選了圖5-2中I/OConfiguration后,此處,PIO_SETUP為1;否則,不勾選時,PIO_SETUP為0,將不初始化IO口。
序號23~24:由于圖5-2中沒有勾選PortA,則PIOA_SETUP為0,A口只有控制寄存器,沒有上拉寄存器,這里只有PCONA_Val,當(dāng)然,這個值由于PIOA_SETUP為0而不會被用到。
序號26~28:由于圖5-2中沒有勾選PortB,則PIOB_SETUP為0;符號PCONB_Val和PUPB_Val的值表示B口的控制寄存器和上拉寄存器的配置字,這些值隨著圖形配置向?qū)Ф詣幼兓?。序?0~32:由于圖5-2中勾選了PortC,則PIOC_SETUP為1;同時,根據(jù)圖形配置向?qū)ё詣釉O(shè)置了控制寄存器和上拉寄存器的值PCONC_Val和PUPC_Val,這兩個值代表的含義請參考圖5-2和“S3C2410AUser’sManual”第九章第10頁,把GPC[7:5]設(shè)為輸出口。
序號34~52:介紹端口D~H,與上述含義相近,不再
重述。
序號54~71:如果PIO_SETUP不為0,則開辟存儲空間存放端口A~H的配置字,其中,A口只有一個配置字,B~H口均有兩個配置字。5.1.2工程ex5_1的注解及運(yùn)行情況
在前面5.1.1小節(jié)對S3C2410A.s進(jìn)行修正之后,可以編譯連接并下載這個工程了,在編譯時會報告一條警告信息,即“ex5_1.sct(8):warning:L6314W:Nosectionmatchespattern*(InRoot$$Sections)”,這里的ex5_1.sct是根據(jù)工程選項(像圖4-15那樣)的設(shè)置編譯工程時自動產(chǎn)生的存儲器配置文件,也稱Scatter文件,以?.sct結(jié)尾;“InRoot$$Section”是指為連接庫里的段分配的空間,用于C語言程序設(shè)計中。
雙擊該警告信息,則彈出ex5_1.sct文件內(nèi)容,如圖5-3所示,在“*(InRoot$$Sections)”前面加上“;”號將其注釋掉,并保存文件。圖5-3ex5_1.sct文件這時先不要編譯工程,打開工程選項,選中“Linker”頁簽,設(shè)置如圖5-4所示,即使用ScatterFile:ex5_1.sct。
說明:工程選項中的其他頁簽保持不變(相對于工程ex4_3)。
點(diǎn)擊圖5-4的“OK”按鈕后,可以重新編譯工程ex5_1,此時沒有錯誤,也沒有警告信息了,如圖5-5所示。
在圖5-5上,點(diǎn)擊“Flash|Download”菜單(或單擊工具欄上的快捷按鈕)則把ex5_1.axf下載到UP-NETARM2410實驗箱Nand型Flash上。下載完畢后,程序?qū)樱梢钥吹饺齻€LED燈在閃爍!也可以在線仿真調(diào)試(一般地,要把程序下載到Flash中后再仿真),或者把ULINK2仿真器從實驗箱上取下來,重新給實驗箱上電,則程序會從Flash中啟動執(zhí)行。圖5-4工程選項卡設(shè)置圖5-5完整的工程ex5_1本節(jié)還有兩個問題沒有解決,其一為Scatter文件如何編寫,其二為匯編語言程序ledflash.s的解釋。
筆者認(rèn)為Scatter文件的內(nèi)容及如何編寫該文件方面的知識,除了一些ARM官方的文檔之外,最好的資料是MDK軟件的幫助菜單。這個幫助菜單和它的內(nèi)容做得相當(dāng)出色!本書中,筆者幾乎無一例外地使用工程選項卡配置存儲器,因此,對Scatter文件內(nèi)容的介紹也不會很多。
現(xiàn)在,解釋一下5.1節(jié)開頭給出的程序段,即ledflash.s文件,該文件內(nèi)容如圖5-6所示,在圖5-6中給出語句的行號,下面按行號解釋。圖5-6ledflash.s文件內(nèi)容行號01:定義名為LEDLIGHT的只讀代碼段。
行號02:標(biāo)號__main在外部可見。
行號03:標(biāo)號__use_two_region_memory在外部可見。這句和行號36處沒有實際意義,僅是為了編譯時不出現(xiàn)警告或錯誤,因為在S3C2410A.s的第1095行(修正后的文件行號)有一句“IMPORT__use_two_region_memory”。
行號04:定義C口數(shù)據(jù)寄存器地址。
行號05:定義LED燈亮的常量。
行號06:定義LED燈滅的常量。行號07:ENTRY指程序入口點(diǎn),一般的匯編程序只需要有一個入口點(diǎn),而且這個入口點(diǎn)常被用作上電復(fù)位后的執(zhí)行入口點(diǎn)。需要說明的是,這里的ENTRY入口點(diǎn),并不是上電復(fù)位的執(zhí)行入口點(diǎn),在本程序中,由于RESET段是存儲在地址0x00000000處的,所以,RESET是上電復(fù)位入口點(diǎn)(RESET在S3C2410A.s文件中)。
行號09:定義標(biāo)號__main。
行號10:R0=0x56000024。
行號11:R1=0。
行號12:向地址0x56000024處賦值0,即使GPC5、GPC6和GPC7為0(低電平),由第二章圖2-26可知,將點(diǎn)亮三個LED燈。行號14:跳轉(zhuǎn)到延遲子程序,這個程序段不作介紹。
行號16:R1=0xE0。
行號17:向地址0x56000024處賦值1,即使GPC5、GPC6和GPC7為1(高電平),由第二章圖2-26可知,將熄滅三個LED燈。
行號19:跳轉(zhuǎn)到延遲子程序。
行號21:跳轉(zhuǎn)到__main,循環(huán)執(zhí)行。
程序功能:點(diǎn)亮三個LED燈后,等待約(0xF0000*0xF0000*指令周期)后,熄滅LED燈,再等待一段時間后,重新點(diǎn)亮LED燈,循環(huán)執(zhí)行,給人LED燈閃爍的感覺。5.1.3匯編語言語法
ARM匯編語言的語法內(nèi)容豐容,本書的重點(diǎn)不在于匯編語言,匯編語言主要用于初始化系統(tǒng)。因此,這里簡單地介紹一些常用的匯編語言語法。
1)?AREA
AREA已出現(xiàn)在ledflash.s中,用于定義匯編語言代碼段或數(shù)據(jù)段,例如:
AREALEDLIGHT,CODE,READONLY
AREALEDSHINE,DATA,?READWRITE上述代碼段定義一個名為LEDLIGHT的只讀代碼段和一個名為LEDSHINE的讀寫代碼段。DATA用得較少。
在S3C2410A.s中有如下語句:
AREASTACK,NOINIT,READWRITE,ALIGN=3
該語句中,NOINIT偽關(guān)鍵字表示該段代碼只分配空間,不初始化(用0填充),ALIGN=3表示按雙字對齊方式(23=8B)。
2)?SPACE
在S3C2410A.s中有如下語句:
Stack_MemSPACEStack_Size這里Stack_Mem為標(biāo)號,Stack_Size為常量,SPACE表示為Stack_Mem分配大小為Stack_Size的連續(xù)空間,單位為字節(jié)。
3)?DCD
DCD已出現(xiàn)在initmemcon.s中,表示分配字大小的連續(xù)空間,并用其他的值初始化該空間,例如:
Mem_Val_ConfDCD0x22111110,0x700
表示為標(biāo)號Mem_Val_Conf分配兩個字空間,并初始化這個字的值為0x22111110和0x700。此外,還有DCDU表示不按字對齊方式存儲,慎用??!
除了DCD之外,還有DCB、DCW、DCQ、DCFS、DCFD等,分別表示為字節(jié)、半字、雙字、單精度浮點(diǎn)數(shù)(即字)、雙精度浮點(diǎn)數(shù)(即字)分配空間,并使用指定的數(shù)據(jù)初始化。
4)?EQU
EQU是匯編語言的相等偽指令,用得較多。例如在initmemcon.s中有:
Mem_Addr_BaseEQU0x48000000
5)?PRESERVE8
PRESERVE8指定當(dāng)前文件的堆棧采用8字節(jié)對齊方式,出現(xiàn)在S3C2410A.s中第0789行,要求每個棧的長度的最低3位為0,且棧底地址的最低3位也應(yīng)為0。
6)?ARM
ARM指示符出現(xiàn)在S3C2410A.s中第0796行,指示編譯器生成32位指令的ARM代碼;而THUMB指示符表示生成16位指令的Thumb代碼。另外,THUMBX用于生成Thumb-2EE代碼。
7)?NOP
NOP即Nooperation,表示空操作。
8)?IF語句
IF語句格式為:
IF條件表達(dá)式
語句組1
ELSE
語句組2
ENDIF當(dāng)條件表達(dá)式為真時,執(zhí)行語句組1;否則,執(zhí)行語句組2。出現(xiàn)在條件表達(dá)式中的“<>”(例如S3C2410A.s中的第0923行)表示不等于。表示等于、大于、小于、大于等于、小于等于的關(guān)系操作符為=、>、<、>=、<=。
9)?IMPORT
IMPORT后面跟標(biāo)識符,表明該標(biāo)識符是在該文件外部定義的,標(biāo)識符后可以加可選項[WEEK],則引用的標(biāo)識符沒有定義時,編譯時也不會出錯。而該文件中定義的標(biāo)識符需要被工程中的其他文件引用時,使用EXPORT關(guān)鍵字。同時,GLOBAL可以聲明一個全局標(biāo)識符。此外,EXTERN的功能與IMPORT相似,當(dāng)該文件中沒有實際引用這個標(biāo)識符時,EXTERN下編譯器不會添加該標(biāo)識符到符號表中。
10)邏輯操作
S3C2410A.s的第1054行出現(xiàn)了“:OR:”,表示按位取或,還有以下偽操作符:
:AND:表示按位取與;:EOR:表示按位取異或;:NOT:表示取反。
同時,還有:MOD:?表示取模,:SHL:、:SHR:、:ROL:?和:?ROR:?分別表示左移、右移、循環(huán)左移、循環(huán)右移,還可以使用+、-、*、/算符,其中“+”出現(xiàn)在S3C2410A.s的第
1100行。
表示邏輯操作的有:LNOT:、:LAND:、:LOR:和:LEOR:,依次為邏輯取反、邏輯與、邏輯或、邏輯異或。
11)?END
匯編語言每個程序段均以END結(jié)尾。
匯編語言程序是由AREA定義的一個個代碼段組成的,每個代碼段由匯編指令語句組成,完成某項特定的功能,最后以END結(jié)尾。不同的代碼段之間可以通過引用標(biāo)號的方式相互調(diào)用。工程ex5_1包含了匯編語言程序的基本特征,可以視為匯編語言程序的學(xué)習(xí)框架程序。在5.4節(jié)中還將添加中斷處理進(jìn)一步完善該程序。
5.2浮點(diǎn)數(shù)據(jù)處理
浮點(diǎn)數(shù)即小數(shù),使用ARM匯編語言表示和處理小數(shù),需要借助于IEEE-754標(biāo)準(zhǔn)或者DSP定標(biāo)的方法。DSP定標(biāo)方法在定點(diǎn)DSP芯片進(jìn)行浮點(diǎn)數(shù)據(jù)處理時經(jīng)常使用,相關(guān)內(nèi)容可參考《TMS320C5000系列DSP匯編語言程序設(shè)計》第六章,在這一章中,作者指出,“匯編語言是公認(rèn)的硬件操作最好的語言,并且用它來編寫算法對編程者的思維也是一個很好的啟迪過程?!笔聦嵣?,由于匯編語言語法簡單明了,用來實現(xiàn)算法時,沒有現(xiàn)成的算法庫來調(diào)用,因此,編程者必須親自編寫算法的每個函數(shù)和每個細(xì)節(jié),從而要求編程者對算法非常熟悉才行。本節(jié)內(nèi)容將介紹ARM920T下的數(shù)值定標(biāo)和正余弦函數(shù)的計算。5.2.1計算基礎(chǔ)
計算正弦和余弦函數(shù)的值,需要借助于泰勒級數(shù)展開式,如下:例如,取x=0.45,則(1)(2)上兩式為本節(jié)程序采用的算法。5.2.2數(shù)值定標(biāo)
匯編語言中的32位操作數(shù)只能為0或1組成的碼字。所謂“碼字”,是指CPU只能把存儲器的內(nèi)容視為二進(jìn)制數(shù)碼符號(實際上是電平信號),而不是數(shù)字。人們習(xí)慣把二進(jìn)制碼字之間的運(yùn)算關(guān)系稱為二進(jìn)制數(shù)(二進(jìn)制補(bǔ)碼)之間的運(yùn)算,所以常常給人一種存儲器存儲的是數(shù)的假象。但是,在碼和數(shù)之間的確有一種一一映射的關(guān)系,并且,在這個映射關(guān)系上可以將數(shù)的運(yùn)算映射為碼間的運(yùn)算。同時,由于十六進(jìn)制表示的整數(shù)和碼字之間這種映射關(guān)系非常直觀,以至于人們會忽略這種映射的存在。例如,給定一個十六進(jìn)制碼字0x00000055,人們會不加思考地認(rèn)為它等于十進(jìn)制數(shù)85。這種相等是有條件的,即0x00000055碼字的小數(shù)定標(biāo)點(diǎn)位于第0位以后(或認(rèn)為沒有小數(shù)定標(biāo)點(diǎn)),這個定標(biāo)點(diǎn)是思想中添加的、用于碼和數(shù)之間映射的一種關(guān)系。對于整數(shù)的處理,人們可以很直觀地認(rèn)為這個定標(biāo)點(diǎn)不存在。對于小數(shù)處理,就不能忽視這個定標(biāo)點(diǎn)了。定標(biāo)的方法就是通過加定標(biāo)的方法將小數(shù)轉(zhuǎn)化為十六進(jìn)制數(shù)(碼)的方法,ARM是32位定點(diǎn)處理器,定標(biāo)點(diǎn)可設(shè)為0~32。定標(biāo)點(diǎn)確定后,32位的存儲字存儲的數(shù)據(jù)大小也就確定了。一個小數(shù)a的n定標(biāo)值為取整(a×2n),0≤n≤32。根據(jù)這種方法,小數(shù)0.45的31定標(biāo)值為0.45×231=966367641.6d≈966367641d=
0x39999999,即設(shè)置定標(biāo)點(diǎn)為31后,十六進(jìn)制值0x39999999不再是整數(shù)966367641,而是小數(shù)0.45。定標(biāo)有一種記號法,即Q(32-n).n,定標(biāo)點(diǎn)為31時,記作Q1.31,有時簡記為Q31,是最常用的一種定標(biāo)方法。但是,Q31定標(biāo)只能表示[-1,1)區(qū)間的小數(shù),如果表示更大范圍內(nèi)的小數(shù),例如區(qū)間[-2,2),則需要采用定標(biāo)Q2.30。小數(shù)定標(biāo)后的值往往是小數(shù)的近似值,這說明計算機(jī)采用定標(biāo)方法只能不精確地表示小數(shù),例如,小數(shù)0.1就不能精確定標(biāo)。小數(shù)的定標(biāo)值可參與加、減和乘等運(yùn)算,由于定標(biāo)值表示的數(shù)據(jù)范圍有限,所以定標(biāo)值間的運(yùn)算不能有溢出,否則計算結(jié)果錯誤。特別是乘法運(yùn)算,乘法結(jié)果為64位,定標(biāo)點(diǎn)位置移動到62位,必須取高32位(同時向左移一位)進(jìn)行定標(biāo)點(diǎn)的還原(為31位);加法和減法運(yùn)算不改變定標(biāo)點(diǎn)。常用的做法為:在十進(jìn)制數(shù)條件下進(jìn)行小數(shù)的算法處理,找到所有參與運(yùn)算的小數(shù)、中間結(jié)果和最終結(jié)果的絕對值最大值,按照這個最大值確定定標(biāo)點(diǎn)位置。然后,將小數(shù)轉(zhuǎn)換為定標(biāo)值,編寫匯編語言程序?qū)Χ?biāo)值進(jìn)行處理,得到定標(biāo)值表示的最終結(jié)果。最后,用去定標(biāo)的方法,即最終結(jié)果除去2n后得到真實的小數(shù)形式結(jié)果。在這個過程中,只有上一行的陰影部分是ARM匯編語言程序完成的。計算0.45的正弦和余弦值匯編語言程序,由于輸入數(shù)據(jù)、中間結(jié)果和最終結(jié)果都不可能超過1,可以采用Q31定標(biāo)方法。
需要指出的是,上述介紹的是有符號的定標(biāo),即定標(biāo)值的最高位31位為符號位,這種定標(biāo)方法用得較多。關(guān)于無符號定標(biāo)方法,由于與有符號定標(biāo)方法相似,故本書不作介紹。
下面把公式(1)和(2)中出現(xiàn)的常數(shù)按Q31定標(biāo)方法計算的定標(biāo)值列于表5-2中。表5-2公式(1)和(2)中常數(shù)的Q31定標(biāo)值小數(shù)0.451/3!1/5!1/7!定標(biāo)值0x399999990x155555550x11111110x68068小數(shù)11/2!1/4!1/6!定標(biāo)值0x7FFFFFFF0x400000000x55555550x2D82D8這里的定標(biāo)點(diǎn)和小數(shù)點(diǎn)是完全不同的概念,請注意區(qū)分。5.2.3程序代碼及結(jié)果分析
本小節(jié)的內(nèi)容不是本書的重點(diǎn),因此對本小節(jié)中的匯編程序不作深入分析,但是我們還是給出了完整的程序示例和源代碼(注釋清晰),供感興趣的讀者參考。
在工程ex5_1的基礎(chǔ)上,新建工程ex5_2,修改ledflash.s文件,其代碼如下所示:
1 AREALEDLIGHT,CODE,READONLY
2 EXPORT__main;LedFlash
3 EXPORT__use_two_region_memory
4
5 IMPORTSin0p45;forSincos0.45
6GPCDAT_ADDR EQU0x56000024
7LED_ON EQU0x0000
8LED_OFF EQU0x00E0
9 ENTRY
10;LedFlash
11__main
12 BL Sin0p45;forSincos0.45
13ledflash
14 LDR R0,=GPCDAT_ADDR
15 MOV R1,#LED_ON16 STR R1,[R0] ;LEDON
17
18 BL Delay
19
20 MOV R1,#LED_OFF
21 STR R1,[R0]
;LEDOFF
22
23 BL Delay
24
25 B ledflash
26Delay
27 MOV R3,#0x0F0000
28 MOV R4,#0x0F0000
29subcycle1
30 SUB
R3,R3,#1
31subcycle2
32
SUB
R4,R4,#1
33 CMP R4,#0
34 BGE subcycle2
35
36 CMP R3,#0
37 BGE subcycle1
38 BX LR
39
40__use_two_region_memory;nowarning
41 END
上述代碼中后跟注釋“;forSincos0.45”的語句為新添加的語句,即先進(jìn)行求正余弦值的運(yùn)算,然后再作使LED燈閃爍的處理。
新建匯編語言文件sincos0p45.s,并添加到工程ex5_2中,工程ex5_2的主界面如圖5-7所示。圖5-7工程ex5_2的工作界面文件sincos0p45.s的完整代碼如下:
1AREASINCOS,CODE,READONLY
2 ?EXPORTSin0p45
3Sin0p45
4 STMFDSP!,{R0-R9,R14}
5
6 ;calculatesin0.45
7 ;R0-R1loadaddress
8 ;R3-R8loadvalue
9 ADRR0,x_q ;R0isaddrofx
10 LDRR4,[R0] ;R4=x
11
12 SMULL R5,R6,R4,R4
13 MOV R7,R6,LSL#1
14 ADD R7,R7,R5,LSR#31;R7=x*x
15
16
SMULL R5,R6,R4,R7
17 MOV R8,R6,LSL#1
18 ADD R8,R8,R5,LSR#31;R8=x*x*x
19
20 ADR R1,cof_3
21 LDR
R3,[R1]
;R3=cof3
22
23 SMULL
R5,R6,R3,R8
24 MOV
R2,R6,LSL#1
25 ADD
R2,R2,R5,LSR#31
;R2=x^3/3!
26
27 MOV
R9,R4
28 SUB
R9,R9,R2
;R9=x-x^3/3!
29
30 SMULL R5,R6,R7,R8
31 MOV R8,R6,LSL#1
32 ADD R8,R8,R5,LSR#31
;R8=x^5
33
34 ADR R1,cof_5
35 LDR R3,[R1];R3=cof5
36
37 SMULL R5,R6,R3,R8
38 MOV R2,R6,LSL#1
39 ADD R2,R2,R5,LSR#31
;R2=x^5/5!
40
41 ADD R9,R9,R2;R9=x-x^3/3!+x^5/5!
42
43 SMULL R5,R6,R7,R8
44 MOV R2,R6,LSL#1
45 ADD R2,R2,R5,LSR#31 ;R2=x^7
46
47 ADR R1,cof_7
48 LDR R3,[R1] ;R3=cof7
49
50SMULL R5,R6,R3,R2
51 MOV R2,R6,LSL#1
52
ADDR2,R2,R5,LSR#31;R2=x^7/7!
53
54
SUBR9,R9,R2;R9=x-x^3/3!+x^5/5!-x^7/7!
55
56LDRR1,=sin_x
57STRR9,[R1]
58
59;calculatecos0.45
60ADR R0,x_q ;R0isaddrofx
61LDR R4,[R0] ;R4=x
62
63 SMULL R5,R6,R4,R4
64 MOV R7,R6,LSL#1
65 ADD R7,R7,R5,LSR#31;R7=x*x
66
67
SMULL R5,R6,R7,R7
68 MOV R8,R6,LSL#1
69 ADD R8,R8,R5,LSR#31;R8=x^4
70
71 ADR R1,cof_2
72 LDR R3,[R1];R3=cof2
73
74 SMULL R5,R6,R3,R7
75 MOV R2,R6,LSL#1
76 ADD R2,R2,R5,LSR#31 ;R2=x^2/2!
77
78 ADR R0,cof_1
79 LDR R9,[R0]
80 SUB
R9,R9,R2;R9=1-x^2/2!
81
82 ADR
R1,cof_4
83 LDR
R3,[R1];R3=cof4
84
85 SMULL R5,R6,R3,R8
86 MOV R2,R6,LSL#1
87 ADD R2,R2,R5,LSR#31 ;R2=x^4/4!
88
89 ADD R9,R9,R2;R9=1-x^2/2!+x^4/4!
90
91 SMULL
R5,R6,R7,R8
92 MOV R2,R6,LSL#1
93 ADD R2,R2,R5,LSR#31;R2=x^6
94
95 ADRR1,cof_6
96 LDRR3,[R1];R3=cof6
97
98 SMULLR5,R6,R3,R2
99 MOVR2,R6,LSL#1
100 ADDR2,R2,R5,LSR#31;
R2=x^6/6!
101
102 SUB R9,R9,R2;R9=1-x^2/2!+x^4/4!-x^6/6!
103
104 LDRR1,=cos_x
105 STR R9,[R1]
106
107 ;BX LR
;return
108 LDMFD SP!,{R0-R9,PC};return
109
110x_q DCD0x39999999;0.45
111cof_1 DCD0x7FFFFFFF ;1
112cof_2 DCD0x40000000 ;1/2!
113cof_3 DCD0x15555555 ;1/3!
114cof_4 DCD0x05555555 ;1/4!
115cof_5 DCD0x01111111 ;1/5!
116cof_6 DCD0x002D82D8 ;1/6!
117cof_7 DCD0x00068068;1/7!
118
119 AREASINCOSRES,DATA,READWRITE
120sin_x DCD0 ;sin0.45
121cos_x DCD0 ;cos0.45
122 END
編譯連接下載工程ex5_2,然后調(diào)試工程,如圖5-8所示。圖5-8工程ex5_2的調(diào)試窗口工程ex5_2的計算結(jié)果sin0.45和cos0.45保存在標(biāo)號sin_x和cos_x處,即圖5-8右側(cè)Memory的0x30000000和0x30000004處,計算結(jié)果數(shù)值為0x37ACF357和0x7341D96B,去定標(biāo)后的值(即轉(zhuǎn)化為十進(jìn)制數(shù),再除以231后的值)為:
計算值sin0.45=0.4349655318073928356170654296875
計算值cos0.45=0.9004470608197152614593505859375而真實值為:
真實值sin0.45=0.4349655341112302104208442462319
真實值cos0.45=0.90044710235267692166884061148645
計算值和真實值的誤差在10-7數(shù)量級上,可見,計算結(jié)果是正確的。(數(shù)學(xué)角度上,還要考慮級數(shù)的截斷誤差!)
5.3系統(tǒng)初始化
系統(tǒng)初始化是指上電復(fù)位后ARM芯片級程序首先要進(jìn)行的處理,即配置工作時鐘、看門狗電路、存儲器空間、通用IO口、中斷向量表及堆棧等,這些工作都可以借助MDK軟件的啟動代碼可視化配置向?qū)瓿?,生成相關(guān)的啟動代碼文件。這里選用了S3C2410芯片,所以啟動代碼文件為S3C2410A.s。下面將介紹這個啟動代碼文件中還沒有講述的部分,并編制一個替換掉該啟動代碼文件的初始化代碼文件。5.3.1啟動代碼S3C2410A.s
啟動代碼文件S3C2410A.s中已經(jīng)講述的部分為存儲器控制器、通用IO口配置以及堆和棧等四部分,本小節(jié)中介紹的內(nèi)容為看門狗定時器(WatchdogTimer)、時鐘管理器(ClockManagement)和中斷向量表(InterruptVectorTable)三部分,其中,中斷向量表在5.4節(jié)還要深入講述。
1.時鐘管理器
初始化時鐘管理器往往是初始化工作的第一步(例如DSP中),而在啟動文件S3C2410A.s中,第一步是初始化看門狗定時器,第二步是初始化時鐘管理器。結(jié)合“S3C2410AUser’sManual”第七章“Clock&PowerManagement”,可知時鐘管理器如圖5-9所示。
S3C2410A有四種工作模式,即正常模式、慢速模式、空閑模式和掉電模式,正常模式下由圖5-9所示模塊向CPU和所有外設(shè)提供時鐘源,外設(shè)時鐘源可以通過軟件打開或關(guān)閉,當(dāng)所有外設(shè)時鐘都工作時,芯片功耗達(dá)到最大。這里僅討論正常模式下的時鐘管理器配置。
從UP-NETARM2410實驗箱原理圖上可以查到,S3C2410A的OM3和OM2腳均接地,即OM[3:2]=0b00,則由S3C2410A芯片資料手冊可以查到,此時上電復(fù)位后時鐘配置為MPLL有效、UPLL有效、主時鐘源和USB時鐘源均來自外部的晶體。再查UP-NETARM2410實驗箱原理圖,可以查到PLL時鐘源頻率為12?MHz,RTC時鐘源為32.768?kHz。圖5-9S3C2410A時鐘管理器從附錄一的附表1-1可以查到與時鐘管理器相關(guān)的映射寄存器共有6個,即LOCKTIME、MPLLCON(必須初始化)、UPLLCON、CLKCON、CLKSLOW和CLKDIVN,基地址為0x4C000000,偏移量依次為0、0x4、0x8、0xC、0x10和0x14。這些寄存器的含義請參考S3C2410A芯片資料手冊第七章。這些寄存器統(tǒng)稱為時鐘控制寄存器,配置好這些寄存器后,輸入到芯片的時鐘將按圖5-10進(jìn)行分配,其中,F(xiàn)CLK給CPU,HCLK給AHB總線外設(shè)(例如ARM920T、存儲控制器、中斷控制器、LCD控制器、DMA和USB主機(jī)等),PCLK給APB總線外設(shè)(例如WDT、IIS、IIC、PWM定時器、MMC接口、ADC、UART、GPIO、RTC和SPI等),UCLK為USB服務(wù)。圖5-10S3C2410A時鐘分配方案現(xiàn)在看一下啟動代碼S3C2410A.s中與配置6個時鐘控制寄存器相關(guān)的語句,如表5-3所示,其中,行號以工程ex5_1中的S3C2410A.s為準(zhǔn)。表5-3S3C2410A.s中與時鐘控制器相關(guān)的代碼序號行號注釋或語句10068~0076;ClockManagementdefinitionsCLK_BASE EQU 0x4C000000 ;ClockBaseAddressLOCKTIME_OFS EQU 0x00 ;LOCKTIMEOffsetMPLLCON_OFS EQU 0x04 ;MPLLCONOffsetUPLLCON_OFS EQU 0X08 ;UPLLCONOffsetCLKCON_OFS EQU 0x0C ;CLKCONOffsetCLKSLOW_OFS EQU 0x10 ;CLKSLOWOffsetCLKDIVN_OFS EQU 0X14 ;CLDKIVNOffsetCAMDIVN_OFS EQU 0X18 ;CAMDIVNOffset20080~0140;時鐘控制器寄存器注釋30141~0147CLK_SETUP EQU 1MPLLCON_Val EQU 0x0005C080UPLLCON_Val EQU 0x00028080CLKCON_Val EQU 0x0007FFF0CLKSLOW_Val EQU 0x00000004LOCKTIME_Val EQU 0x00FFFFFFCLKDIVN_Val EQU 0X00000000序號行號注釋或語句40909~0918;ClockManagementConfigurationIFCLK_SETUP<>0CLK_CFGDCD LOCKTIME_ValDCD CLKDIVN_ValDCD MPLLCON_ValDCD UPLLCON_ValDCD CLKSLOW_ValDCD CLKCON_ValENDIF50958~0968IFCLK_SETUP<>0LDR R0,=CLK_BASEADR R8,CLK_CFGLDMIA? R8,{R1-R6}STR? R1,[R0,#LOCKTIME_OFS]STR? R2,[R0,#CLKDIVN_OFS]STR? R3,[R0,#MPLLCON_OFS]STR? R4,[R0,#UPLLCON_OFS]STR? R5,[R0,#CLKSLOW_OFS]STR? R6,[R0,#CLKCON_OFS]ENDIF表5-3中序號1一行表示定義時鐘控制寄存器的基地址和偏移量;序號3一行中,CLK_SETUP為1表示在配置向?qū)е小癈lockManagement”勾選,即使用S3C2410A.s初始化時鐘寄存器,其他的為6個寄存器的配置值;序號4中為時鐘控制寄存器配置字分配空間;序號5一行為初始化時鐘控制寄存器。(這段代碼寫得不錯!)下面理解一下表5-3中序號3一行中各配置字的含義,如表5-4所示,表5-4中也列出筆者擬配置的值,其中,“MDK值”表示MDK軟件啟動代碼中配置的值,“筆者值”為筆者擬定的值。表5-4時鐘控制寄存器配置值及含義寄存器名MDK值筆者值含義LOCKTIME0x00FFFFFF0x00FFFFFF
LOCKTIME的位[23:12]為UPLL的鎖定時間,位[11:0]為MPLL的鎖定時間,位[31:24]保留。這里采用復(fù)位值,也是最大值,MPLL和UPLL穩(wěn)定(鎖住)前的計數(shù)值均為0xFFFMPLLCON0x0005C0800x00058011
MPLLCON和UPLLCON結(jié)構(gòu)相同,第[19:12]位為MDIV,第[9:4]位為PDIV,第[1:0]位為SDIV,其他位保留。Mpll時鐘值=[輸入時鐘*(MDIV+8)]/[(PDIV+2*2SDIV],MDK的設(shè)置值為默認(rèn)值,表示Mpll為120?MHz,筆者的設(shè)置值為192?MHz。注意:雖然這款S3C2410A芯片最大工作頻率為200?MHz,但是配置PLL值應(yīng)使用推薦的配置,不要任意設(shè)置UPLLCON0x000280800x00078023
MDK的配置值為57.6?MHz,筆者的設(shè)定值為48?MHz寄存器名MDK值作者值含義CLKCON0x0007FFF00x0007FFF0
CLKCON寄存器從第18位至第4位依次管理SPI、IIS、IIC、ADC(含觸摸屏)、TRC、GPIO、UART2、UART1、UART0、SDI、PWMTIMER、USB設(shè)備、USB主機(jī)、LCDC、NandFlash的時鐘源。當(dāng)各位取1時有效;取0時無效。第3位至第0位依次為POWER_OFF模式、空閑模式、保留、SM_BIT(推薦為0)的設(shè)置位,均需取0。采用的是缺省設(shè)置CLKSLOW0x000000040x00000004
CLKSLOW寄存器第7位為1表示UCLK開,為0表示UCLK關(guān)(UPLL終始有效)。第5位為1表示PLL開,為0表示PLL關(guān)。第4位為0表示FCLK=Mpll,為1表示SLOW模式(此時時鐘大小計算請參考S3C2410A手冊)。第[2:0]位為慢時鐘分頻值,缺省為0x4。這里采用缺省值即可CLKDIVN0x000000000x00000003
CLKDIVN寄存器第1位為0,則HCLK時鐘為FCLK;第1位為1,則HCLK時鐘為FCLK/2。第0位為0,表示PCLK時鐘為HCLK;第0位為1,表示PCLK時鐘為HCLK/2。第2位為0,保留;如果第2位設(shè)為1,表示HCLK和PCLK均為FCLK./4,此時位[1:0]無效,且必須設(shè)為0b00結(jié)合圖5-9和圖5-10,配置時鐘寄存器后,Mpll時鐘穩(wěn)定前,CPU直接使用外部時鐘;當(dāng)PLL穩(wěn)定后,CPU時鐘FCLK將使用Mpll時鐘,即工作在192MHz下。
在工程ex5_1的基礎(chǔ)上新建工程ex5_3(此時,與工程ex5_1完全相同),然后,按表5-4中的“作者值”設(shè)置S3C2410A.s,如圖5-11所示。圖5-11
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 淺談對民間文藝演出團(tuán)體的管理與扶持
- 關(guān)于開挖 合同范本
- 公司助理合同范例
- 情感事務(wù)所創(chuàng)業(yè)計劃書模板
- 2025年度建筑工程施工合同勞務(wù)分包與材料采購合同管理
- 做門頭合同范本
- 企業(yè)聯(lián)銷合同范本
- 農(nóng)村樓房購買合同范本
- 2025年度國際物流人才培訓(xùn)與派遣合同
- 出版作品合同范本
- 四川省自貢市2024-2025學(xué)年上學(xué)期八年級英語期末試題(含答案無聽力音頻及原文)
- 2025-2030年中國汽車防滑鏈行業(yè)競爭格局展望及投資策略分析報告新版
- 2025年上海用人單位勞動合同(4篇)
- 二年級上冊口算題3000道-打印版讓孩子口算無憂
- 高中英語北師大版必修第一冊全冊單詞表(按單元編排)
- 新教科版科學(xué)小學(xué)四年級下冊全冊教案
- 2025年生物安全年度工作計劃
- 人教版數(shù)學(xué)六年級下冊全冊核心素養(yǎng)目標(biāo)教學(xué)設(shè)計
- 通用電子嘉賓禮薄
- 新概念英語第三冊課后習(xí)題答案詳解
- 有機(jī)化學(xué)共振論
評論
0/150
提交評論