版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
4.1概述4.1.1嵌入式系統(tǒng)應(yīng)用的編程語(yǔ)言匯編C目前使用的最多C++JAVA第4章ARM的C語(yǔ)言編程技術(shù)滿足系統(tǒng)的實(shí)時(shí)性要求盡量減少執(zhí)行代碼和數(shù)據(jù)所占的空間在算法上的特殊考慮
充分使用宏定義與條件編譯
運(yùn)用好位操作
I/O端口變量的定義要使用修飾符volatile
編制中斷服務(wù)程序是要注意有時(shí)要使用可重入函數(shù)
4.1.2嵌入式系統(tǒng)C語(yǔ)言程序設(shè)計(jì)考慮的問(wèn)題
字符型最基本數(shù)據(jù)類型整型
浮點(diǎn)型盡量少用盡可能使用4.2數(shù)據(jù)類型整型常量的表達(dá)(1)十六進(jìn)制數(shù)需在數(shù)字前加前綴0x(2)二進(jìn)制數(shù)需轉(zhuǎn)換成十六進(jìn)制數(shù)表示2.I/O端口的變量一般要使用易變性修飾符volatile(含義為易變的)修飾使用volatile的修飾符定義的變量,表示對(duì)它的訪問(wèn)不能采用緩存,不能將對(duì)幾次順序的訪問(wèn)優(yōu)化為一次訪問(wèn)。使用Volatil修飾的變量能反映I/O端口的實(shí)時(shí)變化。4.3常量與變量代碼1:voidmain(void){int*a=0x58000000//定義I/O端口
*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平
}程序的執(zhí)行結(jié)果I/O端口保持為0
例:比較有無(wú)volatile修飾的變量的差異
代碼2:voidmain(void){volatileint*a=0x0x5800000050000000//定義I/O端口
*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平}程序的執(zhí)行結(jié)果為I/O端口先輸出為0,然后輸出為1,最后再輸出為0,即輸出一個(gè)脈沖預(yù)處理指令:文件包含預(yù)處理指令宏定義預(yù)處理指令條件編譯預(yù)處理指令#pragma4.4預(yù)處理指令1宏定義宏定義:用一個(gè)指定的標(biāo)識(shí)符來(lái)代表一個(gè)數(shù)據(jù)或字符串。#define標(biāo)識(shí)符數(shù)據(jù)(或字符串)例1:#definePI3.1415926其作用是PI定義后在程序中的PI代替數(shù)據(jù)1。例2:#defineU8unsignedchar,其作用是定義后在程序中的U8都用unsignedchar代替宏定義的基本思想是:一次定義,多次使用其優(yōu)點(diǎn)是:可以用標(biāo)識(shí)符來(lái)代替長(zhǎng)的數(shù)據(jù),減少需要輸入的數(shù)據(jù)或字符串;用易于理解的標(biāo)識(shí)符來(lái)代替那些不太好記的具體的數(shù)據(jù),便于程序的理解和維護(hù);有利于程序的修改和升級(jí),當(dāng)這個(gè)數(shù)據(jù)需要修改時(shí),只需改動(dòng)宏定義之處即可。其作用類似于匯編中的偽指令EQU還可以用指定的標(biāo)識(shí)符來(lái)代表一個(gè)內(nèi)存單元的數(shù)#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)地址定義后,程序中rUTRSTAT0代表(0x50000010)中的數(shù)RAM中的I/O寄存器標(biāo)識(shí)符while(!(rUTRSTAT0&0x1));例:#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)……(0x50000010)中的數(shù)與1與后取反作為循環(huán)判斷的條件也可以進(jìn)行帶參數(shù)的宏定義。#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)形式參數(shù)程序中宏調(diào)用WrUTXH0(0xa)的功能為:(0x50000020)=0xa數(shù)據(jù)類型地址#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)……WrUTXH0(0xa)帶參數(shù)的宏RAM中的I/O寄存器#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)也可以進(jìn)行帶返回?cái)?shù)據(jù)的宏定義。帶返回?cái)?shù)據(jù)的宏地址#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)……*Revdata=RdURXH0();程序中宏調(diào)用*Revdata=RdURXH0()的功能為:將(0x50000024)中的數(shù)據(jù)送到*
Revdata中RAM中的I/O寄存器#defineTRUE 1#definerUTRSTAT1(*(volatileunsignedchar*)0x50004010)#defineWrUTXH1(ch) (*(volatileunsignedchar*)0x50004020)=(unsignedchar)(ch)#defineRdURXH1() (*(volatileunsignedchar*)0x50004024)練習(xí):嵌入式C語(yǔ)言編程經(jīng)常用到位操作運(yùn)算:& 與操作;例:x=rUTRSTAT0&0x4
| 或操作;例:x=x|0xf
y=PRSCVL|ADCCON^ 異或操作;例:a=a^a~
取反操作;例:c=~ c>> 右移操作;例:d=8>>3<< 左移操作;例:r=0x1<<15
PRSCVL=49<<6
4.5位運(yùn)算#defineADCCON_FLAG(0x1<<15)#defineADCCON_ENABLE_START_BYREAD (0x1<<1)#definePRSCVL(49<<6)#defineADCCON_ENABLE_START(0x1)#defineSTDBM(0x0<<2)#definePRSCEN(0x1<<14)練習(xí):子函數(shù)聲明main()
{
……
函數(shù)調(diào)用
……
}子函數(shù)定義{
……}聲明該函數(shù)使用該函數(shù)定義函數(shù)方式一先聲明主函數(shù)后定義4.6函數(shù)的程序結(jié)構(gòu)
函數(shù)定義{……
}main()
{
……
函數(shù)調(diào)用
……
}定義函數(shù)使用該函數(shù)方式二先定義主函數(shù)直接調(diào)用/*********************************************\ Copyright(c)2004-2007Zhangming@,Allrightsreserved. byZhangming2004.5.12----------------------程序功能---------------------------------串口通信Cmain函數(shù)----------------------創(chuàng)建與修正時(shí)間----------------------- 2004-5-12 創(chuàng)建2005-1-10修正*********************************************/4.7嵌入式系統(tǒng)C語(yǔ)言應(yīng)用程序的結(jié)構(gòu)#include<string.h>#include<stdio.h>#defineU8unsignedchar#defineTRUE 1#defineFALSE 0#pragmaimport(_use_no_semihosting_swi)//不使用軟中斷
/**********串口自發(fā)自收通信主函數(shù)***********/#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)//#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)//#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)//voidUart_SendByten(int,U8);charUart_Getchn(char*Revdata,intUartnum,inttimeout);voidARMTargetInit(void);voidhudelay(inttime);/*******主函數(shù)********/intmain(void){charc1[1];charerr;ARMTargetInit();//目標(biāo)板初始化
while(1){Uart_SendByten(0,0xa);//向串口0發(fā)送“換行”符Uart_SendByten(0,0xd);//向串口0發(fā)送“回車”符err=Uart_Getchn(c1,0,0);//串口從超級(jí)終端接收數(shù)據(jù)Uart_SendByten(0,c1[0]);//串口向超級(jí)終端發(fā)送數(shù)據(jù)}}
/*****串口0向發(fā)送數(shù)據(jù)子函數(shù)*******/voidUart_SendByten(intUartnum,U8data){ while(!(rUTRSTAT0&0x4));// hudelay(10);//延時(shí) WrUTXH0(data);//}
/******串口0接收數(shù)據(jù)子函數(shù)*****/charUart_Getchn(char*Revdata,intUartnum,inttimeout){ while(!(rUTRSTAT0&0x1));// *Revdata=RdURXH0();// returnTRUE;//串口0接收數(shù)據(jù)成功返回}
4.8嵌入式C語(yǔ)言程序設(shè)計(jì)技巧4.8.1變量定義4.8.2參數(shù)傳遞4.8.3循環(huán)條件4.8.1變量定義
在變量聲明的時(shí)候,最好把所有相同類型的變量放在一起定義,這樣可以優(yōu)化存儲(chǔ)器布局。由下例可以看出:對(duì)于局部變量類型的定義,使用short或char來(lái)定義變量并不是總能節(jié)省存儲(chǔ)空間。有時(shí)使用32位int或unsinged
int局部變量更有效率一些,如下圖所示:變量定義中,為了精簡(jiǎn)程序,程序員總是竭力避免使用冗余變量。但有時(shí)使用冗余變量可以減少存儲(chǔ)器訪問(wèn)的次數(shù)這可以提高系統(tǒng)性能。
4.8.2參數(shù)傳遞
為了使單獨(dú)編譯的C語(yǔ)言程序和匯編程序能夠互相調(diào)用,定義了統(tǒng)一的函數(shù)過(guò)程調(diào)用標(biāo)準(zhǔn)ATPCS。ATPCS定義了寄存器組中的{R0~R3}作為參數(shù)傳遞和結(jié)果返回寄存器,如果參數(shù)數(shù)目超過(guò)四個(gè),則使用堆棧進(jìn)行傳遞。內(nèi)部寄存器的訪問(wèn)速度是遠(yuǎn)遠(yuǎn)大于存儲(chǔ)器的,所以要盡量使參數(shù)傳遞在寄存器里面進(jìn)行,即應(yīng)盡量把函數(shù)的參數(shù)控制在四個(gè)以下。4.8.3循環(huán)條件
計(jì)數(shù)循環(huán)是程序中十分常用的流程控制結(jié)構(gòu),一般有以下兩種形式:for(loop=1;loop<=limit;loop++)
for(loop=limit;loop!=0;loop--)這兩種循環(huán)形式在邏輯上并沒(méi)有效率差異,但是映射到具體的體系結(jié)構(gòu)中時(shí),就產(chǎn)生了很大的不同,如下圖所示。
4.9C與匯編語(yǔ)言混合編程4.9.1ATPCS介紹4.9.2內(nèi)嵌匯編4.9.3C和ARM匯編程序間相互調(diào)用4.9.1ATPCS介紹
ATPCS(ARM-ThumbProduceCallStandard)是ARM程序和Thumb程序中子程序調(diào)用的基本規(guī)則,目的是為了使單獨(dú)編譯的C語(yǔ)言程序和匯編程序之間能夠相互調(diào)用。這些基本規(guī)則包括子程序調(diào)用過(guò)程中寄存器的使用規(guī)則、數(shù)據(jù)棧的使用規(guī)則和參數(shù)的傳遞規(guī)則。
寄存器的使用規(guī)則寄存器別名特殊名使用規(guī)則R0a1
參數(shù)/結(jié)果/scratch寄存器1R1a2
參數(shù)/結(jié)果/scratch寄存器2R2a3
參數(shù)/結(jié)果/scratch寄存器3R3a4
參數(shù)/結(jié)果/scratch寄存器4R4v1
ARM狀態(tài)局部變量寄存器1R5v2
ARM狀態(tài)局部變量寄存器2R6v3
ARM狀態(tài)局部變量寄存器3R7v4wrARM狀態(tài)局部變量寄存器4Thumb狀態(tài)工作寄存器R8v5
ARM狀態(tài)局部變量寄存器5R9v6sbARM狀態(tài)局部變量寄存器6,在支持RWPI的ATPCS中為靜態(tài)基址寄存器R10v7slARM狀態(tài)局部變量寄存器7,在支持?jǐn)?shù)據(jù)棧檢查的ATPCS中為數(shù)據(jù)棧限制指針R11v8fpARM狀態(tài)局部變量寄存器8/幀指針R12
ip子程序內(nèi)部調(diào)用的scratch寄存器R13
sp數(shù)據(jù)棧指針R14
lr連接寄存器R15
pc程序計(jì)數(shù)器數(shù)據(jù)棧的使用規(guī)則根據(jù)堆棧指針指向位置的不同和增長(zhǎng)方向的不同可以分為以下4種數(shù)據(jù)棧:
FD(FullDescending)
滿遞減
ED(EmptyDescending)空遞減
FA(FullAscending)
滿遞增
EA(EmptyAscending)
空遞增ATPCS規(guī)定數(shù)據(jù)棧為FD(滿遞減)類型,并且對(duì)數(shù)據(jù)棧的操作是8字節(jié)對(duì)齊的。
參數(shù)的傳遞規(guī)則參數(shù)個(gè)數(shù)固定的子程序參數(shù)傳遞規(guī)則:第一個(gè)整數(shù)參數(shù),通過(guò)寄存器R0~R3來(lái)傳遞。其他參數(shù)通過(guò)數(shù)據(jù)棧傳遞。
參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則:當(dāng)參數(shù)不超過(guò)4個(gè)時(shí),可以使用寄存器R0~R3來(lái)傳遞參數(shù);當(dāng)參數(shù)超過(guò)4個(gè)時(shí),還可以使用數(shù)據(jù)棧來(lái)傳遞參數(shù)子程序結(jié)果返回規(guī)則
結(jié)果為一個(gè)32位的整數(shù)時(shí),可以通過(guò)寄存器R0返回;結(jié)果為一個(gè)64位整數(shù)時(shí),可以通過(guò)寄存器R0和R1返回,依次類推。
NEXT4.9.2內(nèi)嵌匯編
在C程序中嵌入?yún)R編程序可以實(shí)現(xiàn)一些高級(jí)語(yǔ)言沒(méi)有的功能,并可以提高執(zhí)行效率。內(nèi)嵌的匯編指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的變量定義,數(shù)據(jù)交換必須通過(guò)ATPCS進(jìn)行。嵌入式匯編在形式上表現(xiàn)為獨(dú)立定義的函數(shù)體。內(nèi)嵌匯編指令的語(yǔ)法格式
__asm(“指令[;指令]”);ARMC匯編器使用關(guān)鍵字“__asm"。如果有多條匯編指令需要嵌入,可以用“{}”將它們歸為一條語(yǔ)句。如:__asm{ 指令[;指令] … [指令]}需要特別注意的是__asm是兩個(gè)下劃線。
內(nèi)嵌匯編指令的應(yīng)用舉例4.9.3C和ARM匯編程序間相互調(diào)用
在C和ARM匯編程序之間相互調(diào)用必須遵守ATPCS(ARM-ThumbProcedureCallStandard)規(guī)則。C和匯編之間的相互調(diào)用可以從以下這三方面來(lái)介紹:匯編程序?qū)全局變量的訪問(wèn)在C語(yǔ)言程序中調(diào)用匯編程序在匯編程序中調(diào)用C語(yǔ)言程序匯編程序訪問(wèn)全局C變量
匯編程序可以通過(guò)地址間接訪問(wèn)在C語(yǔ)言程序中聲明的全局變量。通過(guò)使用IMPORT關(guān)鍵詞引人全局變量,并利用LDR和STR指令根據(jù)全局變量的地址可以訪問(wèn)它們。對(duì)于不同類型的變量,需要采用不同選項(xiàng)的LDR和STR指令,如下所示:
unsignedchar LDRB/STRBunsignedshort LDRH/STRHunsignedint LDR/STRchar
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- “社區(qū)創(chuàng)文明計(jì)劃”社區(qū)工作計(jì)劃
- 2025年生產(chǎn)主管年度工作計(jì)劃范文
- 幼兒園營(yíng)養(yǎng)員工作計(jì)劃幼兒園營(yíng)養(yǎng)員崗位職責(zé)
- 2025大學(xué)生創(chuàng)業(yè)計(jì)劃書(shū)范文模板大全
- 初中語(yǔ)文教研組工作計(jì)劃結(jié)尾怎么寫
- 新目標(biāo)七年級(jí)下學(xué)期的英語(yǔ)教學(xué)計(jì)劃
- 教師校本研修工作計(jì)劃范文個(gè)人校本研修工作計(jì)劃
- 小學(xué)創(chuàng)建文明學(xué)校工作計(jì)劃
- 2025房屋銷售計(jì)劃書(shū)范文類標(biāo)題提綱
- 學(xué)年度六年級(jí)健康教育教學(xué)工作計(jì)劃
- 造紙企業(yè)清潔生產(chǎn)報(bào)告2014年
- 診所抗菌藥物管理制度
- 智慧嬰幼兒托管解決方案
- 設(shè)計(jì)構(gòu)成與應(yīng)用 完整全套教學(xué)課件 第1-12章 平面構(gòu)成設(shè)計(jì)元素- 立體構(gòu)成在建筑設(shè)計(jì)中的應(yīng)用
- 2、廣東省高速公路發(fā)展股份有限公司 2019年度內(nèi)控缺陷整改臺(tái)賬
- 物業(yè)公司安全生產(chǎn)檢查表
- 室內(nèi)配套設(shè)備家具、家電及窗簾等項(xiàng)目供貨服務(wù)方案技術(shù)投標(biāo)方案
- 公司規(guī)章制度清單
- 《高效能人士的七個(gè)習(xí)慣》PPT演講模板
- 獨(dú)領(lǐng)風(fēng)騷的古代技術(shù)創(chuàng)造
- 實(shí)用俄語(yǔ)會(huì)話知到章節(jié)答案智慧樹(shù)2023年山東交通學(xué)院
評(píng)論
0/150
提交評(píng)論