嵌入式系統第四章ARM的C語言編程技術_第1頁
嵌入式系統第四章ARM的C語言編程技術_第2頁
嵌入式系統第四章ARM的C語言編程技術_第3頁
嵌入式系統第四章ARM的C語言編程技術_第4頁
嵌入式系統第四章ARM的C語言編程技術_第5頁
已閱讀5頁,還剩50頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

4.1概述4.1.1嵌入式系統應用的編程語言匯編C目前使用的最多C++JAVA第4章ARM的C語言編程技術滿足系統的實時性要求盡量減少執行代碼和數據所占的空間在算法上的特殊考慮

充分使用宏定義與條件編譯

運用好位操作

I/O端口變量的定義要使用修飾符volatile

編制中斷服務程序是要注意有時要使用可重入函數

4.1.2嵌入式系統C語言程序設計考慮的問題

字符型最基本數據類型整型

浮點型盡量少用盡可能使用4.2數據類型整型常量的表達(1)十六進制數需在數字前加前綴0x(2)二進制數需轉換成十六進制數表示2.I/O端口的變量一般要使用易變性修飾符volatile(含義為易變的)修飾使用volatile的修飾符定義的變量,表示對它的訪問不能采用緩存,不能將對幾次順序的訪問優化為一次訪問。使用Volatil修飾的變量能反映I/O端口的實時變化。4.3常量與變量代碼1:voidmain(void){int*a=0x58000000//定義I/O端口

*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平

}程序的執行結果I/O端口保持為0

例:比較有無volatile修飾的變量的差異

代碼2:voidmain(void){volatileint*a=0x0x5800000050000000//定義I/O端口

*a=0//輸出低電平*a=1//輸出高電平*a=0//輸出低電平}程序的執行結果為I/O端口先輸出為0,然后輸出為1,最后再輸出為0,即輸出一個脈沖預處理指令:文件包含預處理指令宏定義預處理指令條件編譯預處理指令#pragma4.4預處理指令1宏定義宏定義:用一個指定的標識符來代表一個數據或字符串。#define標識符數據(或字符串)例1:#definePI3.1415926其作用是PI定義后在程序中的PI代替數據1。例2:#defineU8unsignedchar,其作用是定義后在程序中的U8都用unsignedchar代替宏定義的基本思想是:一次定義,多次使用其優點是:可以用標識符來代替長的數據,減少需要輸入的數據或字符串;用易于理解的標識符來代替那些不太好記的具體的數據,便于程序的理解和維護;有利于程序的修改和升級,當這個數據需要修改時,只需改動宏定義之處即可。其作用類似于匯編中的偽指令EQU還可以用指定的標識符來代表一個內存單元的數#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)地址定義后,程序中rUTRSTAT0代表(0x50000010)中的數RAM中的I/O寄存器標識符while(!(rUTRSTAT0&0x1));例:#definerUTRSTAT0(*(volatileunsignedchar*)0x50000010)……(0x50000010)中的數與1與后取反作為循環判斷的條件也可以進行帶參數的宏定義。#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)形式參數程序中宏調用WrUTXH0(0xa)的功能為:(0x50000020)=0xa數據類型地址#defineWrUTXH0(ch) (*(volatileunsignedchar*)0x50000020)=(unsignedchar)(ch)……WrUTXH0(0xa)帶參數的宏RAM中的I/O寄存器#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)也可以進行帶返回數據的宏定義。帶返回數據的宏地址#defineRdURXH0() (*(volatileunsignedchar*)0x50000024)……*Revdata=RdURXH0();程序中宏調用*Revdata=RdURXH0()的功能為:將(0x50000024)中的數據送到*

Revdata中RAM中的I/O寄存器#defineTRUE 1#definerUTRSTAT1(*(volatileunsignedchar*)0x50004010)#defineWrUTXH1(ch) (*(volatileunsignedchar*)0x50004020)=(unsignedchar)(ch)#defineRdURXH1() (*(volatileunsignedchar*)0x50004024)練習:嵌入式C語言編程經常用到位操作運算:& 與操作;例: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位運算#defineADCCON_FLAG(0x1<<15)#defineADCCON_ENABLE_START_BYREAD (0x1<<1)#definePRSCVL(49<<6)#defineADCCON_ENABLE_START(0x1)#defineSTDBM(0x0<<2)#definePRSCEN(0x1<<14)練習:子函數聲明main()

{

……

函數調用

……

}子函數定義{

……}聲明該函數使用該函數定義函數方式一先聲明主函數后定義4.6函數的程序結構

函數定義{……

}main()

{

……

函數調用

……

}定義函數使用該函數方式二先定義主函數直接調用/*********************************************\ Copyright(c)2004-2007Zhangming@,Allrightsreserved. byZhangming2004.5.12----------------------程序功能---------------------------------串口通信Cmain函數----------------------創建與修正時間----------------------- 2004-5-12 創建2005-1-10修正*********************************************/4.7嵌入式系統C語言應用程序的結構#include<string.h>#include<stdio.h>#defineU8unsignedchar#defineTRUE 1#defineFALSE 0#pragmaimport(_use_no_semihosting_swi)//不使用軟中斷

/**********串口自發自收通信主函數***********/#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);/*******主函數********/intmain(void){charc1[1];charerr;ARMTargetInit();//目標板初始化

while(1){Uart_SendByten(0,0xa);//向串口0發送“換行”符Uart_SendByten(0,0xd);//向串口0發送“回車”符err=Uart_Getchn(c1,0,0);//串口從超級終端接收數據Uart_SendByten(0,c1[0]);//串口向超級終端發送數據}}

/*****串口0向發送數據子函數*******/voidUart_SendByten(intUartnum,U8data){ while(!(rUTRSTAT0&0x4));// hudelay(10);//延時 WrUTXH0(data);//}

/******串口0接收數據子函數*****/charUart_Getchn(char*Revdata,intUartnum,inttimeout){ while(!(rUTRSTAT0&0x1));// *Revdata=RdURXH0();// returnTRUE;//串口0接收數據成功返回}

4.8嵌入式C語言程序設計技巧4.8.1變量定義4.8.2參數傳遞4.8.3循環條件4.8.1變量定義

在變量聲明的時候,最好把所有相同類型的變量放在一起定義,這樣可以優化存儲器布局。由下例可以看出:對于局部變量類型的定義,使用short或char來定義變量并不是總能節省存儲空間。有時使用32位int或unsinged

int局部變量更有效率一些,如下圖所示:變量定義中,為了精簡程序,程序員總是竭力避免使用冗余變量。但有時使用冗余變量可以減少存儲器訪問的次數這可以提高系統性能。

4.8.2參數傳遞

為了使單獨編譯的C語言程序和匯編程序能夠互相調用,定義了統一的函數過程調用標準ATPCS。ATPCS定義了寄存器組中的{R0~R3}作為參數傳遞和結果返回寄存器,如果參數數目超過四個,則使用堆棧進行傳遞。內部寄存器的訪問速度是遠遠大于存儲器的,所以要盡量使參數傳遞在寄存器里面進行,即應盡量把函數的參數控制在四個以下。4.8.3循環條件

計數循環是程序中十分常用的流程控制結構,一般有以下兩種形式:for(loop=1;loop<=limit;loop++)

for(loop=limit;loop!=0;loop--)這兩種循環形式在邏輯上并沒有效率差異,但是映射到具體的體系結構中時,就產生了很大的不同,如下圖所示。

4.9C與匯編語言混合編程4.9.1ATPCS介紹4.9.2內嵌匯編4.9.3C和ARM匯編程序間相互調用4.9.1ATPCS介紹

ATPCS(ARM-ThumbProduceCallStandard)是ARM程序和Thumb程序中子程序調用的基本規則,目的是為了使單獨編譯的C語言程序和匯編程序之間能夠相互調用。這些基本規則包括子程序調用過程中寄存器的使用規則、數據棧的使用規則和參數的傳遞規則。

寄存器的使用規則寄存器別名特殊名使用規則R0a1

參數/結果/scratch寄存器1R1a2

參數/結果/scratch寄存器2R2a3

參數/結果/scratch寄存器3R3a4

參數/結果/scratch寄存器4R4v1

ARM狀態局部變量寄存器1R5v2

ARM狀態局部變量寄存器2R6v3

ARM狀態局部變量寄存器3R7v4wrARM狀態局部變量寄存器4Thumb狀態工作寄存器R8v5

ARM狀態局部變量寄存器5R9v6sbARM狀態局部變量寄存器6,在支持RWPI的ATPCS中為靜態基址寄存器R10v7slARM狀態局部變量寄存器7,在支持數據棧檢查的ATPCS中為數據棧限制指針R11v8fpARM狀態局部變量寄存器8/幀指針R12

ip子程序內部調用的scratch寄存器R13

sp數據棧指針R14

lr連接寄存器R15

pc程序計數器數據棧的使用規則根據堆棧指針指向位置的不同和增長方向的不同可以分為以下4種數據棧:

FD(FullDescending)

滿遞減

ED(EmptyDescending)空遞減

FA(FullAscending)

滿遞增

EA(EmptyAscending)

空遞增ATPCS規定數據棧為FD(滿遞減)類型,并且對數據棧的操作是8字節對齊的。

參數的傳遞規則參數個數固定的子程序參數傳遞規則:第一個整數參數,通過寄存器R0~R3來傳遞。其他參數通過數據棧傳遞。

參數個數可變的子程序參數傳遞規則:當參數不超過4個時,可以使用寄存器R0~R3來傳遞參數;當參數超過4個時,還可以使用數據棧來傳遞參數子程序結果返回規則

結果為一個32位的整數時,可以通過寄存器R0返回;結果為一個64位整數時,可以通過寄存器R0和R1返回,依次類推。

NEXT4.9.2內嵌匯編

在C程序中嵌入匯編程序可以實現一些高級語言沒有的功能,并可以提高執行效率。內嵌的匯編指令包括大部分的ARM指令和Thumb指令,但是不能直接引用C的變量定義,數據交換必須通過ATPCS進行。嵌入式匯編在形式上表現為獨立定義的函數體。內嵌匯編指令的語法格式

__asm(“指令[;指令]”);ARMC匯編器使用關鍵字“__asm"。如果有多條匯編指令需要嵌入,可以用“{}”將它們歸為一條語句。如:__asm{ 指令[;指令] … [指令]}需要特別注意的是__asm是兩個下劃線。

內嵌匯編指令的應用舉例4.9.3C和ARM匯編程序間相互調用

在C和ARM匯編程序之間相互調用必須遵守ATPCS(ARM-ThumbProcedureCallStandard)規則。C和匯編之間的相互調用可以從以下這三方面來介紹:匯編程序對C全局變量的訪問在C語言程序中調用匯編程序在匯編程序中調用C語言程序匯編程序訪問全局C變量

匯編程序可以通過地址間接訪問在C語言程序中聲明的全局變量。通過使用IMPORT關鍵詞引人全局變量,并利用LDR和STR指令根據全局變量的地址可以訪問它們。對于不同類型的變量,需要采用不同選項的LDR和STR指令,如下所示:

unsignedchar LDRB/STRBunsignedshort LDRH/STRHunsignedint LDR/STRchar

溫馨提示

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

評論

0/150

提交評論