第六講 實驗5-實驗8 知識點:
1、 學會畫程序流程圖
2、 流程控制語句 if(){}else{}用法
3、 操作符 ”~ ”、“!”、“&&”含義
4、 帶參函數
5、 函數調用
6、 理解宏定義 #define “替換”作用
7、 循環語句 for 的用法
8、 庫函數 unsigned char_cror_ (unsigned char, unsigned char);
unsigned char _crol_ (unsignedchar, unsigned char);含義
9、 C51 擴展類型 code含義
10、 流程控制語句:switchcase 用法
11、 數組定義、引用方式
12、 延時函數
一、51單片機軟件延時:
1、 幾種周期介紹
周期名稱
| 描述
| 時間
| 振蕩
| 單片機提供時鐘脈沖信號
的振蕩源的周期
| T=1/f
| 狀態
| 振蕩周期經二分頻后得到
的
| 2T
| 機器
| CPU 可以完成一個獨立操
作所需要的周期
| 12T
| 指令
| 指 CPU 完成一條操作所需
的全部時間
| n*12T
|
2、指令:
1、MUL、DIV:僅有的 4 周期指令
2、包含 DPTR 和 PC 的指令均為 2 周期指令
3、所有的絕對跳轉和條件轉移指令,均為 2 周期指令
4、所有包括 A 寄存器的指令,均為單周期指令
5、位操作指令中,ANL 和 ORL 是 2 周期指令
6、所有包含立即地址的指令,除 INC direct 及 DEC direct 外,均為 2 周期指令
7、剩下的均為單周期指令。如:
voiddelay(uint z)
{
uinti ,j;
for(i = z; i> 0;i--)
for(j =0; j < 921; j++)
}
分析:
1.先計算你單片機的振蕩(時鐘)周期 T=1/晶振(11.0592MHZ)
2.一次 i--操作為 12T
3.忽略變量定義,上述延時函數共需時間:921*z*12T
4.帶入 T:921*12*T*z 約為 z us
3、計算誤差出現的原因:
1.軟件仿真時,函數調用的時候入棧出棧操作的耗時。
2.指令周期隨指令的不同而不同導致的誤差。
3.中斷的影響。
4.變量的范圍超過,從而與預計時間不一樣。
while(i--):如果 i 為 char 型,執行一次大概為 5us 左右;如果 i 為 int 型則執行一次大概為 10us 左右。注意:軟件延時通常用于時序要求較高的編程中,其它需延時較長的地方必須采用單片機內部定時器。
二、#define與 typedef 區別
1、typedef 的用法
在 C 語言中,typedef 常用來定義一個標識符及關鍵字的別名,它是語言編譯過程的一部分, 但它并不實際分配內存空間,
如:typedef int INT;
2、#define 的用法
#define 為一宏定義語句,通常用它來定義常量(包括無參量與帶參量),以及用來實現那些 “表面似和善、背后一長串”的宏,它本身并不在編譯過程中進行,而是在這之前(預處理過程)就已經完成了,但也因此難以發現潛在的錯誤及其它代碼維護問題,如:
#define INT int
#define TRUE 1
#define Add(a,b) ((a)+(b));
#define Loop_10 for (inti=0; i<10; i++)
3、typedef 與#define 的區別
從以上的概念便也能基本清楚,typedef 只是為了增加可讀性而為標識符另起的新名稱(僅僅只是個別名),而#define原本在 C 中是為了定義常量,到了 C++,const、enum、 inline 的出現使它也漸漸成為了起別名的工具。有時很容易搞不清楚與 typedef 兩者到 底該用哪個好,如#define INT int 這樣的語句,用 typedef 一樣可以完成,用哪個好 呢?我主張用 typedef,因為在早期的許多 C 編譯器中這條語句是非法的,只是現今的 編譯器又做了擴充。
為了盡可能地兼容,一般都遵循#define 定義“可讀”的常量以及一些宏語句的任務, 而 typedef 則常用來定義關鍵字、冗長的類型的別名。
宏定義只是簡單的字符串代換(原地擴展),而 typedef 則不是原地擴展,它的新名字具 有一定的封裝性,以致于新命名的標識符具有更易定義變量的功能。請看上面第一大點 代碼的第三行:typedef (int*) pINT;以及下面這行:#define pINT2 int*效果相同?實則不同!實踐中見差別:pINT a,b;的效果同 int *a;int *b;表示定 義了兩個整型指針變量。而 pINT2 a,b;的效果同 int*a, b;表示定義了一個整型指針 變量 a 和整型變量 b。
typedef 的四個用途和兩個陷阱
用途一: 定義一種類型的別名,而不只是簡單的宏替換
用途二: 用在舊的 C 代碼中(具體多舊沒有查),幫助 struct。
typedef struct tagPOINT
{
int x;
int y;
}POINT;
POINT p1; // 這樣就比原來的方式少寫了一個 struct,比較省事,尤其在大量 使用的時候 或許,在 C++中,typedef 的這種用途二不是很大,但是理解了它,對掌握 以前的舊代碼還是有幫助的,畢竟我們在項目中有可能會遇到較早些年代遺留下來的代 碼。
用途三: 用 typedef 來定義與平臺無關的類型。用途四:為復雜的聲明定義一個新的簡單的別名。
陷阱一: 記住,typedef 是定義了一種類型的新別名,不同于宏,它不是簡單的字符串替換。字符串替換就行。
陷阱二: typedef 在語法上是一個存儲類的關鍵字(如 auto、extern、mutable、static、 register 等一樣),雖然它并不真正影響對象的存儲特性,如: typedef static intINT2; //不可行 編譯將失敗,會提示“指定了一個以上的存儲類”。
三、按鍵:
按鍵是單片機系統中最常用的器件。各種儀器儀表、家用電器操作面板上都離不開按鍵,是最基本的輸入部件。因此,掌握按鍵輸入電路設計、按鍵驅動程序設計是十分必要的。按鍵的分類:從單片機獲取按鍵信號類型的角度來講,可以分為模擬按鍵和數字按鍵;從按鍵與單片機IO 端口對應關系上來講,可以分為獨立按鍵和矩陣式按鍵。獨立按鍵很簡單,就是一個按鍵對應一個 IO 端口;而矩陣式按鍵則相對復雜一些,通過行與列的交叉組合成 i 行*j 列個 按鍵。
按鍵的有效方式:
按下有效、按下松開(抬起)有效、長按 n 秒有效、連按 n 次有效、組合按鍵有效等。按鍵驅動程序設計步驟:
讀取鍵值—按鍵消抖—鍵值處理
四、cror 與 crol 的區別
循環右移與循環左移

這是以前給小學生培訓單片機做的一套講義,盡可能的做到了通俗易懂,現分享給大家,絕對的純原創資料.
全部資料下載地址(共15章,pdf格式):http://www.zg4o1577.cn/bbs/dpj-98524-1.html
|