松翰C語(yǔ)言編程指導(dǎo)CProgramGuide_第1頁(yè)
松翰C語(yǔ)言編程指導(dǎo)CProgramGuide_第2頁(yè)
松翰C語(yǔ)言編程指導(dǎo)CProgramGuide_第3頁(yè)
松翰C語(yǔ)言編程指導(dǎo)CProgramGuide_第4頁(yè)
松翰C語(yǔ)言編程指導(dǎo)CProgramGuide_第5頁(yè)
已閱讀5頁(yè),還剩52頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、如何用c來(lái)完成sn8系列芯片的程序設(shè)計(jì)松翰易愛(ài)華松翰科技(深圳)有限公司sonix technology co.,ltd.內(nèi)容概覽一、c 與 assembly 簡(jiǎn)述二、sn8 c studio的安裝與使用2 sn8 c studio的安裝2.2 sn8 c studio 應(yīng)用實(shí)例三、數(shù)據(jù)類型與運(yùn)算3.1專有數(shù)據(jù)類型3.2常量與變量3.3數(shù)據(jù)的存儲(chǔ)類型與存儲(chǔ)結(jié)構(gòu)四、程序流程控制4順序結(jié)構(gòu)4.2分支判斷結(jié)構(gòu)4.3循環(huán)控制結(jié)構(gòu)五、函數(shù)5.1函數(shù)的定義5.2函數(shù)參數(shù)傳遞與返回值5.3函數(shù)參數(shù)與全局變量六、結(jié)構(gòu)體、聯(lián)合在sn8c程序屮的應(yīng)用6結(jié)構(gòu)體6.2聯(lián)合七、中斷7中斷斷數(shù)的定義7.2屮斷過(guò)程的分析7

2、.3中斷函數(shù)的結(jié)構(gòu)八、位操作&1位的定義8.2位的運(yùn)算8.3位比較在程序流程控制屮的應(yīng)用九、內(nèi)嵌匯編9.1如何內(nèi)嵌匯編9.2內(nèi)嵌匯編時(shí)變量的傳遞十、程序結(jié)構(gòu)10主函數(shù)與了函數(shù)10.2構(gòu)建可復(fù)用文件10.3構(gòu)建具有實(shí)用性的程序一、c 與 assembly 簡(jiǎn)述assembly (匯編)的歷史己經(jīng)有半個(gè)多世紀(jì)了,從計(jì)算機(jī)的發(fā)明那天開(kāi)始,匯編就注定要 與其結(jié)緣,它作為第-種真正意義上的編程語(yǔ)言,在計(jì)算機(jī)的發(fā)展過(guò)程小具有無(wú)可替代的地位。匯編具有少機(jī)器語(yǔ)言一一對(duì)應(yīng)的高效率,就是由于匯編的高效率,和其緊貼硬件的特性, 使其在半個(gè)世紀(jì)z后的今天依然是目前開(kāi)發(fā)單片機(jī)程序的主流工具z。但是由于編寫匯編代

3、 碼的工作量和難度都比較高,并且耍求程序員對(duì)硬件必須有較深刻的了解,其入門就相對(duì)較難。 而匯編的寫法各異,不同的程序員編寫的代碼有著巨大的差異,這就帶來(lái)了學(xué)習(xí)的難度,可讀 性差也成為了其推廣的瓶頸,程序的維護(hù)更加艱難。隨著程序復(fù)雜性的增加,開(kāi)發(fā)團(tuán)隊(duì)的形成, 應(yīng)用而牛的高級(jí)語(yǔ)言就逐漸取代了其位置。c就是高級(jí)語(yǔ)言中針對(duì)硬件操作最優(yōu)秀的一利,c也是基于匯編的,其和互關(guān)系如圖所示。 隨著人們不斷的對(duì)c進(jìn)行改善,使c的效率得到了很大的提升,其編譯效率逐漸的逼近匯編。 而c以其模塊化的編程模式,簡(jiǎn)潔的代碼,良好的可讀性和可維護(hù)性,成為了另一種單片機(jī)開(kāi) 發(fā)的主流開(kāi)發(fā)工具,相比匯編而言,其具有無(wú)可比擬的優(yōu)異性

4、。圖1、c與匯編的關(guān)系sn8c是基于標(biāo)準(zhǔn)(2而乂加入sonix sn8系列芯片特征的專用c,它而對(duì)的是sonix sn8系列芯片程序開(kāi)發(fā),它能產(chǎn)生非常簡(jiǎn)潔的能直接運(yùn)行于sn8系列芯片的優(yōu)化代碼。具冇 良好的兼容性,易學(xué)易用,既方便客八開(kāi)發(fā),乂繼承了原有匯編的卓越性能。在木文當(dāng)中,我們將結(jié)合匯編來(lái)講述c開(kāi)發(fā)的各方面知識(shí),以期通過(guò)對(duì)比來(lái)加深對(duì)芯片 的編程應(yīng)用的了解,同吋,對(duì)熟悉c的程序員來(lái)說(shuō),可以更加深入了解芯片;而對(duì)于熟悉匯編 的程序員來(lái)說(shuō),我們可以從對(duì)比中找到從匯編到c的轉(zhuǎn)換方法。二、sn8 c studio的安裝與使用sonix sn8系列的芯片是risc內(nèi)核的高性能芯片。h前,由sonix

5、提供的sn8 assembly 僅有59條指令,是一種高效的匯編語(yǔ)言,有s8asm和m2asm編譯器分別支持其1系和2系 芯片。在此:基礎(chǔ)上的sn8 c studio整合了匯編和c的編譯器,1 1、 sn8 c studio 的安裝在得到sn8 c studio的安裝包后,按照標(biāo)準(zhǔn)的windows程序安裝方法安裝就可以將軟件 安裝到機(jī)器上。12、sn8 c studio應(yīng)用實(shí)例、創(chuàng)建一個(gè)工作區(qū)與vc類似,我們的工程管理模式是以工作區(qū)方式來(lái)管理,在你準(zhǔn)備一個(gè)項(xiàng)目的時(shí)候, 你首先創(chuàng)建一個(gè)屬于這個(gè)項(xiàng)目的工作區(qū):1、打開(kāi)ids-文件新建,單擊出現(xiàn)如下界面:a 2-1新建對(duì)話框2單擊workspace圖

6、標(biāo),進(jìn)入workspace創(chuàng)建窗口,單擊location編輯框后的按鈕,選擇你 需要的匚作目錄,然后輸入新建workspace的name,在這里如f:圖2-2 新建workspace對(duì)話框3、單擊0k, ids的界血生成了工作區(qū)的工作界面,出現(xiàn)了 workspace窗口和output窗口。同 時(shí),打開(kāi)目標(biāo)文件夾,你會(huì)發(fā)現(xiàn)在你選定的文件夾下面,牛成了一個(gè)以workspace name命名 的新文件夾,打開(kāi)文件夾你可以看到一個(gè)新生成的.wsp文件,這就是新生成的workspace的配 置文件:5n8c1ex.wspm/sp爻件$i圖2-3新生成的workspace配置文件二、新建一個(gè)工程(proj

7、ect)在我們成功創(chuàng)建一個(gè)工作區(qū)后,你會(huì)發(fā)現(xiàn)我們的workspace窗口中的projiect數(shù)目為0,接 看我們就要依據(jù)項(xiàng)目所用的芯片母體來(lái)創(chuàng)建一個(gè)工程項(xiàng)目了,跟創(chuàng)建workspace相同,打開(kāi)菜 單中的文件新建,單擊出現(xiàn)新建窗口,此時(shí)默認(rèn)為新建projecto在右邊的project list窗口 中選擇你要使用的芯片母體和要?jiǎng)?chuàng)建的工程類型(一般為普通項(xiàng)冃),此時(shí)的h標(biāo)路徑location 中已經(jīng)顯示為你剛才建立的workspace冃錄,建議將工程保存在這個(gè)口錄下,不修改默認(rèn)路徑。 給新建工程取一個(gè)有意義的name,在框中輸入。這里我們収與workspace相同的名稱,新建 一個(gè)2700系列芯

8、片的普通項(xiàng)口工程,設(shè)迸如f圖所示:1、單擊文件新建,選擇合適的選項(xiàng):newnewrroject list副workspaces陽(yáng)廂陽(yáng)n8陽(yáng)廂陽(yáng)陽(yáng)陽(yáng)廂陽(yáng)1t81t8n82700a rroject2600 project2500 project1900 project1800 project1700 project1600 project2700a sreies static library project260025001900180017001600static static static static static staticlibrary library library library

9、library libraryproject proj ect project project project projectokcancel i圖 2-4 新建 project2、單擊ok。3、新工程選項(xiàng)配置,在確認(rèn)建立工程后,出現(xiàn)project setting對(duì)話框,左邊的project列表 中默認(rèn)選中我們剛剛建立的工程,在這里我們只修改chip和code option項(xiàng)目下的選項(xiàng),如圖 所示:圖 2-5 project setting 對(duì)話框4、選擇正確的芯片:在chip頁(yè)屮,definition文木框屮顯示系統(tǒng)依據(jù)你選定的芯片母體系列而確定的需要調(diào)用 的芯片定義文件。chip list

10、表列出了當(dāng)前版木的ids所支持的這一系列的各個(gè)芯片,選中其中 你需要使用的芯片母體,selected文本框和description sc本框和應(yīng)會(huì)口動(dòng)改變。如圖:圖2-6選擇芯片5、設(shè)置正確的code option選項(xiàng)和ice mode:ice mode的設(shè)置在sn8plxxx芯片中是用丁選擇是否是ice仿真模式,在code option 列表中自動(dòng)顯示選定芯片母體的code option選項(xiàng),在option value項(xiàng)的默認(rèn)值上單擊,出現(xiàn) 一個(gè)下拉列表,單擊選擇合適的選項(xiàng)。如圖:圖2-7設(shè)置止確的code option6、單擊ok,系統(tǒng)牛成一個(gè)沒(méi)有文件的工程,在workspace管理窗口中

11、我們可以看見(jiàn)當(dāng) 前牛成的工程為working project,正處被激活狀態(tài)(工程名稱為加粗字休):workspace - sn8c_ex : 1 projec白鶯 sm8c_ex 口 source header圖2-8新建project的狀態(tài)被激活 打開(kāi)相應(yīng)的文件夾,我們會(huì)發(fā)現(xiàn)系統(tǒng)生成了很多個(gè)新的文件,其屮的.pij文件即為工程文 件,其他的文件為根據(jù)我們剛才的設(shè)置和不同的芯片生成的配置文件及頭文件。三、新建文件完成項(xiàng)目的新建后,我們發(fā)現(xiàn)項(xiàng)目管理器source文件夾下是空的,沒(méi)有任何文件,文件 就是我們編程的主要工作了 !1、打開(kāi)文件-新建菜單,單擊出現(xiàn)我們前面看過(guò)很多次的new對(duì)話框,不過(guò)

12、比前面多了一個(gè)選項(xiàng)files,選擇new列表中的files選項(xiàng),單擊按鈕,對(duì)話框如圖所示:圖2-9新建文件對(duì)話框2在file list 'i1選屮需要?jiǎng)?chuàng)建的文件類型,這里我們創(chuàng)建一個(gè)c source file,給文件命 名從name編輯框屮輸入,存放的地點(diǎn)為剛才的設(shè)定位置,默認(rèn)不做修改。3、單擊0k按鈕,ids打開(kāi)一個(gè)編輯窗口,最大化,顯示為剛剛建立的文件名的頁(yè),系 統(tǒng)允許我們?cè)谶@里進(jìn)行程序的編寫。四、編寫程序在新建一個(gè)文件后,系統(tǒng)自動(dòng)打開(kāi)編輯器,并打開(kāi)一個(gè)由用戶命名的空文檔,它與普通文 檔相比較沒(méi)有什么不同的z處,只不過(guò)它可以對(duì)c的關(guān)鍵字進(jìn)行高亮顯示。在新的文檔里編輯 程序。c本身就

13、是一種模塊化的編程語(yǔ)言,sn8c的編程保持c語(yǔ)言的編程風(fēng)格。 sn8c所具有的nonansi c的特性請(qǐng)參看其他章節(jié),在此不再做描述。 下面是一個(gè)簡(jiǎn)單的c程序舉例。例2:* file name : sn8c_ex.c* post by : dragon.yi* date : 2005/09/23* test history : vi.00.220 describe:test 2708 interrupt住丄 2丄.丄丄丄“ ”“ ”丄 “丄.“/<t>p ppp pppppp /#includc <sn8p2708a.h> struct wordunsigned fin

14、t: 1; unsigned :7;jintword;unsigned int tc0cvaluc=0x64;unsigned int accbuf = 0x00; unsigned int pflagbuf = 0;/the data will auto store!interrupt intserv(void)_bclr(&intrq,5); tc0c = tcocvalue; intword.fint = 1;void initlo(void); void initlnt(void);void main(void)stkp=0x07;initio();initint();whil

15、e(l)if(intword.fint!=0) pl=0x00;p2=0x00;p3=()x()();p4=0x00;p5=0x00;po=oxoo;elsepo=oxff;pl=oxff;p2=0xff;p3=0xff;p4=0xff;p5=0xff;void initlo(void)p0m=0xff;plm=()xff;p2m=0xff;p3m 二 oxff;p4m=0xff;p5m=0xff;void initlnt(void)intrq=0x00;inten=0x00;tc()m=()x()();tc0m=0x20;tc0c=0x64;_bclr(&intrq,5); _bse

16、t(&inten,5);_bset(&tc0m,7); _bset(&stkp,7);注:程序只作為程序架構(gòu)提供參考!五、調(diào)試程序在完成代碼編輯后,想要馬上順利運(yùn)行基本上是不可能的,每一個(gè)程序都有經(jīng)過(guò)調(diào)試的 過(guò)程,程序的調(diào)試在ids屮非常方便,ids有全而的可視化的調(diào)試工具。你可以在程序屮設(shè)置 斷點(diǎn),在程序中按自己的需求來(lái)運(yùn)行。可以根據(jù)不同的需求來(lái)進(jìn)行調(diào)試。1、compile 和 build完成代碼的編輯后,首先要進(jìn)行compile,在菜單build->compile current file單擊或在工具欄屮單擊compile按鈕和單擊快捷鍵ctrl+f7均以啟動(dòng)

17、系統(tǒng)的compile程序。compile程 序會(huì)檢杏代碼屮存在的語(yǔ)法錯(cuò)謀和軟件設(shè)置錯(cuò)込 然示在ompih窗口表列岀來(lái),用戶可以根據(jù) 表列出來(lái)的提示,對(duì)程序進(jìn)行修改。若是語(yǔ)法錯(cuò)誤,在列表中雙擊選項(xiàng),系統(tǒng)會(huì)自動(dòng)將光標(biāo)移 動(dòng)到相對(duì)應(yīng)的代碼行,方便你的檢查和修改。compile通過(guò)后,進(jìn)行build,同樣有3種方式可 以啟動(dòng)build程序,build程序生成運(yùn)行所需要的一些文件,同時(shí)檢查硬件配置和連接錯(cuò)誤,用 戶必須根據(jù)提示對(duì)程序進(jìn)行修改才能順利通過(guò)。2、選擇仿真方式單擊進(jìn)入projcct->sctting, !l|jw我們前面已經(jīng)熟悉的project setting對(duì)話框,當(dāng)前就示的是 gen

18、eral頁(yè),在primary setting組下面找到復(fù)選項(xiàng)use simulateo如果選屮該選項(xiàng),則程序就在系 統(tǒng)提供的虛擬仿真器上仿真并顯示相應(yīng)結(jié)果;若不選中該選項(xiàng),則程序必須在相應(yīng)系列的仿真 器上進(jìn)行程序調(diào)試仿真。這里我們先選擇它。3、進(jìn)入調(diào)試模式完成compile和build z后,進(jìn)入菜單dcbug->bcgin debug,單擊菜單項(xiàng)或直接按快捷鍵f5或在圖標(biāo)選項(xiàng)中選擇按 曾鈕單擊都可進(jìn)入調(diào)試模式,進(jìn)入調(diào)試模式后,系統(tǒng)界面變成如下圖:d e r 0尙 g >> t£? vi % 冷檔諛體ii 4)卩.£ .茫? *.q h f »r

19、» e護(hù)f臥 "a口葉 erowet quu qebug loebgp/tho data vill auto stow!5onb< in*egrated development system - (w8_tet604xuruxened urt tc0cvalue»llx64; unsicned mt accbuf = 0x00; imfifmd lnt pflafbuf = 0: .interrupt interv(void) .boruihtrq, 5); tcoc s tcocvalue. intword. fint « 1 3 lorktpa

20、ct - %nfl.ltt<604e) k ib8_1«sim4 a o swc«void a&w(void)uif (intvord. fint l«0)htoo»k00l1ljioiooaddr«*sm gln 31,3 inum16:53 o圖211調(diào)試程序界面3:void lmt io(void). void lmtlwt(void):stkp«)xo7; mitloo : lnitinto; vhile(l)2 he心oh 轉(zhuǎn) cn»wxtkb |sowlnt9r(gpl»0x00; p2=

21、' <00; p>0x00.pchucl5 fit s 口 k”dr二4ryond.fl h 勻 dryondf2 hokoo0«000x000*00 00 (mlm0noisioksiob owoo系統(tǒng)界而出現(xiàn) ram windowwatch window> variable window> register window> call stack window和disassembly window ,這些窗口都是調(diào)試程序要用到的。程序的指針指向程序的入 口處,即main ()函數(shù)的第一條語(yǔ)句。4 應(yīng)用 watch window:在調(diào)試過(guò)程中如何

22、應(yīng)用watch window? watch window用在調(diào)試工程中對(duì)定義的變量進(jìn)行 監(jiān)視,將需要進(jìn)行監(jiān)視的variable在編輯窗口屮雙擊,然后拖放到watch window當(dāng)中,運(yùn)行 程序就可以在watch window中看到variable的存放地點(diǎn)和值的變化。如圖:namelo.addressvalue keycha tramf0x00000010oxft|1 imiv watch 1 x watch 2 入 watch3 /!圖 2-12 watch window 窗 fl系統(tǒng)會(huì)將產(chǎn)牛了變化的項(xiàng)置成紅色。為方便觀察,你最多可以將variable分別放到3個(gè)watch window當(dāng)

23、中進(jìn)行觀察,他們的 顯示效果是一樣的!5、應(yīng)用 variable windowvariable window顯示格式和watch window的顯示格式樣,但是variable window里面的 項(xiàng)無(wú)法自己設(shè)定。它是以auto的狀態(tài)顯示當(dāng)前運(yùn)行過(guò)程中被改變的local variable,同樣系統(tǒng) 會(huì)將最近改變的量置成紅色。6、應(yīng)用 register window:register window里面顯示的項(xiàng)是根據(jù)芯片的資源而定的,它顯示的是當(dāng)前母體芯片ram 中0x80oxff空間屮專用存儲(chǔ)器在當(dāng)前運(yùn)行狀態(tài)下的值,單擊前面的“ + ”號(hào),將擴(kuò)展項(xiàng)f1展 開(kāi),可以得到毎一個(gè)bit的當(dāng)而值。同樣,

24、在運(yùn)行過(guò)程中,系統(tǒng)會(huì)將剛改變的項(xiàng)的值置為紅色 高亮顯示,便于我們觀察跟蹤。由tcorcannot access.spcloxadspch0x00ep00x00白ploxfff fp100x01 fpu0x01fp120x01ofp130x01fp140x01fp150x01 fp160x01fp170x01a3p20x00由i>30x00namevalue圖 2-13 register 窗口7、應(yīng)用 call stack windowcall stack window顯示當(dāng)前運(yùn)行狀態(tài)卜,stack的使用狀況和入棧的函數(shù),用戶可以根據(jù) 顯示來(lái)判斷程序的調(diào)用狀況,進(jìn)而判斷當(dāng)前的狀態(tài)是否正確,

25、有沒(méi)有函數(shù)調(diào)用岀錯(cuò)。圖 2-14 call stack 窗口8、應(yīng)丿ij memory window:在程序運(yùn)行當(dāng)屮,當(dāng)你想從具體的ram地址而得到它的值的時(shí)候,你可以通過(guò)memory 窗口中實(shí)現(xiàn),你可以直接在go to后面的編輯框中輸入地址,按enter鍵確認(rèn),窗口會(huì)自動(dòng)跳轉(zhuǎn) 到相應(yīng)的位置顯示該位置的值,方便我們?cè)谑褂眠^(guò)程中的查找。9 應(yīng)用 disassembly window:如果調(diào)試過(guò)程屮,你需耍知道程序的直接匯編碼,你可以在這個(gè)窗口屮觀察。1()、設(shè)置斷點(diǎn):程序調(diào)試的時(shí)候,往往需要知道程序運(yùn)行過(guò)程中某個(gè)變雖的運(yùn)行狀態(tài),或者想知道某段 程序是否執(zhí)行,還有執(zhí)行后的結(jié)果;或者,需要知道某段程

26、序的運(yùn)行過(guò)程是否匸確。這吋,就 必須在程序的正確位置設(shè)置斷點(diǎn)。將光標(biāo)移到正確位置,在相應(yīng)的行,單擊設(shè)置斷點(diǎn)的按鈕或按快捷鍵f9或者從菜單項(xiàng)中 設(shè)置都可以使該行程序被設(shè)置成為斷點(diǎn),被設(shè)置成斷點(diǎn)后,運(yùn)行程序,程序就會(huì)運(yùn)行到斷點(diǎn)處 停下來(lái),以便于用戶控制程序的執(zhí)行和觀察執(zhí)行的結(jié)果。如圖:elsep0=0xff;pl=0xff;op2=0xff;p3=0xff;p4=0xff;p5=0xff;圖215斷點(diǎn)執(zhí)行狀態(tài)11、跟蹤程序執(zhí)行:應(yīng)用系統(tǒng)提供的debug工具,用戶可以很方便地對(duì)程序的執(zhí)行效果進(jìn)行跟蹤。你可以單步, 也可越過(guò)一段程序往下執(zhí)行,這要看你的需要!調(diào)試工具同樣町以以3種方式打開(kāi):debug菜

27、 單、工具欄按鈕和快捷鍵。六、程序輸出1、仿真程序結(jié)果:將仿真器與主機(jī)連接好,在project setting中清除use simulate選項(xiàng)的選中狀態(tài)。將需要仿 真的硬件系統(tǒng)冃標(biāo)板連接好。單擊debug按鈕或者按快捷鍵進(jìn)入調(diào)試狀態(tài),就可以在實(shí)際硬件 上看到程序運(yùn)行的結(jié)果,對(duì)程序進(jìn)行修改直到得到正確結(jié)果。我們就得到一個(gè)正確運(yùn)行的可以 燒錄到實(shí)際芯片的程序。2、輸出燒錄文檔在完成程序的調(diào)試仿真后,我們就需要將程序輸出。系統(tǒng)已經(jīng)在默認(rèn)目錄下生成程序的 燒錄檔xxx.sns,默認(rèn)目錄為當(dāng)前工程文件的目錄下。數(shù)據(jù)類型與運(yùn)算sn8 c支持標(biāo)準(zhǔn)c的所有數(shù)據(jù)類型。具體有無(wú)符號(hào)字符(unsigned cha

28、r).有符號(hào)字符 (signed char)> 無(wú)符號(hào)整型(unsigned int)> 有符號(hào)整型(signed int)、無(wú)符號(hào)長(zhǎng)型(unsigned long)、 有符號(hào)長(zhǎng)型(signed long)浮點(diǎn)(float)和指針類型。還支持所有的構(gòu)造類型。字符型(char)r基本類型整型(int)長(zhǎng)整型(long)< 浮點(diǎn)型(float)數(shù)據(jù)類型j構(gòu)造類型指針類型數(shù)組(any)結(jié)構(gòu)體(struct) 共用體(union) 枚舉(enum)圖3-1數(shù)據(jù)類型3.1專有數(shù)據(jù)類型雖然sn8c支持c的所冇數(shù)據(jù)類型,但是由于它面對(duì)的是8-bit單片機(jī),所以必然會(huì)考慮 數(shù)據(jù)類型的定義方法

29、和長(zhǎng)度。在這些方面,sn8 c有它口己的專有的定義特征和數(shù)據(jù)長(zhǎng)度,在 使用時(shí)一定要加于區(qū)分。請(qǐng)看下表:數(shù)據(jù)類型size (byte)數(shù)據(jù)取值范圍signed char (short int)1-128 +127unsigned char(shorts int)10-255signed long2-32768+32767unsigned long2065535float、double4pointer2enum1表31、數(shù)據(jù)類型長(zhǎng)度定義表3.2常量與變量在程序設(shè)計(jì)的過(guò)程中,我們有些量可能是參考值,也町能是預(yù)設(shè)的值??倆,我們希望它 在整個(gè)程序中保持不變,并且在程序的任何地方可以提供我們調(diào)用,用來(lái)比

30、對(duì)某些條件是否成對(duì)于這樣的值,我們可以不去定義它,而直接參考數(shù)值,這在匯編編程過(guò)程中,經(jīng)常會(huì)有 一些缺乏經(jīng)驗(yàn)的程序員這樣用。但這就需要程序員把程序中的這些值都牢牢記住,并要將他 們的值前后統(tǒng)一,這是一個(gè)非常容易出錯(cuò)的過(guò)程,而且也會(huì)影響了程序的可讀性,這樣,程序 的修改和維護(hù)都非常艱難,必須處處小心翼翼,一處不慎就全盤錯(cuò)誤!這是任何人不想看到的 后果。因此,建議對(duì)于程序中用到的不會(huì)改變的參考值或其他預(yù)設(shè)的值都進(jìn)行一個(gè)預(yù)先的定義, 給它取一個(gè)有意義的或與其相關(guān)的名字。這個(gè)過(guò)程就是常最定義,白然,這個(gè)不變的量就稱為 常量。在標(biāo)準(zhǔn)c中,由于而對(duì)的是功能強(qiáng)大的cpu系統(tǒng)和大內(nèi)存,用戶可以不去管它放置的地

31、 方。但是,而對(duì)一個(gè)單片機(jī)系統(tǒng),它的ram非常小,有吋會(huì)顯得很緊張。所以系統(tǒng)為了節(jié)省空 間會(huì)將一些表格等放在系統(tǒng)的rom中。而我們直接命名的常雖,則由編譯器自動(dòng)將其替換為 所需要的值,這些工作就由計(jì)算機(jī)來(lái)完成好了。我們先來(lái)看看我們用匯編編寫程序時(shí)是怎么來(lái)定義常量的:如:door_service_cequ#8();80ms去門抖動(dòng)toint_cequ#224;t0中斷時(shí)間segment_cequ#3;最多3段烹調(diào)注:上面數(shù)值前的#號(hào),是sn8asm的符號(hào),用于提示后面的是立即數(shù)。上而定義了 3個(gè)程序中會(huì)用到的參考值,順便提一下,在定義的時(shí)候加上注釋是有必耍的, 要不然時(shí)間久了你就乂不知道你定義的

32、到底是什么了。在上而的定義中,用的是匯編equ關(guān)鍵 字,在編譯過(guò)程中,程序里但凡出現(xiàn)了 equ前面的字段都會(huì)被其后面的值直接代替,因此,很 方便地減輕了程序員的工作。我們?cè)賮?lái)看看用sn8 c是如何定義這些相同的常量的:如:#define door_service_c 80 /80ms 去門抖動(dòng)#dcfinc toint.c224/t0 中斷時(shí)間#define segment_c3;最多 3 段烹調(diào)上面定義的3個(gè)量是與前面匯編當(dāng)中定義的3個(gè)常量是完全和同的。在進(jìn)行編譯預(yù)處理時(shí), 這些量就會(huì)被數(shù)值代替。還有一個(gè)特殊的地方,那就是一些數(shù)值列表,在匯編當(dāng)中,查表項(xiàng)都是放在code當(dāng)中的, 作為code

33、來(lái)處理,其實(shí)這些值也是常量,只不過(guò)他們的處理不同于一般常量而己,并且它們 共用一個(gè)入口。下面是一個(gè)匯編的表:disp_automenu:;顯示菜單用第二數(shù)字表格dw oooohdwoaelfh;a-1dw0ae2fhdwoae3thdw0ac4flidwoae5flidw0ae6flidw0ae7fh我們可以看到,匯編的表是用dw關(guān)鍵字定義一個(gè)word,它是存放在.code段里面的,通 過(guò)表頭地址來(lái)得到每一個(gè)相對(duì)應(yīng)的值。那么在sn8c里面乂如何來(lái)處理這些表呢?在講到表的處理之前,必須先提一提變量定義關(guān)鍵字的問(wèn)題。sn8c定義一個(gè)變量時(shí),可 以指明它所放置的地方(ram或rom),分別用關(guān)鍵字_

34、ram 和rom來(lái)指定存放的地點(diǎn), 如:unsigned int _ram ramveriable;將變量存放在 ram 中ram unsigned int ramveriable2;unsigned int _rom romveriable;將變赧存放在 rom 屮_rom unsigned int romveriable2;我們可以知道,當(dāng)一個(gè)最放到了 rom當(dāng)屮就沒(méi)法改變它的值了,其實(shí)就是我們說(shuō)的常最。在c當(dāng)屮,可以通過(guò)一個(gè)頭名稱來(lái)訪問(wèn)的變量類型比較多,其屮數(shù)組是比較方便的一種, 我們可以通過(guò)定義一個(gè)數(shù)組來(lái)存儲(chǔ)這些表的數(shù)值,然示通過(guò)對(duì)數(shù)纟r的訪問(wèn)來(lái)杏詢對(duì)應(yīng)的值。如:unsigned lo

35、ng rom disp_automenu=顯示菜單用第二數(shù)字表格0x0000,oxoae 1 f,0x0ae2f,0x0ae3f,0x0ae4f,0x0ae5f,0x0ae6f,0x0ae7f;這是一個(gè)與上面的匯編表完全相同的表,我們將它存放在_rom中,通過(guò)調(diào)用數(shù)組來(lái)查 表,這在后面將詳細(xì)介紹。而在程序中還冇另外一類的雖是會(huì)在程序中不斷被改變的,比如程序中的計(jì)數(shù)器,狀態(tài)寄 存器等等都會(huì)隨著程序的運(yùn)行而改變。我們將這一類量稱z為變量。我們先來(lái)看看匯編的定義變量的方法:.dataorgohtempids1tcmp2ds1temp3ds1temp4ds1led_dpds1stepds1 ;當(dāng)前狀態(tài)

36、上面的代碼定義了 tempi、temp2、temp3、temp4、led_dp> step6個(gè)變量,它們分別占用 一個(gè)byte的ram空間,那么程序當(dāng)屮就可以通過(guò)變量名對(duì)該變量的空間進(jìn)行讀寫。當(dāng)然在匯 編屮你也可以用一個(gè)變蜃名來(lái)訪問(wèn)兩個(gè)或多個(gè)ram空間,這類似于杏表的操作,其定義如下:job_modeds 2powcr_modeds 4對(duì)上面的job_mode變最對(duì)以通過(guò)job_mode和job_mode+1來(lái)讀寫定義的兩個(gè)存儲(chǔ)單元, 以此類推power_inode或其他多個(gè)ram空間定義的變蜃可以通過(guò)相同的方法來(lái)定義。可見(jiàn), sn8asm定義變屋的方法主要是通過(guò)ds關(guān)鍵字來(lái)申請(qǐng)盂要的變

37、雖空間,空間一旦被申請(qǐng),就 在整個(gè)程序流程里面被占用,也就是說(shuō)定義一個(gè)變量就少一個(gè)空間,這對(duì)于ram本身就很少 的單片機(jī)而言,不能不說(shuō)是一種浪費(fèi)°那么sn8c又是如何來(lái)定義變量的呢?要說(shuō)到c的變疑,就不能不提一提變量的有效作用域。我們知道,匯編當(dāng)中定義的變量都是在整個(gè)程序中冇效的,在程序中任何地方都可以改變 變量的值,這樣程序員就會(huì)經(jīng)常遇到這樣的悄況:在調(diào)試程序時(shí)發(fā)現(xiàn)變量的值有誤,卻無(wú)法判 斷變量到底在什么地方被錯(cuò)誤賦值或被賦予了錯(cuò)誤的值,從而不得不在整個(gè)程序中到處設(shè)置斷 點(diǎn),運(yùn)行多次才找出問(wèn)題的所在。這就是匯編當(dāng)屮變量定義造成不方便的地方!而c的變量的定義區(qū)分了作用域,分為全局變量

38、和局部變量,而區(qū)分定義這兩種變量的 方法很簡(jiǎn)單,只是在不同的位置定義就行了,這與標(biāo)準(zhǔn)c所規(guī)定的方法是一樣的,后面再詳細(xì) 討論。卜面是sn8 c定義的兒個(gè)變量:unsigned int tempi;unsigned int temp2;unsigned int temp3;unsigned int temp4;unsigned int led_dp;unsigned int step;當(dāng)前狀態(tài)unsigned long job_mode;unsigned long power_mode 1;float powervalue;int templ_l;有符號(hào)的long temp2_2;從上面的定義可

39、以看到c的變量不僅區(qū)分了作用域,還有不同長(zhǎng)度的變量類型,這樣就 方便了程序員的使用。與面向數(shù)學(xué)運(yùn)算的計(jì)算機(jī)相比,單片機(jī)的編程對(duì)變量類型或數(shù)據(jù)類型的選擇更具有關(guān)鍵性 意義。sn8系列單片機(jī)是8bi(處理器的單片機(jī),只有byie型的數(shù)據(jù)是處理器肓接支持的。對(duì) 于c這樣的高級(jí)語(yǔ)言,不管使用何種數(shù)據(jù)類型,雖然某一行程序從字面上看,其操作i 分簡(jiǎn)單, 然而,實(shí)際上系統(tǒng)的c編譯器需耍用一系列機(jī)器指令對(duì)其復(fù)朵的變量類型、數(shù)據(jù)類型的進(jìn)行處 理。相同的一行語(yǔ)句,變量選擇的類型不同,處理時(shí)就會(huì)產(chǎn)生很大的差別,產(chǎn)牛:的代碼更是差 別很多。特別是當(dāng)使川浮點(diǎn)變量時(shí),將明顯地贈(zèng)加運(yùn)算時(shí)間和程序的長(zhǎng)度。當(dāng)程序必須保證運(yùn) 算

40、精度時(shí),c編譯器將調(diào)用相應(yīng)的了程序庫(kù),把它們加到程序屮。然而許多不熟練的程序員, 在編寫c程序時(shí)往往會(huì)使用大量的、不必要的變屋類型。這就導(dǎo)致c編譯器相應(yīng)地增加所調(diào)用 的庫(kù)函數(shù)以處理大量增加的變量類型,并最終導(dǎo)致程序變得過(guò)于龐大,運(yùn)行速度減慢,甚至因 此會(huì)在link時(shí),出現(xiàn)因程序過(guò)大而裝不進(jìn)rom的情況。所以必須特別慎重的選擇變量和數(shù)據(jù) 類型。而對(duì)于有符號(hào)與無(wú)符號(hào)的變蜃類型。在編寫程序時(shí),如果使用signed和unsigned兩種數(shù) 據(jù)類型,那么就得使用兩種格式類型的庫(kù)函數(shù)。這將使得占用的存儲(chǔ)空間成倍增長(zhǎng)。因此在編 程時(shí),如果只強(qiáng)調(diào)程序的運(yùn)算速度而又不進(jìn)行負(fù)數(shù)運(yùn)算吋,最好采用無(wú)符號(hào)(unsign

41、ed)格式。note:1、選擇數(shù)據(jù)類型的時(shí)候,在能夠順利完成功能的情況下,請(qǐng)盡量選擇占空 間少的數(shù)據(jù)類型,這樣不管是在ram空間使用上還是在產(chǎn)生代碼效率上 都是有益的!2、能使用無(wú)符號(hào)數(shù)的都使用無(wú)符號(hào)數(shù),以免處理出錯(cuò),因?yàn)樾酒瑑?nèi)部是以 無(wú)符號(hào)數(shù)處理的。3、切記! c語(yǔ)言對(duì)大小寫敏感,在開(kāi)始定義變量的時(shí)候就要注意要有相應(yīng) 的規(guī)范可循,用駝峰式是一個(gè)好的選擇,這對(duì)于習(xí)慣于匯編的程序員來(lái) 說(shuō),可能不大習(xí)慣!當(dāng)然,在標(biāo)準(zhǔn)c編程當(dāng)中,經(jīng)常會(huì)冇為書(shū)寫方便,對(duì)數(shù)據(jù)類型進(jìn)行縮寫定義,這在sn8c 也是允許的。如:#define uchar unsigned char#define uint unsigned

42、int這樣,在以后的編程中,就可以用uchar代替unsigncd char,用uint代替unsigned int來(lái) 定義變量。33數(shù)據(jù)的存儲(chǔ)類型與存儲(chǔ)結(jié)構(gòu)在前面分析查表類型數(shù)據(jù)定義的時(shí)候已經(jīng)提到了數(shù)據(jù)在單片機(jī)里的存儲(chǔ),會(huì)分為rom和 ram兩部分,我們分別稱之為程序存儲(chǔ)器(rom)和數(shù)據(jù)存儲(chǔ)器(ram)。它們?cè)谖覀兙帉憛R 編的時(shí)候,會(huì)分別用關(guān)鍵字.code和.data來(lái)預(yù)先聲明。通常sn8系列單片機(jī)不用擴(kuò)展存儲(chǔ)器,它提供種類豐富的機(jī)型,你完全可以根據(jù)你的需 求來(lái)選擇合適的機(jī)型。因此,數(shù)據(jù)只存儲(chǔ)在片內(nèi),尋址也不存在片內(nèi)片外的區(qū)分。sn8p單片機(jī)的數(shù)據(jù)存儲(chǔ)器(ram)的結(jié)構(gòu)如下:bankoba

43、nklooooh007fhoo8ohooffhoo1ooolffhsn8p系列單片機(jī)的通用ram區(qū)的大小依不同的芯片而不同,但都是按bank來(lái)劃分, 每一個(gè)bank內(nèi)的地址為00hffh。而所有芯片的banko的80hffh的空間都是留給系統(tǒng) 專用的系統(tǒng)寄存器區(qū)。其實(shí)我們上面定義的變雖都是放在ram區(qū)的數(shù)據(jù)結(jié)構(gòu),在定義一個(gè)變雖時(shí),我們前面已 經(jīng)提到可以用_ram和rom關(guān)鍵字來(lái)指定存儲(chǔ)的地方,而變最定義一般都放在ram當(dāng)屮, 因而ram關(guān)鍵字是缺省項(xiàng)??聪旅娴睦樱簎nsigned int temp 1;unsigned int _ram temp2;_ram unsigned int tem

44、p3;unsigned long job_modc;unsigned long ram job_mode2;ram unsigned long job_mode3;float powervalue;float _ram powervalue;_ram float powcrvaluc;int templ_l;冇符號(hào)的int ram tempi-2;_ram temp 1-3;long temp2_2;其實(shí)上面的定義都是相同的效果,就是定義變量,并將其放置在數(shù)據(jù)存儲(chǔ)區(qū)(ram)內(nèi)。 也就是說(shuō),我們?cè)诙x一個(gè)變量,按我們c常用的方法定義就自動(dòng)地放到ram里了,缺省項(xiàng) 給我們帶來(lái)了很大的方便。上面已

45、經(jīng)說(shuō)明了,在ram存儲(chǔ)區(qū)內(nèi),80hffh是系統(tǒng)寄存器區(qū)。那么我們又是如何來(lái)定義系統(tǒng)寄存器區(qū)呢?我們先來(lái)看看系統(tǒng)寄存器都有哪些內(nèi)容:0123456789abcdef8lhrzyxpflagrbank9ampmap4con-bdamadmadbadrpedgec-p2m-p4mp5m-intrqintenoscm-wdtrtcorpclpchdp0p2p4p5tomtcomtcoctc1mtc1ctc1rstkpepourp2urp4urp5uryzfstk7lstk7hstk6lstk6hstk5lstk5hstk4lstk4hstk3lstk3hstk2lstk2hstk1lstk1hstko

46、lstkoh表32、sn8p系列單片機(jī)系統(tǒng)寄存器列表根據(jù)不同的芯片的資源,寄存器的內(nèi)容會(huì)隨之改變,但是他們定義的區(qū)域都不變。這些寄 存器都分別對(duì)應(yīng)了芯片內(nèi)部的資源,sn8 c針對(duì)這部分的系統(tǒng)資源,對(duì)這些寄存器進(jìn)行了定義,其定義的形式如下:# definel(*(_ram unsigned int*)ox8o)#defineh(*(_ram unsigned int*)ox8l)#definer(*(_ram unsigned int*)ox82)# definez(*(_ram unsigned int*)ox83)# definey(*(_ram unsigned int*)0x84)# d

47、efinex(*(_ram unsigned int*)ox85)#definepflag(*(_ram unsigned int*)ox86)這些定義都被包含在相應(yīng)芯片的頭文檔里(h),因此并不需要用戶自己去定義寄存器的相應(yīng)名稱,只需要在程序的開(kāi)頭包含相應(yīng)的頭文檔就行了。如下所示:#include <sn8p2708a.h>note:這些系統(tǒng)寄存器都是以大寫字母進(jìn)行定義的,在編寫程序時(shí)要注意這一 占/lit。程序流程控制是程序的精華所在,正確的程序流程/能實(shí)現(xiàn)正確的程序功能。安排精巧的 程序流程控制才可能使程序具有高效率。程序流程控制不管是在c還是在匯編中都是程序設(shè)計(jì) 者最值得思

48、考的地方。41順序結(jié)構(gòu)順序結(jié)構(gòu)是程序最基木的流程,其語(yǔ)句順序執(zhí)行,pc指針依次下移,是cpu內(nèi)部處理指 令的初始方法。這也是編程思維的蝕初級(jí)方式,也是程序的蝕基本方式和流程。順序結(jié)構(gòu)流程:圖41順序結(jié)構(gòu)流程其實(shí),其描述的是一個(gè)向量方式發(fā)展的問(wèn)題,是所有問(wèn)題發(fā)展和描述的基木方法,具有明 確的方向性和時(shí)間性,如圖中的a操作的發(fā)展方向只冇一個(gè),即接下來(lái)就是b操作,中間既沒(méi) 有反復(fù)也沒(méi)有曲折變化,b 一定發(fā)生在a的后面。我們平時(shí)可以看到的c語(yǔ)言的實(shí)現(xiàn):(微波爐開(kāi)機(jī)初始化)key_bibi_f = 1;上電響一聲menu_disp_h = oxfou;上電顯示 0:00menu_disp=();disp

49、5 = oxffu;上述簡(jiǎn)短的幾條語(yǔ)句分別完成一定冃的的初始化,雖然在這星沒(méi)冇強(qiáng)制要求什么樣的順 序,但是執(zhí)行過(guò)程屮是嚴(yán)格按語(yǔ)旬的先后來(lái)開(kāi)關(guān)目標(biāo)的。sn8asm的實(shí)現(xiàn):bobset key_bibi_f;上電響一聲mova,#ofohmovmenu_disp_h,amova,#00hmovmcnu_disp_l,amova,#llllllllbmovdisp5,a;上電顯示0:00這是一段功能完全與上面這段c相同的匯編實(shí)現(xiàn),我們可以看見(jiàn)在順序結(jié)構(gòu)的匯編語(yǔ)句 當(dāng)中沒(méi)有任何的跳轉(zhuǎn)和判斷,都是按原功能的順序來(lái)描述。從對(duì)比當(dāng)中我們完全可以找到它們的邏輯上的一一對(duì)應(yīng)關(guān)系。4.2選擇結(jié)構(gòu)事實(shí)上,完全順序結(jié)

50、構(gòu)的流程的程序很少,因?yàn)楹芏嗍虑椴⒉皇且环L(fēng)順,順流而下。很 多情況下,事件的發(fā)生都需要具備一定的條件,只冇一定條件下才冇可能實(shí)現(xiàn)。這就得使用選 擇結(jié)構(gòu)來(lái)描述。選擇結(jié)構(gòu)流程圖:圖4-2選擇結(jié)構(gòu)流程圖簡(jiǎn)單選擇結(jié)構(gòu)只判斷一個(gè)條件的真假來(lái)決定下面的需要執(zhí)行的操作,這是一個(gè)最簡(jiǎn)單的判 斷。c語(yǔ)言實(shí)現(xiàn):(bcd碼調(diào)整)if(result_buf > oxoa)result_buf = input + 6;rcsult_buf = input;我們看見(jiàn)在c語(yǔ)言當(dāng)中,我們用判斷語(yǔ)句來(lái)實(shí)現(xiàn)這樣一個(gè)判斷邏輯,不管是什么樣的條 件,我們只計(jì)算其真假,做出判斷。ifelse是一個(gè)非常好的判斷組合,很容易用它來(lái)

51、完 成下列我們用匯編來(lái)實(shí)現(xiàn)的功能。sn8匯編實(shí)現(xiàn):emprs a,#oah nop bobtso fcjmp $+3 bomov a,ybomov a,yadd a,#6h;調(diào)整后的數(shù)放在a事實(shí)上,在匯編程序中,我們會(huì)遇到幾種情況的條件選擇:一是當(dāng)條件是一個(gè)位變量時(shí),我們可以直接川bobts指令來(lái)進(jìn)行判斷。一是當(dāng)條件是是否滿足一個(gè)預(yù)定的值,我們可以用cmprs指令來(lái)進(jìn)行判斷,當(dāng)然也可以 將英轉(zhuǎn)化為標(biāo)志位來(lái)判斷。也可以用減法的方法將其轉(zhuǎn)化成為標(biāo)志位進(jìn)行判斷,就看需要來(lái)安 排了更 7/k o o 0 o 0 oa、串行多分支結(jié)構(gòu)流程:事實(shí)上大多數(shù)時(shí)候,單個(gè)的條件無(wú)法分析判斷復(fù)雜的問(wèn)題,冇時(shí)候一個(gè)結(jié)

52、果的出現(xiàn)需要很 多個(gè)條件同吋成立,而每一個(gè)條件成立,又都有不同的結(jié)果產(chǎn)生,這樣就會(huì)有一系列的有層次 的判斷!圖4-3串行多分支結(jié)構(gòu)流程圖c用if, else if嵌套來(lái)實(shí)現(xiàn):if(key_bibi_f)buzzejtime = d_buzzer_time 1;響聲長(zhǎng)愆,200msbuzzer_not = d_buzzer_not3;要響兒次,#1else if(end_bibi_f)/buzzer 10buzzejtime = d_buzzer_time2;響聲長(zhǎng)愆,500msbuzzer_not = d_buzzer_not 1;要響幾次,#10else if(segment_bibi_f) /buzzer20buzzejtime = d_buzzer_time2;響聲長(zhǎng)愆,500msbuzzer_not = d_buzzer_not 1;要響兒次,#4說(shuō)明:kcy_bibi_f;按鍵響聲請(qǐng)求標(biāo)志end_bibi_f;烹調(diào)結(jié)束響聲請(qǐng)求標(biāo)志sgment_bibi_f;段切換響聲請(qǐng)求標(biāo)志按鍵響聲:200ms/l次結(jié)束響聲:5()()ms/5次段切換響聲:500ms/2次問(wèn):sn8 asm怎么實(shí)現(xiàn)?sn8 asm的實(shí)現(xiàn):

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論