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