天天看點

基于ADS1.2下的ARM應用開發(一)!

1.宏定義中volatile uint8

UINT8等效于unsigned   char,而volatile關鍵字主要作用是針對變量可能在編譯器控制之外被修改的情況,強制讓編譯器放棄對這個變量的優化。volatile:因為C編譯器的優化作用以及作業系統的cache等的影響,某些變量的值在記憶體中和寄存器中是不一緻的。這對單指令流程式沒有影響,但對有中斷處理函數、多線程應用等而言,會造成混亂。是以,C裡提供了volatile修飾符強制要求該變量必須從記憶體通路,也就是告訴編譯器該變量可能在任何時候被修改。

2.定義寄存器處理函數的函數宏。

帶參數的宏也被稱為"函數宏". 利用宏可以提高代碼的運作效率: 子程式的調用需要壓棧出棧, 這一過程如果過于頻繁會耗費掉大量的CPU運算資源. 是以一些代碼量小但運作頻繁的代碼如果采用帶參數宏來實作會提高代碼的運作效率.如:

#define  _CLR(REG,n) REG = REG ^ (1 << n)  //n位置0.

#define  _SET(REG,n) SET = REG | (1 << n)   //n位置1.

3.類型的強制轉換

類型的強制轉換格式上需要有括号來标定,如:

資料的轉換:unit8      data8;

float              b;

b = (float)data8;……

指針的轉換:unit8      *point8;

                     unit8      data8;

                     point8 = (unit8*)data8;……

4.extern用法

1) 基本解釋

extern可以置于變量或者函數前,以标示變量或者函數的定義在别的檔案中,提示編譯器遇到此變量和函數時在其他子產品中尋找其定義。另外,extern也可用來進行連結指定。

2 )問題:extern 變量在一個源檔案裡定義了一個數組:char a[6];在另外一個檔案裡用下列語句進行了聲明:extern char *a;請問,這樣可以嗎?

答案與分析:

(1)、不可以,程式運作時會告訴你非法通路。原因在于,指向類型T的指針并不等價于類型T的數組。extern char *a聲明的是一個指針變量而不是字元數組,是以與實際的定義不同,進而造成運作時非法通路。應該将聲明改為extern char a[ ]。

(2)、例子分析如下,如果a[] = "abcd",則外部變量a=0x61626364 (abcd的ASCII碼值),*a顯然沒有意義。顯然a指向的空間(0x61626364)沒有意義,易出現非法記憶體通路。

(3)、這提示我們,在使用extern時候要嚴格對應聲明時的格式,在實際程式設計中,這樣的錯誤屢見不鮮。

(4)、extern用在變量聲明中常常有這樣一個作用,你在*.c檔案中聲明了一個全局的變量,這個全局的變量如果要被引用,就放在*.h中并用extern來聲明。

3) 問題:extern 函數2

當函數提供方單方面修改函數原型時,如果使用方不知情繼續沿用原來的extern申明,這樣編譯時編譯器不會報錯。但是在運作過程中,因為少了或者多了輸入參數,往往會照成系統錯誤,這種情況應該如何解決?

答案與分析:

目前業界針對這種情況的處理沒有一個很完美的方案,通常的做法是提供方在自己的xxx_pub.h中提供對外部接口的聲明,然後調用方include該頭檔案,進而省去extern這一步。以避免這種錯誤。寶劍有雙鋒,對extern的應用,不同的場合應該選擇不同的做法。

4) 問題:extern “C”

在C++環境下使用C函數的時候,常常會出現編譯器無法找到obj子產品中的C函數定義,進而導緻連結失敗的情況,應該如何解決這種情況呢?

答案與分析:

C++語言在編譯的時候為了解決函數的多态問題,會将函數名和參數聯合起來生成一個中間的函數名稱,而C語言則不會,是以會造成連結時找不到對應函數的情況,此時C函數就需要用extern “C”進行連結指定,這告訴編譯器,請保持我的名稱,不要給我生成用于連結的中間函數名。

下面是一個标準的寫法:

//在.h檔案的頭上

#ifdef __cplusplus

#if __cplusplus

extern "C"{

 #endif

 #endif

 …

 …

 //.h檔案結束的地方

 #ifdef __cplusplus

 #if __cplusplus

}

#endif

#endif

5)問題:extern 函數1

常常見extern放在函數的前面成為函數聲明的一部分,那麼,C語言的關鍵字extern在函數的聲明中起什麼作用?

答案與分析:

如果函數的聲明中帶有關鍵字extern,僅僅是暗示這個函數可能在别的源檔案裡定義,沒有其它作用。即下述兩個函數聲明沒有明顯的差別:extern int f(); 和int f();當然,這樣的用處還是有的,就是在程式中取代include “*.h”來聲明函數,在一些複雜的項目中,我比較習慣在所有的函數聲明前添加extern修飾。

5.ADS開發時,注意結構體和指針的轉換!結構體可以用指針來完成,執行個體化後也可以用位址來引用!

    在嵌入式C中,我們經常用結構體來封裝一些相關的資料,這樣易于閱讀!對于指針的應用要謹慎!另外,如果能彙編,直接可以在C中嵌入彙編,利用好了,可提高程式的執行效率!

繼續閱讀