標題: 第14章 實踐項目開發(fā)-智能溫控系統(tǒng)14.1 [打印本頁]
作者: 卓然塵世間 時間: 2026-5-8 15:21
標題: 第14章 實踐項目開發(fā)-智能溫控系統(tǒng)14.1
本章首先介紹實際項目開發(fā)中的一些技巧和規(guī)范性的內(nèi)容,把一些實際開發(fā)中經(jīng)常使用的零散知識點逐一的講解,然后做一個溫控器的小項目,模擬一個空調(diào)產(chǎn)品的程序控制功能,把項目開發(fā)的整個流程都走一遍,學習一下真正的項目流程。
本章內(nèi)容非常重要,是否把本章內(nèi)容消化理解是檢驗是否能夠真正獨立開發(fā)產(chǎn)品的重要的一步。實際上復雜的內(nèi)容只是簡單內(nèi)容的堆疊,相信只要耐心認真反復學習實踐,肯定可以越過龍門,步入電子工程師的行列。
14.1復合數(shù)據(jù)類型-在前邊學數(shù)據(jù)類型的時候,主要是字符型、整型、浮點型等基本類型,而學數(shù)組的時候,數(shù)組的定義要求數(shù)組元素必須是相同的數(shù)據(jù)類型。在實際應用中,有時候還需要把不同類型的數(shù)據(jù)組成一個有機的整體來處理,這些組合在一個整體中的數(shù)據(jù)之間還有一定的聯(lián)系,比如一個學生的姓名、性別、年齡、考試成績等,這就引入了復合數(shù)據(jù)類型。復合數(shù)據(jù)類型主要包含結(jié)構(gòu)體數(shù)據(jù)類型、共用體數(shù)據(jù)類型和枚舉體數(shù)據(jù)類型。
14.1.1結(jié)構(gòu)體數(shù)據(jù)類型Kingst51開發(fā)板上的LED顯示有三部分,LED小燈、數(shù)碼管和LED點陣。LED小燈是1個字節(jié)控制;數(shù)碼管是6個字節(jié)控制;LED點陣是8個字節(jié)控制。它們都受P0口輸出控制,控制方式有相似性,可以統(tǒng)一進行動態(tài)掃描刷新;這三者又屬于獨立的LED功能顯示,要改變其顯示內(nèi)容需要單獨分別賦值。三者需要允許一起處理,也允許獨立操作。如果分別進行變量定義,一是操作容易出錯,二是比較零散,可讀性不強。
于是,就可以使用結(jié)構(gòu)體來將這一組彼此相關的數(shù)據(jù)做一個封裝,既組成了一個整體,易讀不易錯;又可以獨立單獨處理其中某一個元素,這就是結(jié)構(gòu)體數(shù)據(jù)類型。結(jié)構(gòu)體是一種構(gòu)造而成的數(shù)據(jù)類型,使用之前需要先定義它。
聲明結(jié)構(gòu)體變量的一般格式如下:
struct 結(jié)構(gòu)體名
{
類型1 變量名1;
類型2 變量名2;
……
類型n 變量名n;
} 結(jié)構(gòu)體變量名1, 結(jié)構(gòu)體變量名2, ... 結(jié)構(gòu)體變量名n;
這種聲明方式是在聲明結(jié)構(gòu)體類型的同時又用它定義了結(jié)構(gòu)體變量,此時的結(jié)構(gòu)體名是可以省略的,但如果省略后,就不能在別處再次定義這樣的結(jié)構(gòu)體變量了。這種方式把類型定義和變量定義混在了一起,降低了程序的靈活性和可讀性,因此并不建議采用這種方式,而是推薦用以下這種方式:
struct 結(jié)構(gòu)體名
{
類型1 變量名1;
類型2 變量名2;
……
類型n 變量名n;
};
struct 結(jié)構(gòu)體名 結(jié)構(gòu)體變量名1, 結(jié)構(gòu)體變量名2, ... 結(jié)構(gòu)體變量名n;
為了方便理解,首先定義一個變量unsigned char keyBuff;然后將LED小燈、LED數(shù)碼管和LED點陣,構(gòu)建一個結(jié)構(gòu)體類型。
struct sLedBuff { //LED顯示緩沖區(qū)結(jié)構(gòu)
uint8 array[8]; //點陣緩沖區(qū)
uint8 number[6]; //數(shù)碼管緩沖區(qū)
uint8 single; //獨立LED緩沖區(qū)
};
struct sLedBuff ledBuff;
struct是結(jié)構(gòu)體類型關鍵字,sLedBuff 是這個結(jié)構(gòu)體名字。一旦結(jié)構(gòu)體構(gòu)建完成,sLedBuff 起到的作用和unsigned char類似,是表達變量類型的。ledBuff和keyBuff類似,即定義了一個sLedBuff 類型的結(jié)構(gòu)體變量。如果要給結(jié)構(gòu)體變量的成員賦值的話,寫法是
ledBuff.single = 0xFF;
ledBuff.array[0] = 0xFF;
一個指針變量如果指向了一個結(jié)構(gòu)體變量的時候,稱之為結(jié)構(gòu)指針變量。結(jié)構(gòu)指針變量是指向的結(jié)構(gòu)體變量的首地址,通過結(jié)構(gòu)體指針也可以訪問到這個結(jié)構(gòu)變量。
結(jié)構(gòu)指針變量聲明的一般形式如下:
struct sLedBuff *pledBuff;
這里要特別注意的是,使用結(jié)構(gòu)體指針對結(jié)構(gòu)體成員的訪問,和使用結(jié)構(gòu)體變量名對結(jié)構(gòu)體成員的訪問,其表達式有所不同。結(jié)構(gòu)體指針對結(jié)構(gòu)體成員的訪問表達式為
pledBuff ->single= 0xFF; 或者是
(*pledBuff).single= 0xFF;
很明顯前者更簡潔,所以推薦使用前者。
14.1.2共用體數(shù)據(jù)類型共用體也稱之為聯(lián)合體,共用體定義和結(jié)構(gòu)體十分類似,使用以下形式:
union 共用體名
{
數(shù)據(jù)類型1 成員名1;
數(shù)據(jù)類型2 成員名2;
……
數(shù)據(jù)類型n 成員名n;
};
union 共用體名 共用體變量;
共用體表示的是幾個變量共用一個內(nèi)存位置,也就是成員1、成員2……成員n都用一個內(nèi)存位置。共用體成員的訪問方式和結(jié)構(gòu)體是一樣的,成員訪問的方式是:共用體名.成員名,使用指針來訪問的方式是:共用體名->成員名。
從程序安全性和可移植性角度考慮,除非用戶非常了解所使用的開發(fā)環(huán)境的實現(xiàn)細節(jié),否則使用共用體存在代碼上的隱患,所以現(xiàn)在諸多以安全為首要訴求的C語言編程規(guī)范禁止使用共用體。因此共用體不推薦使用,也不再贅述。
14.1.3枚舉數(shù)據(jù)類型在實際問題中,有些變量的取值被限定在一個有限的范圍內(nèi)。例如,一個星期從周一到周日有7天,一年從1月到12月有12個月,蜂鳴器有響和不響兩種狀態(tài)等等。如果把這些變量定義成整型或者字符型不是很合適,因為這些變量都有自己的范圍。C語言提供了一種稱為“枚舉”的類型,在枚舉類型的定義中列舉出所有可能的值,并可以為每一個值取一個形象化的名字,它的這一特性可以提高程序代碼的可讀性。
枚舉的說明形式如下:
enum 枚舉名
{
標識符1[=整型常數(shù)],
標識符2[=整型常數(shù)],
……
標識符n[=整型常數(shù)
};
enum 枚舉名 枚舉變量;
枚舉的說明形式中,如果沒有被初始化,那么“=整型常數(shù)”是可以被省略的,如果是默認值的話,從第一個標識符順序賦值0、1、2……,但是當枚舉中任何一個成員被賦值后,它后邊的成員按照依次加1的規(guī)則確定數(shù)值。
比如本章的溫控器系統(tǒng),正常工作時一共有三種狀態(tài),分別為正常工作狀態(tài),設置繼電器動作狀態(tài)和設置報警器狀態(tài)三種,可以定義一個枚舉類型,根據(jù)枚舉的定義E_NORMAL值為0,E_SET_ACT值為1,E_SET_ALARM值為2,具體應用后續(xù)有例程。
enum eStaSystem { //系統(tǒng)運行狀態(tài)枚舉
E_NORMAL, E_SET_ACT, E_SET_ALARM
};
枚舉的使用,有幾點要注意:
1、枚舉中每個成員結(jié)束符是逗號,而不是分號,最后一個成員可以省略逗號。
2、枚舉成員的初始化值可以是負數(shù),但是后邊的成員依然依次加1。
3、枚舉變量只能取枚舉結(jié)構(gòu)中的某個標識符常量,不可以在范圍之外。
作者: joyb 時間: 2026-5-9 08:23
最好經(jīng)過授權
作者: 卓然塵世間 時間: 2026-5-11 10:55
經(jīng)過授權的
| 歡迎光臨 (http://www.denmoz.com/bbs/) |
Powered by Discuz! X3.1 |