一、 引子
被控制對象、構(gòu)造、工作原理、性能--控制要求—控制功能與結(jié)構(gòu)—執(zhí)行元件—技術(shù)要求與性能—原理圖硬件選擇--仿真圖與控制軟件(控制指令)--仿真與調(diào)試修改(各控制點(diǎn)信號特性、軟硬件、器件參數(shù)等)--施工圖(PCB板等)--加工制造—測試安裝—調(diào)試—維護(hù)等
模擬電路的的工作狀態(tài)可以在線性工作區(qū)、非線性工作區(qū)、截止區(qū),在截止區(qū)工作者表現(xiàn)了開關(guān)、高電位與低電位兩種狀態(tài),將這種特性用作信號處理,則成為數(shù)字電路的基礎(chǔ)。數(shù)字電路對信號的處理,用數(shù)學(xué)理論表示則有布爾代數(shù),也就是0,1,也稱作邏輯代數(shù)。用二進(jìn)制數(shù)學(xué)進(jìn)行數(shù)字計(jì)算來代替原來的十進(jìn)制,則需要有用二進(jìn)制表示的十個(gè)數(shù)字符號0-9,這便有了4位二進(jìn)位數(shù)0000表示的數(shù)字對照表及其換算公式。人們發(fā)現(xiàn),要充分發(fā)揮二進(jìn)制的長處(用數(shù)字電路的狀態(tài)組合表示信息),也就是說:將二進(jìn)制的排列組合充分利用,采用十六進(jìn)制更合適—充分利用數(shù)字電路及其二進(jìn)制的優(yōu)勢。而十六進(jìn)制恰好是兩個(gè)8位,那么,用8位二進(jìn)制則可表示更多的信息—更復(fù)雜的信息。這便有了0000 0000 ---- 1111 1111,也就是:00 ---- FF。
二進(jìn)制
| 十進(jìn)制
| 二進(jìn)制
| 十進(jìn)制
| 二進(jìn)制
| 十六進(jìn)制
| 二進(jìn)制
| 十六進(jìn)制
| 0000
| 0
| 0100
| 4
| 1000
| 8
| 1100
| C
| 0001
| 1
| 0101
| 5
| 1001
| 9
| 1101
| D
| 0010
| 2
| 0110
| 6
| 1010
| A
| 1110
| E
| 0011
| 3
| 0111
| 7
| 1011
| B
| 1111
| F
|
注意51系列8位(bit)一個(gè)字節(jié),應(yīng)用匯編語言簡潔高效。16位的處理器需要用兩個(gè)0000 0000H 表示。16或32位以上,使用操作系統(tǒng)(WinCE、Linux等)更有效,可以利用大量的、底層的、專業(yè)化、標(biāo)準(zhǔn)化的面向控制的庫函數(shù)(如:API等)。高級語言具有對底層硬件的無關(guān)性,則可移植性好、可重用性好;高級語言描述控制更接近人的自然語言,可描述性好,表達(dá)力好。Linux的代碼與模塊的開放性、可剪裁性、自我構(gòu)造等特點(diǎn)使其前景廣闊。8位1個(gè)字節(jié),16位2個(gè)字節(jié),32位4個(gè)字節(jié),64位8個(gè)字節(jié)。16進(jìn)制表示:8位單片機(jī)00H~FFH,16位計(jì)算機(jī)0000H~FFFFH,32位計(jì)算機(jī)0000 0000H~FFFF FFFFH,64位計(jì)算機(jī)呢?
用Proteus+Keil軟件組合進(jìn)行實(shí)踐訓(xùn)練,逐級學(xué)習(xí)和理解硬件配置及其C語言的編程技術(shù)。
單字與單詞、單詞與句子、控制與計(jì)算或判斷、函數(shù)及其調(diào)用、故事情節(jié)與段落,整體問題的分解與實(shí)現(xiàn)(組合)
二、 C語言指令說明
C語言是在匯編語言的基礎(chǔ)上發(fā)展演變而來的,它的最初功能是在計(jì)算機(jī)硬件上進(jìn)行操作,也就是說,是為計(jì)算機(jī)的操作系統(tǒng)而設(shè)計(jì)的語言。后來的發(fā)展,可以為非操作系統(tǒng)(應(yīng)用程序—軟件)編寫指令,但其與底層硬件的關(guān)系一直被保留著。如可以進(jìn)行位操作等,對于在單片機(jī)上應(yīng)用該語言提供了便利條件。由于涉及到為非操作系統(tǒng)編寫指令,其計(jì)算方法的指令、數(shù)據(jù)類型與結(jié)構(gòu)、較抽象的詞法(變量類型、算符等)、較復(fù)雜的語法結(jié)構(gòu)等應(yīng)運(yùn)而生。由此可以應(yīng)對更豐富與復(fù)雜的故事情節(jié)—軟件系統(tǒng)。對于更復(fù)雜的軟件系統(tǒng)、更大的軟件系統(tǒng),使用C++語言則是更合適的。雖然C++語言是面向?qū)ο蟮模牵匀灰獞?yīng)用C語言提供的結(jié)構(gòu)化的編程機(jī)制來實(shí)現(xiàn)面向?qū)ο笾械膶ο髢?nèi)部的底層細(xì)節(jié)實(shí)現(xiàn),如成員函數(shù)等。面向?qū)ο蟮幕A(chǔ)是面向過程。C++是面向?qū)ο蟮恼Z言,C是面向過程的,學(xué)起來比C語言困難得多,所以不太適合程序編寫與設(shè)計(jì)的初學(xué)者,尤其是學(xué)習(xí)目的是用C語言來編寫單片機(jī)的控制系統(tǒng)指令。C++中對象的概念、由對象構(gòu)成的類的概念對初學(xué)者都是難以建立的。其實(shí),本質(zhì)上來說,對象是自然事物、事務(wù)的數(shù)量化抽象及其表達(dá)。也就是說,表達(dá)了對象要表達(dá)的事物的諸多屬性而已。或說表達(dá)了對象要表達(dá)的概念的內(nèi)涵與外延。內(nèi)涵表征該事物的最基本特征,外延表征該事物基本特征以外的關(guān)系密切的其他特征。但該特征或?qū)傩耘c基本特征構(gòu)成的組合體,必定是該事物。也就是說,特征屬性組成的數(shù)據(jù)結(jié)構(gòu)體為統(tǒng)一整體。作為一種語言,用來寫什么--歌詞、詩歌、小說、散文、科技論文、控制軟件、管理軟件、計(jì)算軟件、分析軟件、學(xué)習(xí)軟件、……格式與風(fēng)格、模式與規(guī)則
1. C語言的特點(diǎn)—函數(shù)型及其組合與調(diào)用
(1)語言簡潔、緊湊,使用方便、靈活。 32個(gè)關(guān)鍵字、9種控制語句,程序形式自由
(2)運(yùn)算符豐富。34種運(yùn)算符
(3)數(shù)據(jù)類型豐富,具有現(xiàn)代語言的各種數(shù)據(jù)結(jié)構(gòu)。
(4)具有結(jié)構(gòu)化的控制語句 ,是完全模塊化和結(jié)構(gòu)化的語言。
(5)語法限制不太嚴(yán)格,程序設(shè)計(jì)自由度大。
(6)允許直接訪問物理地址,能進(jìn)行位操作,能實(shí)現(xiàn)匯編語言的大部分功能,可直接對硬件進(jìn)行操作。兼有高級和低級語言的特點(diǎn) 。
(7)目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高。只比匯編程序生成的目標(biāo)代碼效率低10%-20%。
(8)程序可移植性好(與匯編語言比),基本上不做修改就能用于各種型號的計(jì)算機(jī)和各種操作系統(tǒng)。
C語言的基本結(jié)構(gòu)—語法問題:C語言的詞匯及其結(jié)構(gòu)—詞匯的書寫順序
2. C語言的詞匯—數(shù)據(jù)類型、運(yùn)算符與保留字
C語言的詞匯主要有:數(shù)據(jù)類型、數(shù)組、結(jié)構(gòu)體、操作符(運(yùn)算符)、控制指令、內(nèi)部函數(shù)(標(biāo)準(zhǔn)庫函數(shù))、用戶自定義函數(shù)等
3. C語言的結(jié)構(gòu)—語法
C語言的語句表達(dá)方式—詞匯組合方式—(語言結(jié)構(gòu))主要有:表達(dá)式、控制結(jié)構(gòu)(順序、選擇、循環(huán))等,函數(shù)調(diào)用、復(fù)合語句(用{}標(biāo)記的多個(gè)語句組合)、結(jié)構(gòu)體、共用體、文件等
C語言的程序表述方式—程序結(jié)構(gòu)主要是用函數(shù)。主函數(shù)中主要包含的是具有各自功能的函數(shù)的引用—調(diào)用等。當(dāng)然,最簡單的主函數(shù)自身也是一個(gè)普通函數(shù)。函數(shù)概念及其應(yīng)用可以使得程序概念清晰、邏輯與層次分明、便于理解和交流、便于維護(hù)和擴(kuò)充。
4. C語言的表述—處理對象的特點(diǎn)及其描述方式
a) 處理對象及其特點(diǎn)—數(shù)據(jù)格式
b) 控制語言與軟件算法
計(jì)算機(jī)執(zhí)行指令,通常是由程序指針PC按照程序的書寫順序逐行進(jìn)行的。如果需要改變順序,則通過調(diào)用指針PC的指向命令來進(jìn)行。這些指向命令如:if……,for……,while……,等,通常稱為控制語句。
在程序編寫過程中,順序執(zhí)行是計(jì)算機(jī)程序語言的最簡單、最基本、最常見的一種運(yùn)行方式,C語言也是如此。對于簡單的順序執(zhí)行控制,可直接用C語言符號系統(tǒng)編寫在編譯器的編譯界面上。所謂的簡單控制程序,一般是指程序的行數(shù)較少(語句較少),控制運(yùn)行邏輯簡單明了(這些都是針對人的大腦內(nèi)存處理能力而言的,也就是每個(gè)語句及其執(zhí)行的控制,可以在大腦中順序執(zhí)行,寫過以后不需要再記住已經(jīng)寫過的語句)。
對于比較復(fù)雜的順序控制,應(yīng)該先用邏輯框架、偽碼書寫自然段的大意要求,再逐個(gè)填寫“自然段”(一個(gè)階段性的、相對完整的控制時(shí)段的指令集)的大意要求,最終填寫具體詳細(xì)的控制指令。
對于帶有運(yùn)行條件及其控制的指令集(程序組、軟件),先用邏輯框架、偽碼書寫控制條件及其分支的要求,然后再寫自然段的大意要求,再逐個(gè)填寫“自然段”(一個(gè)階段性的、相對完整的控制時(shí)段的指令集)的大意要求,最終填寫每個(gè)自然段具體詳細(xì)的順序控制指令。
對于帶有運(yùn)行條件及其循環(huán)控制的指令集(程序組、軟件),先用邏輯框架、偽碼書寫控制條件、循環(huán)要求及其循環(huán)終止、分支的要求框架,然后再寫自然段的大意要求,尤其是循環(huán)及其終止(循環(huán)退出),再逐個(gè)填寫“自然段”(一個(gè)階段性的、相對完整的控制時(shí)段的指令集)的大意要求,最終填寫每個(gè)自然段具體詳細(xì)的順序控制指令。
為了保證書寫結(jié)果的正確,需要在程序編譯器上進(jìn)行編譯驗(yàn)證,還要在硬件開發(fā)機(jī)上進(jìn)行運(yùn)行驗(yàn)證。當(dāng)然,也可以在虛擬的軟件開發(fā)產(chǎn)品上進(jìn)行仿真運(yùn)行驗(yàn)證。
為了通過多層驗(yàn)證,對于復(fù)雜、大型的控制軟件,尤其是多重分支、循環(huán)等的指令集,可以先編寫1~2兩個(gè)分支與循環(huán),驗(yàn)證無誤,再逐步增加分支的復(fù)雜性、循環(huán)的多層性。避免一次調(diào)試錯(cuò)誤與警告過多,影響開發(fā)效率、過多返工,工作心情等。經(jīng)驗(yàn)豐富了,可以逐步根據(jù)自身的能力與條件減少不必要的環(huán)節(jié),提高開發(fā)效率。
c) 描述框架—流程圖與偽碼
計(jì)算機(jī)程序除過用數(shù)據(jù)類型、算法和表達(dá)式(主要是運(yùn)算符號)構(gòu)成以外,還有必要的運(yùn)算控制。控制的基本結(jié)構(gòu)(底層結(jié)構(gòu))包括順序結(jié)構(gòu)、選擇結(jié)構(gòu)、循環(huán)結(jié)構(gòu),實(shí)現(xiàn)復(fù)雜功能的程序都是他們的各種組合。
a) 游戲 <wbr> <wbr> <wbr> <wbr> <wbr>51系列 <wbr> <wbr>c語言 <wbr> <wbr> <wbr> <wbr>proteus-keil順序結(jié)構(gòu):順序結(jié)構(gòu)通常是用來解決那些按照步步緊連的次序可以進(jìn)行計(jì)算的問題的,用計(jì)算的邏輯關(guān)系圖,也就高級語言的流程圖表達(dá)如圖3-8所示。
b) 選擇結(jié)構(gòu): 選擇結(jié)構(gòu)通常是用來解決那些按照某些條件來決定執(zhí)行那個(gè)運(yùn)算問題的。指令的運(yùn)行次序由IF……THEN……或者IF……ELSE……來控制進(jìn)行問題計(jì)算的,用計(jì)算的邏輯關(guān)系圖,也就是計(jì)算機(jī)高級語言的流程圖表達(dá)如圖3-9所示。其執(zhí)行的順序是,先計(jì)算表達(dá)式得值,若表達(dá)式的值為真,執(zhí)行語句1表示的指令,否則執(zhí)行語句2表達(dá)的指令。
c) 游戲 <wbr> <wbr> <wbr> <wbr> <wbr>51系列 <wbr> <wbr>c語言 <wbr> <wbr> <wbr> <wbr>proteus-keil循環(huán)結(jié)構(gòu): 循環(huán)結(jié)構(gòu)通常是用來解決那些需要累加重復(fù)的計(jì)算問題的,用計(jì)算的邏輯關(guān)系圖,也就是計(jì)算機(jī)高級語言的流程圖表達(dá)如圖3-10所示,其執(zhí)行的順序是,先判斷循環(huán)控制條件(表達(dá)式的值),若表達(dá)式的值為真,執(zhí)行循環(huán)體表示的指令,否則執(zhí)行語句2表達(dá)的指令。還有一種形式的執(zhí)行的順序是,先執(zhí)行循環(huán)體表示的指令(語句),后判斷循環(huán)控制條件表達(dá)式的值,若表達(dá)式的值為真,繼續(xù)執(zhí)行循環(huán)體表示的指令,表達(dá)式的值為假,則結(jié)束循環(huán)體。
計(jì)算機(jī)的應(yīng)用就是將現(xiàn)實(shí)問題通過各種描述和變換,用計(jì)算機(jī)高級語言“書寫”,并實(shí)際運(yùn)行計(jì)算機(jī)的各種動(dòng)作來實(shí)現(xiàn)工作。
計(jì)算機(jī)軟件的基本結(jié)構(gòu),是在計(jì)算機(jī)程序結(jié)構(gòu)的基礎(chǔ)上發(fā)展演變而來的。計(jì)算機(jī)軟件架構(gòu)與其需求的內(nèi)容、規(guī)模、功能及復(fù)雜性(人可理解的層次性、概念的大小層級等)等密切相關(guān)。為了在人的大腦可理解的前提下,將實(shí)際問題轉(zhuǎn)換成計(jì)算機(jī)語言可表征的形式,需要在實(shí)際問題與計(jì)算機(jī)語言之間添加適當(dāng)層級的軟件模型。這些模型主要是表征計(jì)算機(jī)信息處理單元之間的邏輯關(guān)聯(lián)與數(shù)據(jù)、控制關(guān)系等。
d) 語句選擇
5. C語言的程序示例—故事內(nèi)容與形式—想說什么?
l 例-1 信息輸出—單函數(shù)(主函數(shù)也是普通函數(shù))
#include
void main( )
{
printf ("This is a C program.\n");
}
說明: main-主函數(shù)名, void-函數(shù)類型
• 每個(gè)C程序必須有一個(gè)主函數(shù)main
• { }是函數(shù)開始和結(jié)束的標(biāo)志,不可省
• 每個(gè)C語句以分號 ; 結(jié)束
• 使用標(biāo)準(zhǔn)庫函數(shù)時(shí)應(yīng)在程序開頭一行寫: #include ,稱為頭文件,該頭文件中包含著用戶需要的標(biāo)準(zhǔn)庫函數(shù)。stdio.h中包含著輸出函數(shù):printf ();輸入函數(shù)scanf()等。
• 表示注釋。注釋只是給程序編寫與閱讀人員看,對編譯和運(yùn)行不起作用,既機(jī)器不運(yùn)行該信息。所以可以用漢字或英文字符表示,可以出現(xiàn)在一行中的最右側(cè),也可以單獨(dú)成為一行。還可以用//表示。
• 這是一個(gè)C語言的基本格式。也是一個(gè)結(jié)構(gòu)化程序設(shè)計(jì)的基本形式之一—順序結(jié)構(gòu)。
•標(biāo)準(zhǔn)庫函數(shù)常用的有:
l 例-2 求兩數(shù)之和—單函數(shù)(主函數(shù)也是普通函數(shù))—故事內(nèi)容與形式—想說什么?
#include
void main( )
{
int a,b,sum;
a=123; b=456; sum=a+b;
printf(″sum is %d\n″,sum);
}
l 例-3 輸出3個(gè)數(shù)中較大者
—多函數(shù)(主函數(shù)引用—調(diào)用普通函數(shù)—自定義函數(shù))(判斷與選擇)—故事內(nèi)容與形式—想說什么?
#include
void main( ) 求3個(gè)數(shù)中較大者
{
int max(int x,int y);
int a, b, c;
scanf(″%d,%d″,&a,&b);
c=max(a,b);
printf(″max=%d\\n″,c);
}
int max(int x, int y)
{
int z;
if (x>y) z=x; /*判斷與選擇—結(jié)構(gòu)化程序設(shè)計(jì)之分支結(jié)構(gòu)
else z=y;
return (z); /*被調(diào)用的函數(shù)max用return語句將z的值返回給主調(diào)函數(shù)max
}
程序說明:
l C程序總是從main函數(shù)開始執(zhí)行的,與main函數(shù)的位置無關(guān)。
l C程序書寫格式自由,一行內(nèi)可以寫幾個(gè)語句, 一個(gè)語句可以分寫在多行上,C程序沒有行號。
l 每個(gè)語句和數(shù)據(jù)聲明的最后必須有一個(gè)分號。
l C語言本身沒有輸入輸出語句。輸入和輸出的操作是由標(biāo)準(zhǔn)庫函數(shù)scanf和printf等函數(shù)來完成的。使用方法是調(diào)用。C對輸入輸出實(shí)行“函數(shù)化”。
l 例-4 將16進(jìn)制數(shù)FF賦51單片機(jī)的P1口,字節(jié)傳送數(shù)據(jù)—信息
#include //預(yù)處理指令,將頭文件reg51.h轉(zhuǎn)換為與C語言一致的格式
void main( ) //主函數(shù)
{ //函數(shù)體開始
P1= 0xFF; //賦值語句,函數(shù)體內(nèi)容 - 將16進(jìn)制數(shù)FF賦P1口
} //函數(shù)體結(jié)束
l 例-5 延時(shí)函數(shù)—子程序(自定義函數(shù)—常用函數(shù))
#include
#define uchar unsigned char //定義了DelayMS等
#define uint unsigned int //定義了x,i等
void DelayMS(uint x) //延時(shí)函數(shù) — 非主函數(shù),用戶定義的函數(shù),可被調(diào)用
{
while(x--) ; //條件循環(huán)語句,C語言的保留字,x每循環(huán)一次,自動(dòng)減1,直至x為0,終止循環(huán)
}
void main()//主函數(shù)
{
P1=0x00; //將16進(jìn)制數(shù)00H賦給P1口,字節(jié)傳送,語句
DelayMS(200); //調(diào)延時(shí)函數(shù),并傳遞數(shù)值x=200,語句
P1=0xff; //將16進(jìn)制數(shù)FF賦給P1口,字節(jié)傳送,語句
DelayMS(200); //調(diào)延時(shí)函數(shù),并傳遞數(shù)值x=200,語句
}
l 例-6 掃描函數(shù)—子程序—用戶定義的函數(shù)—判斷與選擇(邏輯運(yùn)算)—條件
uchar Keys_Scan() //鍵盤掃描函數(shù)
{
uchar sCode,kCode,i,k;
P1=0xf0; //高4位置1,低4 位置0,令P1口狀態(tài)為1111 0000B,有鍵按下,兩位導(dǎo)通,則會(huì)出現(xiàn)高位0
文本框: //鍵值判斷函數(shù) bit pkey(void) { P1=0xf0; if(P1!=0xf0) { Delayt(25); if(P1!=0xf0) return 1; else return 0; } else return 0; } if((P1&0xf0)!=0xf0) //用位邏輯運(yùn)算中的與&運(yùn)算(遇0則0),確認(rèn)高4位是否有0,有鍵按下,成立執(zhí)行return(-1);
{ //不等的條件成立,則執(zhí)行一下語句
DelayMS(2);//延時(shí)函數(shù)調(diào)用,防抖動(dòng)
if((P1&0xf0)!=0xf0)//再判斷有鍵按下否,成立執(zhí)行return(-1);
{//不等的條件成立,則執(zhí)行一下語句
sCode=0xfe; //行掃描碼初值1111 1110B
for(k=0;k<4;k++) //對4 行分別進(jìn)行掃描
{
P1=sCode; //行掃描碼初值賦給P1口=1111 1110B
if((P1&0xf0)!=0xf0)//再判斷1110 1110B
{//不等的條件成立,則執(zhí)行一下語句,否則else
kCode=~P1;//取反后賦給列碼0001 0001B—即0x11
for(i=0;i<16;i++) //查表得到按鍵序號并返回,i=16則再判斷
if(kCode==KeyCodeTable) //掃描出16種狀態(tài)
return(i); //按照列碼對照表return(i),返回for(i=0;i<16;i++)
}
else
sCode=_crol_(sCode,1);//51庫函數(shù),行碼左移1位補(bǔ)1,如:1111 1110B成為1111 1101B
}//移位以后,去執(zhí)行for(k=0;k<4;k++) 行碼右移1位補(bǔ)1,_cror_(sCode,1);
}
}
return(-1);//函數(shù)調(diào)用結(jié)尾,返回函數(shù)運(yùn)行結(jié)束后的入口處。
}
程序說明:
在后續(xù)的逐級實(shí)踐過程中,通過實(shí)例實(shí)踐及其程序注解與程序說明,介紹C語言的基本概念、數(shù)據(jù)類型、算符及其約定、語句語法、函數(shù)構(gòu)成、程序構(gòu)成等。
這是一個(gè)常用程序段—子程序—標(biāo)準(zhǔn)程序—自定義函數(shù),通過端口掃描而獲得輸入數(shù)據(jù)或控制輸出數(shù)據(jù),達(dá)到節(jié)省位或字節(jié)的目的—節(jié)約硬件資源。
關(guān)于掃描,可以從位及其取反實(shí)現(xiàn)流水燈著手來理解。可以通過移位實(shí)現(xiàn)流水燈—掃描。可以通過字節(jié)數(shù)據(jù)(01H,02H,04H,08H,10H,20H,40H,80H)的端口發(fā)送實(shí)現(xiàn)流水燈—掃描。可以通過數(shù)據(jù)表(DB 01H,02H,04H,08H,10H,20H,40H,80H)實(shí)現(xiàn)流水燈—掃描。可以通過循環(huán)跳轉(zhuǎn)實(shí)現(xiàn)流水燈—掃描。
數(shù)學(xué)中的邏輯運(yùn)算被用來處理判斷與選擇—條件控制(按照某個(gè)限制條件來執(zhí)行動(dòng)作)。主要有兩種:
第一種:if語句,用來做兩分支選擇
主要有 ® if(表達(dá)式) 語句;
® if(表達(dá)式) 語句1; else 語句2;
® if(表達(dá)式1) 語句1; else if(表達(dá)式2) 語句2; else if(表達(dá)式) 語句3;else if(表達(dá)式4) 語句4;……; else 語句n;
第二種:switch語句,用來做多分支選擇
® switch(表達(dá)式)
{
case 常量表達(dá)式1:語句1; case 常量表達(dá)式2:語句2; case 常量表達(dá)式3:語句3;……;default:語句n+1;
|