C語言在單片機(jī)設(shè)計(jì)中的應(yīng)用課件_第1頁
C語言在單片機(jī)設(shè)計(jì)中的應(yīng)用課件_第2頁
C語言在單片機(jī)設(shè)計(jì)中的應(yīng)用課件_第3頁
C語言在單片機(jī)設(shè)計(jì)中的應(yīng)用課件_第4頁
C語言在單片機(jī)設(shè)計(jì)中的應(yīng)用課件_第5頁
已閱讀5頁,還剩90頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

高級(jí)語言在單片機(jī)設(shè)計(jì)中的應(yīng)用C語言程序設(shè)計(jì)及基本技巧高級(jí)語言在單片機(jī)設(shè)計(jì)中的應(yīng)用C語言程序設(shè)計(jì)及基本技巧1箴言程序設(shè)計(jì)絕對(duì)是一門藝術(shù),而不僅僅是一門技術(shù)我們的工作應(yīng)該不僅僅是把當(dāng)前已有的功能實(shí)現(xiàn)而已,在程序設(shè)計(jì)期間要為以后的擴(kuò)展和維護(hù)做好鋪墊(這也許是目前很多工程師所忽略的)程序設(shè)計(jì)的出發(fā)點(diǎn)是,是給別人看,可讀、易理解、好維護(hù),如果你的程序只能自己來維護(hù),到你離開這個(gè)程序時(shí),你的程序也就與你一起離開了這個(gè)世界為了可讀、易理解、好維護(hù),你的程序要有好的設(shè)計(jì),而不是一接手就進(jìn)行東抄抄、西抄抄的寫代碼工作箴言程序設(shè)計(jì)絕對(duì)是一門藝術(shù),而不僅僅是一門技術(shù)2C語言的發(fā)展簡(jiǎn)史和特點(diǎn)

1.C語言的誕生與發(fā)展(1)在C語言誕生以前,系統(tǒng)軟件主要是用匯編語言編寫的。由于匯編語言程序依賴于計(jì)算機(jī)硬件,其可讀性和可移植性都很差;但一般的高級(jí)語言又難以實(shí)現(xiàn)對(duì)計(jì)算機(jī)硬件的直接操作(這正是匯編語言的優(yōu)勢(shì)),于是人們盼望有一種兼有匯編語言和高級(jí)語言特性的新語言。(2)C語言是貝爾實(shí)驗(yàn)室于70年代初研制出來的,后來又被多次改進(jìn),并出現(xiàn)了多種版本。80年代初,美國(guó)國(guó)家標(biāo)準(zhǔn)化協(xié)會(huì)(ANSI),根據(jù)C語言問世以來各種版本對(duì)C語言的發(fā)展和擴(kuò)充,制定了ANSIC標(biāo)準(zhǔn)(1989年再次做了修訂)。(3)與單片機(jī)有關(guān)的C編譯器基本上都是以ANSI

C為標(biāo)準(zhǔn)的,但都會(huì)有些許的不同,比如在對(duì)位定義的處理上,中斷的處理上等。C語言的發(fā)展簡(jiǎn)史和特點(diǎn)1.C語言的誕生與發(fā)展3如何成為一個(gè)優(yōu)秀的軟件工程師會(huì)哪種語言不重要,重要的是如何將客戶的零散無序的需求,迅速消化理解成程序邏輯,然后用自己熟悉的語言將其實(shí)現(xiàn)沒有哪一個(gè)語言比其他語言更高級(jí),我們需要的是高效(包括成本和開發(fā)周期考慮)的工具沒有沒有BUG的軟件,沒有最優(yōu)化的軟件精通語言不等于是一個(gè)好的軟件開發(fā)人員最重要的,學(xué)習(xí)和總結(jié)的能力邏輯分析能力如何成為一個(gè)優(yōu)秀的軟件工程師會(huì)哪種語言不重要,重要的是如何將4一個(gè)好的軟件開發(fā)人員應(yīng)該具備哪些基本素質(zhì)1牢固掌握計(jì)算機(jī)軟件的基本知識(shí)技能;2善于分析和綜合問題,具有嚴(yán)密的邏輯思維能力;3工作踏實(shí)細(xì)致,遵循標(biāo)準(zhǔn)和規(guī)范,具有嚴(yán)格的科學(xué)作風(fēng);4工作有耐心、有毅力、有責(zé)任心;5善于聽取別人的意見,善于與周圍人員團(tuán)結(jié)協(xié)作,建立良好的人際關(guān)系;6具有良好的書面和口頭表達(dá)能力。一個(gè)好的軟件開發(fā)人員應(yīng)該具備哪些基本素質(zhì)1牢固掌握計(jì)算機(jī)軟5邏輯分析能力訓(xùn)練對(duì)于事業(yè)部的人來說控制板就相當(dāng)于黑匣子,只需要正確的結(jié)果,他們不會(huì)關(guān)心具體的實(shí)現(xiàn)方法而對(duì)于編程來說,需要將各個(gè)輸入細(xì)化,最后給出一個(gè)輸出,需要細(xì)心,考慮周全邏輯分析能力訓(xùn)練對(duì)于事業(yè)部的人來說控制板就相當(dāng)于黑匣子,只需6拿到項(xiàng)目后馬上就開始寫代碼嗎?不,首先分析流程熟悉系統(tǒng)可做到事半功倍事業(yè)部的產(chǎn)品需要擴(kuò)展,同樣我們的軟件也不會(huì)只使用一次,只有把系統(tǒng)了解透徹,才可以將變量和過程定義的更加合理,這就是所謂的擴(kuò)展性好很多的算法沒有最好一說,只能說更適合這個(gè)系統(tǒng)拿到項(xiàng)目后馬上就開始寫代碼嗎?不,首先分析流程熟悉系統(tǒng)可做到7C語言優(yōu)點(diǎn)代碼簡(jiǎn)練,可讀性好易于合作:1+1>2(Microsoft)可移植性(硬件無關(guān)性):模塊代碼可以很容易嵌入至任意一個(gè)系統(tǒng)易于模塊化:函數(shù)有輸入輸出的存在浮點(diǎn)數(shù)與長(zhǎng)整型數(shù)已經(jīng)由編譯器處理位操作雖然繁瑣,但好的編譯器可以勝任需要速度快的地方可嵌入?yún)R編語言趨勢(shì):編譯器也在升級(jí),芯片廠商都在推出更快的支持C語言的芯片(Toshiba,ST)不需掌握每種匯編語言,將更多經(jīng)歷集中程序流程和算法中站在巨人的肩膀上C語言優(yōu)點(diǎn)代碼簡(jiǎn)練,可讀性好8舉例:可讀性好C語言:If((a==b)&&(c==d)) e=f;對(duì)應(yīng)匯編:CMPA,BJRZ,_STEP1…_STEP1:LDA,CLDB,DCMPA,BJRZ,_STEP2…_STEP2:LDE,F舉例:可讀性好C語言:If((a==b)&&(c9舉例:硬件無關(guān)性與硬件有關(guān)的全部做成一個(gè)文件通常IO口操作可以調(diào)用與硬件有關(guān)的函數(shù)

main() { … f_MCU_InitSfr(); f_MCU_DspLamp(); a=f_MCU_ChkKey(1); }中斷操作可調(diào)用主文件中的相應(yīng)函數(shù)或直接指向主文件中的中斷函數(shù)__interruptf_MCU_Int_1s(void){

TCCS_IVF=0; f_Int_1s();}舉例:硬件無關(guān)性與硬件有關(guān)的全部做成一個(gè)文件10如何選擇使用匯編或C語言程序量大小原則:建議4K以下匯編,以上用C語言與算法有關(guān)性:使用某種算法的用C,不需要算法的簡(jiǎn)單流程使用匯編是否使用浮點(diǎn)數(shù)或長(zhǎng)整型C語言編譯器是否穩(wěn)定:當(dāng)前16位機(jī)C語言編譯器都比較穩(wěn)定,8位機(jī)有待提高可擴(kuò)展性與可移植性考慮如何選擇使用匯編或C語言程序量大小原則:建議4K以下匯編,以11最簡(jiǎn)單的C程序當(dāng)前芯片廠商都會(huì)有集成開發(fā)環(huán)境IDE,包括了工程的管理和代碼的編譯連接在生成工程時(shí)會(huì)有一些與所用芯片有關(guān)的代碼,先不要更改找到某個(gè)LED輸出端口的定義,如p1_2將此端口設(shè)置為輸出端口點(diǎn)亮LED燈main(){while(1){pd1_2=1;P1_2=1;}}最簡(jiǎn)單的C程序當(dāng)前芯片廠商都會(huì)有集成開發(fā)環(huán)境IDE,包括了12加入時(shí)間中斷的C程序找到定義中斷的地方,加入時(shí)間中斷定義計(jì)算時(shí)間中斷計(jì)數(shù)器,打開時(shí)間中斷,編寫中斷函數(shù):輸出燈閃爍main(void){

trbmr=0x10; //時(shí)間中斷模式,f8 trbpre=0x00; trbpr=100-1; //500ms trbic=0x06; tstart_trbcr=1; //啟動(dòng)定時(shí)器}#pragmainterrupt _timer_rb(vect=24)void_timer_rb(void){p1_2=1–p1_2; //slpash}加入時(shí)間中斷的C程序找到定義中斷的地方,加入時(shí)間中斷定義13加入外部中斷的C程序找到定義中斷的地方,加入外部中斷定義//int1 (softwareint25)//#pragmainterrupt _int1(vect=25)//void_int1(void){}打開外部中斷使能

int1en=1;編寫外部中斷程序#pragmainterrupt _int1(vect=25)void_int1(void){ nPulseCnt++;}加入外部中斷的C程序找到定義中斷的地方,加入外部中斷定義14C語言的特點(diǎn)1語言簡(jiǎn)潔、緊湊,使用方便、靈活2運(yùn)算符豐富3數(shù)據(jù)結(jié)構(gòu)豐富4具有結(jié)構(gòu)化的控制語句5程序設(shè)計(jì)自由度大6允許直接訪問物理地址7程序執(zhí)行效率高8可移植性好C語言的特點(diǎn)1語言簡(jiǎn)潔、緊湊,使用方便、靈活15結(jié)構(gòu)特點(diǎn)函數(shù)與主函數(shù)程序由一個(gè)或多個(gè)函數(shù)組成必須有且只能有一個(gè)主函數(shù)main()程序執(zhí)行從main開始,在main中結(jié)束,其它函數(shù)通過嵌套調(diào)用得以執(zhí)行。程序語句C程序由語句組成用“;”作為語句終止符注釋/**/為注釋,不能嵌套,C99之后可以用//注釋不產(chǎn)生編譯代碼,老編譯器編譯時(shí)會(huì)選擇注釋消失,但ANSI

C確認(rèn)用空白代替編譯預(yù)處理命令:預(yù)處理命令不占用ROM空間#ifdefDEBUG#else#endif結(jié)構(gòu)特點(diǎn)編譯預(yù)處理命令:預(yù)處理命令不占用ROM空間16數(shù)據(jù)類型C數(shù)據(jù)類型基本類型構(gòu)造類型指針類型空類型void定義類型typedef數(shù)值類型字符類型char枚舉類型enum整型浮點(diǎn)型單精度型float雙精度型double字節(jié)型char長(zhǎng)整型long整型int數(shù)組結(jié)構(gòu)體struct共用體union數(shù)據(jù)類型C基本類型構(gòu)造類型指針類型空類型void定義類型ty17占用內(nèi)存字節(jié)數(shù)因內(nèi)存有限,我們使用的單片機(jī)中最常使用的是unsignedchar和unsignedint類型占用內(nèi)存字節(jié)數(shù)因內(nèi)存有限,我們使用的單片機(jī)中最常使用的是un18注意變量的自動(dòng)類型轉(zhuǎn)換變量都是有類型的,使用變量特別要注意它的類型。如下面的處理合適嗎? 例1inti=30; charc; c=i;例2還是上面的例子,下面處理還有問題嗎?

c=(char)i;注意變量的自動(dòng)類型轉(zhuǎn)換變量都是有類型的,使用變量特別要注意它19C程序的結(jié)構(gòu)

C程序源程序文件1源程序文件2……源程序文件n預(yù)處理命令定義全局變量函數(shù)1……函數(shù)n函數(shù)首部函數(shù)體定義局部變量執(zhí)行語句C程序的結(jié)構(gòu)20C語言的源程序要經(jīng)過編譯、連接以后,生成可執(zhí)行文件,程序才能運(yùn)行。其過程為:源程序擴(kuò)展的源程序目標(biāo)文件可執(zhí)行文件頭文件庫(kù)函數(shù)預(yù)處理句型語法分析連接編譯.c.obj.exe編譯執(zhí)行or解釋執(zhí)行?C語言的源程序要經(jīng)過編譯、連接以后,生成可執(zhí)行文件,程序才能21C語言編譯與連接過程1、源文件.c和.h文件稱為源文件,適合多人協(xié)作2、編譯過程和目標(biāo)文件.o或.obj文件為編譯后的文件編譯時(shí)只檢查語法錯(cuò)誤,不分配內(nèi)存地址對(duì)調(diào)用的外部函數(shù)只要有聲明即可3、連接過程將編譯后的.o或.obj文件連接成一個(gè)可以燒寫的文件為RAM和ROM分配地址空間,超過則報(bào)錯(cuò)連接時(shí)可能需要第三方函數(shù)庫(kù)無外部函數(shù)的實(shí)現(xiàn)則報(bào)錯(cuò)C語言編譯與連接過程1、源文件22編程四步驟源文件的編輯:選擇合適的編輯器

編譯源文件:一般使用單片機(jī)廠家提供的編譯器,第三方的通常收費(fèi)。比較成功的第三方編譯器:GCC,IAR

計(jì)算機(jī)把C的源程序翻譯成計(jì)算機(jī)可以識(shí)別的二進(jìn)制形式的目標(biāo)代碼文件,這個(gè)過程稱為編譯,它由C的編譯器的程序完成C的編譯程序在編譯的同時(shí),還對(duì)源程序的語法和程序的邏輯結(jié)構(gòu)等進(jìn)行檢查。當(dāng)發(fā)現(xiàn)錯(cuò)誤時(shí),將會(huì)列出錯(cuò)誤的位置和種類,此時(shí)需要重新編輯修改源程序。如果編輯成功則生成目標(biāo)文件,該文件包含了與源文件語句對(duì)應(yīng)的機(jī)器語言指令,文件名同源程序文件名,擴(kuò)展名為“.obj”。編譯生成的目標(biāo)文件,不包含程序運(yùn)行所需要的庫(kù)函數(shù)等,計(jì)算機(jī)仍然不能直接執(zhí)行。這時(shí)不檢測(cè)外部函數(shù)是否存在連接連接程序以將目標(biāo)程序和其它目標(biāo)程序模塊,以及系統(tǒng)提供的C庫(kù)函數(shù)等進(jìn)行連接生成可執(zhí)行文件的過程,稱為“連接”。連接生成的可執(zhí)行文件的文件名同源程序文件名,擴(kuò)展名為“.hex”,在計(jì)算機(jī)上則為”.exe”。

連接生成的可執(zhí)行文件,計(jì)算機(jī)可以直接執(zhí)行。編程四步驟源文件的編輯:選擇合適的編輯器23模塊化設(shè)計(jì)思想概述模塊化程序設(shè)計(jì)基本思想:將一個(gè)大的程序按功能分割成一些小模塊,特點(diǎn):各模塊相對(duì)獨(dú)立、功能單一、結(jié)構(gòu)清晰、接口簡(jiǎn)單控制了程序設(shè)計(jì)的復(fù)雜性提高元件的可靠性縮短開發(fā)周期避免程序開發(fā)的重復(fù)勞動(dòng)易于維護(hù)和功能擴(kuò)充開發(fā)方法:自上向下,逐步分解,分而治之模塊化設(shè)計(jì)思想概述24為什么程序需要模塊化做到硬件無關(guān),可移植性好黑匣子,除接口外,如何實(shí)現(xiàn)與外界無關(guān),提高開發(fā)效率可以將不同功能的模塊設(shè)計(jì)成小耦合度模塊,使程序執(zhí)行出錯(cuò)率降低,提高程序可靠性可以大為提高源代碼的復(fù)用率,降低代碼占有空間,提高程序可靠性可以提高了程序的可維修性,延長(zhǎng)了程序生命周期對(duì)于軟硬結(jié)合的系統(tǒng)來說,軟件性能和可靠性的提高,無疑也提升了系統(tǒng)的性能和可靠性。雖然,對(duì)于特定硬件來說,執(zhí)行功能是一樣的。但從系統(tǒng)角度看,仍然有其積極意義為什么程序需要模塊化做到硬件無關(guān),可移植性好25如何才算做到好的模塊化程序結(jié)構(gòu)上,就像積木一樣,到處都可調(diào)整的,很多東西不是寫“死”的,很多可重復(fù)利用,程序模塊間相互關(guān)系可調(diào)整,需求變動(dòng)后,程序修改成本低的抽象點(diǎn):高內(nèi)聚,低耦合(這個(gè)口號(hào)很響)簡(jiǎn)單點(diǎn):老大們提要求用了幾分鐘甚至幾小時(shí)和你扯,你回去找到改幾行就ok了。一般就是指這樣的程序,偷懶系程序員的理想人很難正確預(yù)料將來,所以一開始就“盡可能的多想”,往往會(huì)造成不必要的復(fù)雜度;與其一開始就“務(wù)求完美”,不若一開始時(shí)只用最簡(jiǎn)單的思想,遭遇變化之后再改成靈活應(yīng)對(duì)的方案。

摘自

----《敏捷軟件開發(fā)》。如何才算做到好的模塊化程序結(jié)構(gòu)上,就像積木一樣,到處都可調(diào)整26模塊分解的指導(dǎo)思想(1)如果一個(gè)程序段被很多模塊所公用,則它應(yīng)是一個(gè)獨(dú)立的模塊。(2)如果若干個(gè)程序段處理的數(shù)據(jù)是公用的,則這些程序段應(yīng)放在一個(gè)模塊中。(3)若兩個(gè)程序段的利用率差別很大,則應(yīng)分屬于兩個(gè)模塊。(4)一個(gè)模塊既不能過大,也不能過小。過大則模塊的通用性較差,過小則會(huì)造成時(shí)間和空間上的浪費(fèi)。

(5)力求使模塊具有通用性,通用性越強(qiáng)的模塊利用性越高。

(6)各模塊間應(yīng)在功能上,邏輯上相互獨(dú)立,盡量截然分開,特別應(yīng)避免用轉(zhuǎn)移語句的模塊間轉(zhuǎn)來轉(zhuǎn)去。

(7)各模塊間的接口應(yīng)該簡(jiǎn)單,要盡量減少公共符號(hào)的個(gè)數(shù),盡量不用共用數(shù)據(jù)存儲(chǔ)單元,在結(jié)構(gòu)或編排上有聯(lián)系的數(shù)據(jù)應(yīng)放

在一個(gè)模塊中,以免相互影響,造成查錯(cuò)困難。

(8)每個(gè)模塊的結(jié)構(gòu)應(yīng)盡量設(shè)計(jì)成單入口,單出口的形式。這樣的程序便于調(diào)試,閱讀和理解且可靠性高。模塊分解的指導(dǎo)思想(1)如果一個(gè)程序段被很多模塊所公用,則27模塊(文件)的劃分原則這是程序設(shè)計(jì)的第一步,會(huì)影響到整個(gè)代碼的移植和效率問題,因此請(qǐng)不要怕浪費(fèi)時(shí)間一般按功能來劃分各個(gè)模塊(文件),如按鍵檢測(cè),步進(jìn)電機(jī)驅(qū)動(dòng),風(fēng)機(jī)驅(qū)動(dòng),液晶驅(qū)動(dòng),蜂鳴器驅(qū)動(dòng)等等盡量將模塊黑匣子化:只需要知道其輸入輸出,而不用知道其實(shí)現(xiàn)方法盡量不使用全局變量:使用返回值或指針來完成功能模塊(文件)的劃分原則這是程序設(shè)計(jì)的第一步,會(huì)影響到整個(gè)代28模塊(文件)的劃分原則為提高可移植性,模塊的內(nèi)容盡量與硬件無關(guān),或使用外部函數(shù)來獲取與硬件有關(guān)的內(nèi)容如溫度檢測(cè)模塊:模塊內(nèi)容只關(guān)注檢測(cè)溫度的AD值所對(duì)應(yīng)的具體溫度值,及濾波算法,至于如何獲得AD值則由其他文件完成,這樣在移植到另一芯片時(shí)此文件則不用更改主文件負(fù)責(zé)整體流程和各個(gè)模塊間的調(diào)用盡量不要有交叉調(diào)用發(fā)生模塊(文件)的劃分原則為提高可移植性,模塊的內(nèi)容盡量與硬件29規(guī)范這是保證代碼可讀性的重要部分,如果沒有規(guī)范,每人能保證永遠(yuǎn)記得住當(dāng)時(shí)為什么取這樣一個(gè)變量名的含義為資源共享、可讀性與可移植性,需要一定的規(guī)范一般由公司來規(guī)定,但好的規(guī)范可以使使用者自己受益匪淺命名規(guī)范:注釋規(guī)范:編程規(guī)范:模塊劃分:規(guī)范這是保證代碼可讀性的重要部分,如果沒有規(guī)范,每人能保證永30命名規(guī)范通則程序中變量名稱=變量的前綴+代表變量含意的英文單詞或單詞縮寫+后綴;為方便閱讀,英文單詞建議不多于3個(gè)應(yīng)使用標(biāo)準(zhǔn)的英文單詞或縮寫;所有命名都應(yīng)遵循達(dá)意原則,即名稱應(yīng)含義清晰、明確;所有命名都不易過長(zhǎng),變量名應(yīng)小于等于20字符,函數(shù)名和文件名應(yīng)小于等于30字符;當(dāng)名稱由多個(gè)單詞構(gòu)成時(shí),每一個(gè)單詞的第一個(gè)字母必須大寫;宏定義要求全部大寫。命名規(guī)范通則31文件名命名規(guī)范(建議)與硬件有關(guān)的文件:產(chǎn)品類型+產(chǎn)品型號(hào)+MCU廠家+MCU型號(hào);通用函數(shù)文件:原則上以能說明此文件主要功能為宜,如RTC_HT1381.c表示文件命名不區(qū)分大小寫,建議每個(gè)的單詞的第一個(gè)字母大寫,廠家縮寫大寫文件名命名規(guī)范(建議)與硬件有關(guān)的文件:產(chǎn)品類型+產(chǎn)品型號(hào)+32函數(shù)名命名規(guī)范模塊是實(shí)現(xiàn)不同功能的子程序,其以“f_”做為前綴,后面接模塊功能名稱。建議模塊功能以“動(dòng)-名”結(jié)構(gòu)排列,即動(dòng)詞在前,名詞在后,來表示處理某個(gè)事件。函數(shù)名應(yīng)清晰反映函數(shù)的功能、用途,不能引起歧異。與硬件有關(guān)的函數(shù)名以“f_MCU_”作為前綴中斷函數(shù)以“f_Int_”作為前綴函數(shù)名命名規(guī)范模塊是實(shí)現(xiàn)不同功能的子程序,其以“f_”做為前33變量名命名規(guī)范原則上,變量名的命名遵從匈牙利記法。即:前綴+類型+變量名unsignedcharnSecondCnt; //秒級(jí)計(jì)數(shù)器變量名最長(zhǎng)不得超過20個(gè)字符。類型縮寫(type)bool bunsignedchar,BYTE nWORD,int,long n,lpointer ptype t class c 建議使用結(jié)構(gòu)來定義有關(guān)的變量與高級(jí)語言命名中的區(qū)別變量名命名規(guī)范原則上,變量名的命名遵從匈牙利記法。即:前綴34注釋規(guī)范總體原則采用中文注釋;如果某個(gè)模塊或某個(gè)復(fù)合語句在5分鐘內(nèi)仍不能被其他編程人員看明白,則說明此處的注釋是不成功的;注釋內(nèi)容應(yīng)簡(jiǎn)煉、清楚、明了;保持注釋與代碼完全一致,錯(cuò)誤的注釋還不如沒有注釋;每個(gè)源程序文件,都有文件注釋每個(gè)函數(shù)(模塊),都有函數(shù)頭注釋常量定義(DEFINE)有相應(yīng)說明;注釋規(guī)范總體原則35文件注釋內(nèi)容文件注釋內(nèi)容放在文件的最上端;文件注釋需包含以下內(nèi)容:文件名稱、版權(quán)、包含文件、作者名稱、修改時(shí)間、文件功能簡(jiǎn)介、使用芯片等,復(fù)雜的算法需要加上流程說明;文件結(jié)尾注釋一律為:/**(c)達(dá)峰科技有限公司*****ENDOFFILE**/文件注釋內(nèi)容文件注釋內(nèi)容放在文件的最上端;36舉例/*=================================*文件名:SOLARMain.c*版權(quán):達(dá)峰科技有限公司*功能描述:主程序*芯片名稱:STM8105K4*包含文件:SOLARMain.h*編譯器:STVisualDevelop*修改日期 修改人 修改說明*2010-06-08 徐風(fēng)飛

===============================*/舉例/*=========================37程序中的注釋內(nèi)容對(duì)于基本數(shù)據(jù)類型,聲明在一行內(nèi)完成;unsignedcharnSecCnt; /*秒級(jí)計(jì)數(shù)器*/unsignedcharn1msCnt; /*毫秒級(jí)計(jì)數(shù)器*/一目了然的語句不加注釋;算法語句需要添加注釋來解釋算法的實(shí)現(xiàn)方法;處理過程的每個(gè)階段都有相關(guān)注釋說明;空行和空白字符也是一種特殊注釋,具體見下一節(jié)《編程風(fēng)格》。程序中的注釋內(nèi)容對(duì)于基本數(shù)據(jù)類型,聲明在一行內(nèi)完成;38結(jié)構(gòu)體與共用體數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)存儲(chǔ)、組織數(shù)據(jù)的方式。數(shù)據(jù)結(jié)構(gòu)是指相互之間存在一種或多種特定關(guān)系的數(shù)據(jù)元素的集合。通常情況下,精心選擇的數(shù)據(jù)結(jié)構(gòu)可以帶來更高的運(yùn)行或者存儲(chǔ)效率的算法。數(shù)據(jù)結(jié)構(gòu)往往同高效的檢索算法和索引技術(shù)有關(guān)。數(shù)據(jù)結(jié)構(gòu)在計(jì)算機(jī)科學(xué)界至今沒有標(biāo)準(zhǔn)的定義。個(gè)人根據(jù)各自的理解而有不同的表述方法。結(jié)構(gòu)體可以用來表示數(shù)據(jù)結(jié)構(gòu)結(jié)構(gòu)體與共用體數(shù)據(jù)結(jié)構(gòu)是計(jì)算機(jī)存儲(chǔ)、組織數(shù)據(jù)的方式。數(shù)據(jù)結(jié)構(gòu)39結(jié)構(gòu)體與共用體結(jié)構(gòu)體結(jié)構(gòu)體是一種構(gòu)造數(shù)據(jù)類型用途:把不同類型的數(shù)據(jù)組合成一個(gè)整體-------自定義數(shù)據(jù)類型結(jié)構(gòu)體類型定義struct[結(jié)構(gòu)體名]{

類型標(biāo)識(shí)符成員名;類型標(biāo)識(shí)符成員名;

…………….};成員類型可以是基本型或構(gòu)造型struct是關(guān)鍵字,不能省略合法標(biāo)識(shí)符可省:無名結(jié)構(gòu)體結(jié)構(gòu)體與共用體結(jié)構(gòu)體struct[結(jié)構(gòu)體名]成員類40共用體構(gòu)造數(shù)據(jù)類型,也叫聯(lián)合體用途:使幾個(gè)不同類型的變量共占一段內(nèi)存(相互覆蓋)共用體類型定義定義形式:union共用體名{

類型標(biāo)識(shí)符成員名;類型標(biāo)識(shí)符成員名;

…………….};例uniondata{inti;charch;floatf;};fchi類型定義不分配內(nèi)存共用體union共用體名例uniondata41形式一:uniondata{inti;charch;floatf;}a,b;形式二:uniondata{inti;charch;floatf;};uniondataa,b,c,*p,d[3];形式三:union{inti;charch;floatf;}a,b,c;共用體變量的定義fchifchiab共用體變量定義分配內(nèi)存,長(zhǎng)度=最長(zhǎng)成員所占字節(jié)數(shù)共用體變量任何時(shí)刻只有一個(gè)成員存在形式一:形式二:形式三:共用體變量的定義fchifchiab42我經(jīng)常用到的結(jié)構(gòu)體和共用體typedefunion{ unsignedcharbyte; struct { unsignedcharbMainValve:1; unsignedcharbSubValve:1; unsignedcharbSubValve2:1; unsignedcharbFire:1; }bit;}relay_def;typedefstruct{ unsignedchar hour; unsignedchar minute; unsignedchar second;}time_def;我經(jīng)常用到的結(jié)構(gòu)體和共用體typedefunion43結(jié)構(gòu)體說明可以使用一條簡(jiǎn)單的賦值語句將一個(gè)結(jié)構(gòu)體變量的值賦給另一個(gè)相同類型的結(jié)構(gòu)體變量(數(shù)組是不可以直接賦值的) books2=books1;可以將一個(gè)結(jié)構(gòu)體放入另一個(gè)結(jié)構(gòu)體內(nèi)。結(jié)構(gòu)體不能嵌套它自身

structissue{ chardt_of_issue[8]; structcatbooks;}issl;結(jié)構(gòu)體說明可以使用一條簡(jiǎn)單的賦值語句將一個(gè)結(jié)構(gòu)體變量的值賦給44結(jié)構(gòu)體說明結(jié)構(gòu)體變量可以作為參數(shù)傳遞給函數(shù)使用這種方式可以將一組邏輯上相關(guān)的數(shù)據(jù)項(xiàng)一起傳遞,而不是逐個(gè)傳遞變量的類型應(yīng)該與參數(shù)的類型相匹配結(jié)構(gòu)體內(nèi)容比較多的話建議傳形參結(jié)構(gòu)體的一種常見用法是采用結(jié)構(gòu)體數(shù)組的形式結(jié)構(gòu)體說明結(jié)構(gòu)體變量可以作為參數(shù)傳遞給函數(shù)45枚舉型枚舉類型的定義

enum枚舉類型名{取值表};3.說明(1)枚舉型僅適應(yīng)于取值有限的數(shù)據(jù)。例如,根據(jù)現(xiàn)行的歷法規(guī)定,1周7天,1年12個(gè)月。(2)取值表中的值稱為枚舉元素,其含義由程序解釋。一般會(huì)從上到下解釋為0到N的數(shù)值

(3)好的編譯器可以在調(diào)試的時(shí)候?qū)⑵滹@示為枚舉值,但現(xiàn)在用的編譯器好像都沒有這個(gè)功能。使用可以大大增加程序的可讀性和可擴(kuò)展性可擴(kuò)展性:如在中間加一個(gè)值基本上原來的程序是不用更改的枚舉型枚舉類型的定義46指針和數(shù)組引用數(shù)組中的任意一個(gè)元素的形式:數(shù)組名[下標(biāo)表達(dá)式]1.“下標(biāo)表達(dá)式”可以是任何非負(fù)整型數(shù)據(jù),取值范圍是0~(元素個(gè)數(shù)-1)。特別強(qiáng)調(diào):在運(yùn)行C語言程序過程中,系統(tǒng)并不自動(dòng)檢驗(yàn)數(shù)組元素的下標(biāo)是否越界。因此在編寫程序時(shí),保證數(shù)組下標(biāo)不越界是十分重要的。

2.1個(gè)數(shù)組元素,實(shí)質(zhì)上就是1個(gè)變量,它具有和相同類型單個(gè)變量一樣的屬性,可以對(duì)它進(jìn)行賦值和參與各種運(yùn)算。

3.在C語言中,數(shù)組作為1個(gè)整體,不能參加數(shù)據(jù)運(yùn)算,只能對(duì)單個(gè)的元素進(jìn)行處理。指針和數(shù)組引用數(shù)組中的任意一個(gè)元素的形式:47最常用到的數(shù)組查表法根據(jù)AD值求溫度1、離線計(jì)算出各AD值所對(duì)應(yīng)的溫度2、直接用數(shù)組得到溫度值通訊過程中的數(shù)據(jù)緩沖1、因占用中斷,故希望中斷里內(nèi)容越少越好2、接收計(jì)數(shù)器++3、直接將接收到的內(nèi)容通過計(jì)數(shù)器賦予數(shù)組4、注意緩沖區(qū)的大小要滿足要求最常用到的數(shù)組查表法根據(jù)AD值求溫度48指針1)指針──即地址一個(gè)變量的地址稱為該變量的指針。通過變量的指針能夠找到該變量。(2)指針變量──專門用于存儲(chǔ)其它變量地址的變量指針變量num_pointer的值就是變量num的地址。指針與指針變量的區(qū)別,就是變量值與變量的區(qū)別。(3)為表示指針變量和它指向的變量之間的關(guān)系,用指針運(yùn)算符“*”表示。例如,指針變量num_pointer與它所指向的變量num的關(guān)系,表示為:*num_pointer,即*num_pointer等價(jià)于變量num。因此,下面兩個(gè)語句的作用相同:num=3; /*將3直接賦給變量num*/num_pointer=#/*使num_pointer指向num*/*num_pointer=3; /*將3賦給指針變量num_pointer所指向的變量*/指針1)指針──即地址49我們常用到的指針1)函數(shù)調(diào)用:為了利用被調(diào)用函數(shù)改變的變量值,應(yīng)該使用指針(或指針變量)作函數(shù)實(shí)參。其機(jī)制為:在執(zhí)行被調(diào)用函數(shù)時(shí),使形參指針變量所指向的變量的值發(fā)生變化;函數(shù)調(diào)用結(jié)束后,通過不變的實(shí)參指針(或?qū)崊⒅羔樧兞浚⒆兓闹当A粝聛怼?)當(dāng)數(shù)組大小不能確定時(shí),使用指針無疑要比數(shù)組方便的多3)通過指針引用數(shù)組元素(注意:pointer+1指向數(shù)組的下一個(gè)元素,而不是簡(jiǎn)單地使指針變量pointer的值+1。其實(shí)際變化為pointer+1*size(size為一個(gè)元素占用的字節(jié)數(shù)))。

我們常用到的指針1)函數(shù)調(diào)用:為了利用被調(diào)用函數(shù)改變的變量值50指針使用注意事項(xiàng)(1)指針變量的值是可以改變的,所以必須注意其當(dāng)前值,否則容易出錯(cuò)。(2)指向數(shù)組的指針變量,可以指向數(shù)組以后的內(nèi)存單元,雖然沒有實(shí)際意義。(3)對(duì)指向數(shù)組的指針變量(px和py)進(jìn)行算術(shù)運(yùn)算和關(guān)系運(yùn)算的含義

1)可以進(jìn)行的算術(shù)運(yùn)算,只有以下幾種:

px±n,px++/++px,px--/--px,px-py·px±n:將指針從當(dāng)前位置向前(+n)或回退(-n)n個(gè)數(shù)據(jù)單位,而不是n個(gè)字節(jié)。顯然,px++/++px和px--/--px是px±n的特例(n=1)。

·px-py:兩指針之間的數(shù)據(jù)個(gè)數(shù),而不是指針的地址之差。2)關(guān)系運(yùn)算表示兩個(gè)指針?biāo)傅刂分g、位置的前后關(guān)系:前者為小,后者為大。例如,如果指針px所指地址在指針py所指地址之前,則px〈py的值為1。指針使用注意事項(xiàng)(1)指針變量的值是可以改變的,所以必須注意51數(shù)組與指針的區(qū)別

數(shù)組要么在靜態(tài)存儲(chǔ)區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧上被創(chuàng)建。指針可以隨時(shí)指向任意類型的內(nèi)存塊。

(1)修改內(nèi)容上的差別chara[]=“hello”;

a[0]=‘X’;

char*p=“world”;//注意p指向常量字符串

p[0]=‘X’;//編譯器不能發(fā)現(xiàn)該錯(cuò)誤,運(yùn)行時(shí)錯(cuò)誤

(2)用運(yùn)算符sizeof可以計(jì)算出數(shù)組的容量(字節(jié)數(shù))。sizeof(p),p為指針得到的是一個(gè)指針變量的字節(jié)數(shù),而不是p所指的內(nèi)存容量。C++/C語言沒有辦法知道指針?biāo)傅膬?nèi)存容量,除非在申請(qǐng)內(nèi)存時(shí)記住它。注意當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時(shí),該數(shù)組自動(dòng)退化為同類型的指針。chara[]="helloworld";

char*p=a;

cout<<sizeof(a)<<endl;//12字節(jié)

cout<<sizeof(p)<<endl;//4字節(jié)

計(jì)算數(shù)組和指針的內(nèi)存容量voidFunc(chara[100])

{

cout<<sizeof(a)<<endl;//4字節(jié)而不是100字節(jié)

}數(shù)組與指針的區(qū)別

數(shù)組要么在靜態(tài)存儲(chǔ)區(qū)被創(chuàng)建(如全局?jǐn)?shù)組)52編譯預(yù)處理所謂編譯預(yù)處理是指,在對(duì)源程序進(jìn)行編譯之前,先對(duì)源程序中的編譯預(yù)處理命令進(jìn)行處理;然后再將處理的結(jié)果,和源程序一起進(jìn)行編譯,以得到目標(biāo)代碼。

宏定義與符號(hào)常量文件包含條件編譯編譯預(yù)處理所謂編譯預(yù)處理是指,在對(duì)源程序進(jìn)行編譯之前,先對(duì)源53宏的使用及命名規(guī)范宏是用來表示一些固定或可能會(huì)改變的參數(shù)的名稱宏不占用內(nèi)存空間(RAM)建議:在用到有意義的數(shù)值參數(shù)時(shí)應(yīng)盡量使用宏定義,而不是直接在程序中使用數(shù)值

需要使用宏定義的內(nèi)容:芯片輸入輸出口:IN_RMC內(nèi)部常量:BEEP_SHORT_TIME宏的使用及命名規(guī)范宏是用來表示一些固定或可能會(huì)改變的參數(shù)的名54無參宏定義1.無參宏定義的一般格式

#define標(biāo)識(shí)符語言符號(hào)字符串其中:#definepi3.142.使用宏定義的優(yōu)點(diǎn)(1)可提高源程序的可維護(hù)性(2)可提高源程序的可移植性(3)減少源程序中重復(fù)書寫字符串的工作量無參宏定義1.無參宏定義的一般格式55說明(1)宏名一般用大寫字母表示,以示與變量區(qū)別。但這并非是規(guī)定。(2)宏定義不是C語句,所以不能在行尾加分號(hào)。否則,宏展開時(shí),會(huì)將分號(hào)作為字符串的1個(gè)字符,用于替換宏名。(3)在宏展開時(shí),預(yù)處理程序僅以按宏定義簡(jiǎn)單替換宏名,而不作任何檢查。如果有錯(cuò)誤,只能由編譯程序在編譯宏展開后的源程序時(shí)發(fā)現(xiàn)。(4)宏定義命令#define出現(xiàn)在函數(shù)的外部,宏名的有效范圍是:從定義命令之后,到本文件結(jié)束。通常,宏定義命令放在文件開頭處。(5)在進(jìn)行宏定義時(shí),可以引用已定義的宏名。(6)對(duì)雙引號(hào)括起來的字符串內(nèi)的字符,即使與宏名同名,也不進(jìn)行宏展開。說明(1)宏名一般用大寫字母表示,以示與變量區(qū)別。但這并非是56有參宏定義1.帶參宏定義的一般格式#define宏名(形參表)語言符號(hào)字符串2.帶參宏的調(diào)用和宏展開(1)調(diào)用格式:宏名(實(shí)參表)(2)宏展開:用宏調(diào)用提供的實(shí)參字符串,直接置換宏定義命令行中、相應(yīng)形參字符串,非形參字符保持不變。3.說明(1)定義有參宏時(shí),宏名與左圓括號(hào)之間不能留有空格。否則,C編譯系統(tǒng)將空格以后的所有字符均作為替代字符串,而將該宏視為無參宏。(2)有參宏的展開,只是將實(shí)參作為字符串,簡(jiǎn)單地置換形參字符串,而不做任何語法檢查。在定義有參宏時(shí),在所有形參外和整個(gè)字符串外,均加一對(duì)圓括號(hào)。有參宏定義1.帶參宏定義的一般格式57有參宏定義3)雖然有參宏與有參函數(shù)確實(shí)有相似之處,但不同之處更多,主要有以下幾個(gè)方面:1)調(diào)用有參函數(shù)時(shí),是先求出實(shí)參的值,然后再?gòu)?fù)制一份給形參。而展開有參宏時(shí),只是將實(shí)參簡(jiǎn)單地置換形參。2)在有參函數(shù)中,形參是有類型的,所以要求實(shí)參的類型與其一致;而在有參宏中,形參是沒有類型信息的,因此用于置換的實(shí)參,什么類型都可以。有時(shí),可利用有參宏的這一特性,實(shí)現(xiàn)通用函數(shù)功能。3)使用有參函數(shù),無論調(diào)用多少次,都不會(huì)使目標(biāo)程序變長(zhǎng),但每次調(diào)用都要占用系統(tǒng)時(shí)間進(jìn)行調(diào)用現(xiàn)場(chǎng)保護(hù)和現(xiàn)場(chǎng)恢復(fù);而使用有參宏,由于宏展開是在編譯時(shí)進(jìn)行的,所以不占運(yùn)行時(shí)間,但是每引用1次,都會(huì)使目標(biāo)程序增大1次。有參宏定義3)雖然有參宏與有參函數(shù)確實(shí)有相似之處,但不同之處58經(jīng)常用到的有參宏定義#defineBit(x) (1<<(x))#definebset(var,bitno)((var)|=(1<<(bitno)))#definebclr(var,bitno)((var)&=~(1<<(bitno)))#definenop() asm("nop")#defineclrwdt() asm("clrwdt")經(jīng)常用到的有參宏定義#defineBit(x) 59文件包含1.文件包含的概念文件包含是指,一個(gè)源文件可以將另一個(gè)源文件的全部?jī)?nèi)容包含進(jìn)來。2.文件包含處理命令的格式#include“包含文件名”或#include<包含文件名>兩種格式的區(qū)別僅在于:(1)使用雙引號(hào):系統(tǒng)首先到當(dāng)前目錄下查找被包含文件,如果沒找到,再到系統(tǒng)指定的“包含文件目錄”(由用戶在配置環(huán)境時(shí)設(shè)置)去查找。(2)使用尖括號(hào):直接到系統(tǒng)指定的“包含文件目錄”去查找。一般地說,使用雙引號(hào)比較保險(xiǎn)。文件包含1.文件包含的概念60文件包含優(yōu)點(diǎn)一個(gè)大程序,通常分為多個(gè)模塊,并由多個(gè)程序員分別編程。有了文件包含處理功能,就可以將多個(gè)模塊共用的數(shù)據(jù)(如符號(hào)常量和數(shù)據(jù)結(jié)構(gòu))或函數(shù),集中到一個(gè)單獨(dú)的文件中。這樣,凡是要使用其中數(shù)據(jù)或調(diào)用其中函數(shù)的程序員,只要使用文件包含處理功能,將所需文件包含進(jìn)來即可,不必再重復(fù)定義它們,從而減少重復(fù)勞動(dòng)。文件包含優(yōu)點(diǎn)一個(gè)大程序,通常分為多個(gè)模塊,并由多個(gè)程序員分別61文件包含說明(1)編譯預(yù)處理時(shí),預(yù)處理程序?qū)⒉檎抑付ǖ谋话募?,并將其?fù)制到#include命令出現(xiàn)的位置上。(2)常用在文件頭部的被包含文件,稱為“標(biāo)題文件”或“頭部文件”,常以“h”(head)作為后綴,簡(jiǎn)稱頭文件。在頭文件中,除可包含宏定義外,還可包含外部變量定義、結(jié)構(gòu)類型定義等。(3)一條包含命令,只能指定一個(gè)被包含文件。如果要包含n個(gè)文件,則要用n條包含命令。(4)文件包含可以嵌套,即被包含文件中又包含另一個(gè)文件。理論上講,包含.c文件是沒有任何問題的文件包含說明(1)編譯預(yù)處理時(shí),預(yù)處理程序?qū)⒉檎抑付ǖ谋话?2條件編譯條件編譯可有效地提高程序的可移植性,并廣泛地應(yīng)用在商業(yè)軟件中,為一個(gè)程序提供各種不同的版本。#ifdef~#endif和#ifndef~#endif命令#if~#endif條件編譯條件編譯可有效地提高程序的可移植性,并廣泛地應(yīng)用在商63條件編譯操作系統(tǒng)中使用的條件編譯是最多的,因?yàn)槠湟凑詹煌陌姹竞筒煌腃PU來進(jìn)行編譯,基本上,我們不會(huì)用到多個(gè)CPU的情況我們用的最多的應(yīng)該是debug模式和release模式要注意條件不滿足的內(nèi)容是不編譯的,即使有錯(cuò)誤也不會(huì)報(bào)錯(cuò),在連接的時(shí)候根本不占用ROM區(qū)條件編譯操作系統(tǒng)中使用的條件編譯是最多的,因?yàn)槠湟凑詹煌?4請(qǐng)說出const與#define相比,有何優(yōu)點(diǎn)1)const常量有數(shù)據(jù)類型,而宏常量沒有數(shù)據(jù)類型。編譯器可以對(duì)前者進(jìn)行類型安全檢查。而對(duì)后者只進(jìn)行字符替換,沒有類型安全檢查,并且在字符替換可能會(huì)產(chǎn)生意料不到的錯(cuò)誤。

2)有些集成化的調(diào)試工具可以對(duì)const常量進(jìn)行調(diào)試,但是不能對(duì)宏常量進(jìn)行調(diào)試。請(qǐng)說出const與#define相比,有何優(yōu)點(diǎn)1)co65關(guān)于流程圖流程圖的好處方便地看到程序流向其他人幫你檢查錯(cuò)誤時(shí)容易發(fā)現(xiàn)錯(cuò)誤方便與第三方廠家共享必要性太簡(jiǎn)單的程序不需要流程圖當(dāng)思緒理不清時(shí)需要畫一下流程圖文字說明有時(shí)比流程圖更簡(jiǎn)潔有效關(guān)于流程圖流程圖的好處66C語言編寫注意事項(xiàng)類型強(qiáng)制轉(zhuǎn)換:unsignedcharx=unsignedintn;取n的低8位賦給xcharA=intb+charc;將c轉(zhuǎn)換為整形后與b相加,取b的低8位賦給x某些特定操作時(shí)各編譯器可能實(shí)現(xiàn)結(jié)果不同,為安全起見最好強(qiáng)制轉(zhuǎn)換,本身b為unsignedchar型,則相加后可能造成結(jié)果錯(cuò)誤。(int)A=(unsignedint)(b)+c;某些用來延時(shí)的語句可能會(huì)被編譯器優(yōu)化掉盡量不要用;來延時(shí),改用asm(“nop”);建議在RAM和ROM空間足夠的情況下編譯器選擇不優(yōu)化可以在線仿真的芯片一般會(huì)占用芯片部分資源C語言編寫注意事項(xiàng)類型強(qiáng)制轉(zhuǎn)換:67C語言編寫注意事項(xiàng)堆棧的使用先進(jìn)后出原則注意調(diào)用函數(shù)層數(shù)過多可能引起堆棧溢出,結(jié)果不可預(yù)料盡量不使用嵌套中斷生成.hex文件后先查看下.map文件確認(rèn)RAM使用量,避免堆棧溢出C語言編寫注意事項(xiàng)堆棧的使用68C語言編寫注意事項(xiàng)注意如果使用unsignedchari來定義變量,在判斷過程中不要使用如下代碼: if(i>=0)或者if(i)兩個(gè)unsignedchar數(shù)相乘時(shí)需要類型強(qiáng)制

nSum=(unsignedchar)(nCost)*nSum;使用數(shù)組時(shí)注意數(shù)組的大小為你認(rèn)為永遠(yuǎn)不可能出現(xiàn)的地方填寫一些代碼外部函數(shù)有返回值時(shí)一定要事先聲明后再使用C語言編寫注意事項(xiàng)注意如果使用unsignedchari69C語言編寫注意事項(xiàng)一般在電源重置后(PowerOnReset)所執(zhí)行的第一個(gè)程序模塊并不是使用者的主程序main(),而是一個(gè)隱藏在標(biāo)準(zhǔn)鏈接庫(kù)中稱為startup.a的程序模塊(一般為匯編文件),具體啟動(dòng)文件可咨詢芯片廠商。startup.a的主要工作是把包含idata、xdata、pdata在內(nèi)的內(nèi)存區(qū)塊清除為0,并且初始化遞歸指針。接著startup.a被執(zhí)行的仍然是一個(gè)隱藏在標(biāo)準(zhǔn)鏈接庫(kù)中稱為init.a的程序模塊。而init.a51的主要工作則是初始化具有非零初始值設(shè)定的變量。在完成上述的初始化程序之后,程序的控制權(quán)才會(huì)交給main()開始執(zhí)行使用者的程序。也就是說,一般的C編譯器都會(huì)在初始運(yùn)行時(shí)將RAM清空,而這段程序我們?cè)谧约旱拇a中就可以省略了。C語言編寫注意事項(xiàng)一般在電源重置后(PowerOnRe70編程風(fēng)格程序編碼力求簡(jiǎn)潔,結(jié)構(gòu)清晰,避免太多的分支結(jié)構(gòu)及太過于技巧性的程序,盡量不采用遞歸模式(不容易理解);編寫程序時(shí),亦必須想好測(cè)試的方法,換句話說,“單元測(cè)試”的測(cè)試方案應(yīng)在程序編寫時(shí)一并擬好;將大的復(fù)雜代碼節(jié)分為較小的、易于理解的模塊:一般一個(gè)模塊的大小不超過100行;編程風(fēng)格程序編碼力求簡(jiǎn)潔,結(jié)構(gòu)清晰,避免太多的分支結(jié)構(gòu)及太過71編程風(fēng)格版本封存以后的修改一定要將老語句用/**/封閉,不能自行刪除或修改,并要在文件及函數(shù)的修改記錄中加以記錄預(yù)處理語句、全局?jǐn)?shù)據(jù)、函數(shù)原型、標(biāo)題、附加說明、函數(shù)說明等均頂格書寫;對(duì)齊:原則上關(guān)系密切的行應(yīng)對(duì)齊,對(duì)齊包括類型、修飾、名稱、參數(shù)等各部分對(duì)齊;空行:程序文件結(jié)構(gòu)各部分之間空兩行,若不必要也可只空一行,各函數(shù)實(shí)現(xiàn)之間一般空兩行;一些常數(shù)和表格之類的應(yīng)該放到code去中以節(jié)省RAM或編譯器指定的方法;編程風(fēng)格版本封存以后的修改一定要將老語句用/**/封閉,72編程風(fēng)格程序編完編譯看有多少code多少data,注意留有足夠的堆??臻g;形參:在定義函數(shù)時(shí),在函數(shù)名后面括號(hào)中直接進(jìn)行形式參數(shù)說明,不再另行說明;形參使用“i_”作為前綴禁止出現(xiàn)兩條等價(jià)的支路;禁止GOTO語句;避免從循環(huán)引出多個(gè)出口;即使對(duì)于可能僅出現(xiàn)在幾個(gè)代碼行中的生存期很短的變量,仍然使用有意義的名稱。僅對(duì)于短循環(huán)索引使用單字母變量名,如i或j;編程風(fēng)格程序編完編譯看有多少code多少data,注意留有足73編程風(fēng)格循環(huán)、分支代碼,判斷條件與執(zhí)行代碼不得在同一行上語句塊的“{”“}”配對(duì)對(duì)齊,并與其前一行對(duì)齊;‘{’、‘}’應(yīng)獨(dú)占一行,在該行內(nèi)可有注釋,但不許有可執(zhí)行語句‘{’必須另起一行,‘{’之后的代碼必須縮進(jìn)一個(gè)Tab?!畕’與‘}’必須在同一列上。編程風(fēng)格循環(huán)、分支代碼,判斷條件與執(zhí)行代碼不得在同一行上74編程風(fēng)格在所有兩目、三目運(yùn)算符的兩邊都必須有空格,在單目運(yùn)算符兩端不必空格。但在‘->’、‘.’、‘[’、‘]’等運(yùn)算符前后,及‘&’(取地址)、‘*’(取值)等運(yùn)算符之后不得有空格。for、while、if等關(guān)鍵詞之后應(yīng)有1個(gè)空格,再接‘(’,之后無空格;在結(jié)尾的‘)’前不得有空格。調(diào)用函數(shù)、宏時(shí),‘(’、‘)’前后不得有空格。類型強(qiáng)制轉(zhuǎn)換時(shí),‘(’‘)’前后不得有空格編程風(fēng)格在所有兩目、三目運(yùn)算符的兩邊都必須有空格,在單目運(yùn)算75常用技巧1,防止一個(gè)頭文件被重復(fù)包含#ifndefCOMDEF_H#defineCOMDEF_H//頭文件內(nèi)容#endif常用技巧1,防止一個(gè)頭文件被重復(fù)包含76高效編程的一些辦法編寫高效簡(jiǎn)潔的C語言代碼,是軟件工程師追求的目標(biāo)。1:以空間換時(shí)間在數(shù)碼管掃描過程中,假設(shè)需要2ms掃描一次for(i=0;i<8;i++){ OUT_595_CLK=0; if(nTemp&0x80) OUT_595_DATA=1; else OUT_595_DATA=0; OUT_595_CLK=1; nTemp<<=1;}點(diǎn)評(píng):每個(gè)輸出之后都會(huì)判斷一次,浪費(fèi)時(shí)間,但代碼清晰高效編程的一些辦法編寫高效簡(jiǎn)潔的C語言代碼,是軟件工程師追求77高效編程的一些辦法1:以空間換時(shí)間在數(shù)碼管掃描過程中,假設(shè)需要2ms掃描一次OUT_595_CLK=0;if(nTemp&0x80) OUT_595_DATA=1;else OUT_595_DATA=0;OUT_595_CLK=1;……OUT_595_CLK=0;if(nTemp&0x01) OUT_595_DATA=1;else OUT_595_DATA=0;OUT_595_CLK=1;點(diǎn)評(píng):代碼增長(zhǎng),但運(yùn)行速度加快高效編程的一些辦法1:以空間換時(shí)間78高效編程的一些辦法2:數(shù)學(xué)方法解決問題現(xiàn)在我們演繹高效C語言編寫的第二招--采用數(shù)學(xué)方法來解決問題。數(shù)學(xué)是計(jì)算機(jī)之母,沒有數(shù)學(xué)的依據(jù)和基礎(chǔ),就沒有計(jì)算機(jī)的發(fā)展,所以在編寫程序的時(shí)候,采用一些數(shù)學(xué)方法會(huì)對(duì)程序的執(zhí)行效率有數(shù)量級(jí)的提高。舉例如下,求1~100的和。方法1intI,j;for(I=1;I<=100;I++)

j+=I;循環(huán)了100次,用了100個(gè)賦值,100個(gè)判斷,200個(gè)加法方法2intI;I=(100*(1+100))/2用了1個(gè)加法,1次乘法,1次移位高效編程的一些辦法2:數(shù)學(xué)方法解決問題79高效編程的一些辦法3:使用移位操作減少除法和取模的運(yùn)算。在計(jì)算機(jī)程序中,數(shù)據(jù)的位是可以操作的最小數(shù)據(jù)單位,理論上可以用“位運(yùn)算”來完成所有的運(yùn)算和操作。一般的位操作是用來控制硬件的,或者做數(shù)據(jù)變換使用,但是,靈活的位操作可以有效地提高程序運(yùn)行的效率。方法1:I=257/8;

J=456%32;方法2:I=257>>3;

J=456-(456>>4<<4);在字面上好像H比G麻煩了好多,但是,仔細(xì)查看產(chǎn)生的匯編代碼就會(huì)明白,方法G調(diào)用了基本的取模函數(shù)和除法函數(shù),既有函數(shù)調(diào)用,還有很多匯編代碼和寄存器參與運(yùn)算;而方法H則僅僅是幾句相關(guān)的匯編,代碼更簡(jiǎn)潔,效率更高。運(yùn)用這招需要注意的是,因?yàn)镃PU的不同而產(chǎn)生的問題。所以只有在一定技術(shù)進(jìn)階的基礎(chǔ)下才可以使用這招。高效編程的一些辦法3:使用移位操作80高效編程的一些辦法4:嵌入?yún)R編可以獲得同匯編一樣的效果,尤其在需要精確計(jì)算時(shí)間的地方使可移植性變差,除非萬不得已,不建議使用典型應(yīng)用:asm(“nop”);可精確控制延時(shí)時(shí)間高效編程的一些辦法4:嵌入?yún)R編81高效編程的一些辦法5:指針的使用優(yōu)點(diǎn):可以有效的對(duì)變量進(jìn)行底層操作,直接操作變量的地址。非常方便好用,使代碼變得更簡(jiǎn)潔缺點(diǎn):錯(cuò)誤的操作可導(dǎo)致致命性錯(cuò)誤小一點(diǎn)的程序基本可以不使用指針完成典型應(yīng)用: constTBL_1={1,2,3}; constTBL_2={1,2,3,4};constunsignedchar*pPointer;If(1) pPointer=TBL_1;Else pPointer=TBL_2;X=pPointer[2];高效編程的一些辦法5:指針的使用82高效編程的一些辦法5:指針的傳遞使用指針傳遞可使程序模塊化更好除非必須,在函數(shù)里使用時(shí)盡量不要修改指針?biāo)碜兞康闹担駝t會(huì)引起程序混亂典型應(yīng)用: 6024驅(qū)動(dòng)voidf_HL6024Write(unsignedchari_StartAddress,unsignedchar*i_pAddress,unsignedchari_DataNum){ f_WriteStart(); //寫入起始位

nTemp=f_WriteByte(0X7C); nTemp=f_WriteByte(0XE0); //從地址選擇

nTemp=f_WriteByte(0XF0); //屏閃關(guān)閉

nTemp=f_WriteByte(0XC8); //顯示打開d8(節(jié)電) nTemp=f_WriteByte(i_StartAddress); for(i=0;i<i_DataNum;i++) nTemp=f_WriteByte(i_pAddress[i]); f_Stop(); //結(jié)束位}高效編程的一些辦法5:指針的傳遞83高效編程的一些辦法6:結(jié)構(gòu)的使用可讀性好,代碼簡(jiǎn)潔,效率高為方便使用,芯片廠商給的頭文件中都包括了寄存器的結(jié)構(gòu)體定義,如可用p2=0;設(shè)置整個(gè)p2口輸出,也可以使用p2_2=1;設(shè)置一個(gè)口的輸出典型應(yīng)用: 故障定義typedefunion{ unsignedintbyte; struct { unsignedcharbFireFail:1; /*點(diǎn)火失敗*/ unsignedcharbFireLose:1; /*中途熄火*/ unsignedcharbFanErr:1; /*風(fēng)機(jī)故障*/ unsignedcharbSsrOverHeat:1;/*溫度傳感器過熱*/ unsignedcharbSsrErr:1; /*溫度傳感器開路/短路*/ unsignedcharbOverHeat:1; /*過熱*/ unsignedcharunUsed:2; }bit;}err_def;定義變量:typedef err_def tError;高效編程的一些辦法6:結(jié)構(gòu)的使用84高效編程的一些辦法6:結(jié)構(gòu)的使用故障清零只需一句話 tError.byte=0;單獨(dú)設(shè)置故障位:

tError.bit.bSSrErr=1;修改故障

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論