機(jī)電之家資源網(wǎng)
單片機(jī)首頁(yè)|單片機(jī)基礎(chǔ)|單片機(jī)應(yīng)用|單片機(jī)開(kāi)發(fā)|單片機(jī)文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開(kāi)發(fā)
培訓(xùn)信息
贊助商
分支程序設(shè)計(jì)
分支程序設(shè)計(jì)
 更新時(shí)間:2008-7-27 16:15:21  點(diǎn)擊數(shù):2
【字體: 字體顏色
 第一部分課程學(xué)習(xí)了如何建立Keil C的編程環(huán)境,并了解了一些C語(yǔ)言的基礎(chǔ)知識(shí),這一部分將通過(guò)一個(gè)鍵控流水燈程序的分析來(lái)學(xué)習(xí)分支程序設(shè)計(jì)。

  1 程序功能與實(shí)現(xiàn)

  硬件電路描述如下:89S52單片機(jī)的P1口接有8個(gè)LED,當(dāng)某一端口輸出為“0”時(shí),相應(yīng)的LED點(diǎn)亮,P3.2、P3.3、P3.4、P3.5分別接有四個(gè)按鈕K1~K4,按下按鈕時(shí),相應(yīng)引腳被接地。現(xiàn)要求編寫可鍵控的流水燈程序,當(dāng)K1按下時(shí),開(kāi)始流動(dòng),K2按下時(shí)停止流動(dòng),全部燈滅,K3使燈由上往下流動(dòng),K4使燈由下往上流動(dòng)。

  下面首先給出程序,然后再進(jìn)行分析。

例1:鍵控流水燈的程序

#include "reg51.h"

#include "intrins.h"

#define uchar unsigned char

void mDelay(unsigned int DelayTime)

{ unsigned int j=0;

for(;DelayTime>0;DelayTime--)

{ for(j=0;j<125;j++) 

{;} }}

uchar Key()

{ uchar KeyV;

uchar tmp; 

P3=P3|0x3c; //四個(gè)按鍵所接位置

KeyV=P3;

if((KeyV|0xc3)==0xff) //無(wú)鍵按下

return(0);

mDelay(10); //延時(shí),去鍵抖

KeyV=P3;

if((KeyV|0xc3)==0xff)

return(0);

else

{ for(;;){ tmp=P3;

if((tmp|0xc3)==0xff)

break;}

return(KeyV);}}

void main()

{ unsigned char OutData=0xfe; 

bit UpDown=0;

bit Start=0;

uchar KValue;

for(;;)

{ KValue=Key();

switch (KValue)

{ case 0xfb: //P3.2=0,Start

{ Start=1; 

break; }

case 0xf7: //P3.3=0,Stop

{ Start=0;

break; }

case 0xef: //P3.4=0 Up

{ UpDown=1;

break; }

case 0xdf: //P3.5=0 Down

{ UpDown=0;

break; }

}

if(Start)

{ if(UpDown)

OutData=_crol_(OutData,1); 

else

OutData=_cror_(OutData,1); P1=OutData;

}

else

P1=0xff; //否則燈全滅

mDelay(1000);

}

}


  輸入源程序,保存為exam21.c,建立名為exam21的工程文件,選擇的CPU型號(hào)為AT89S52,在Debug頁(yè)加入-ddpj6,以便使用單片機(jī)實(shí)驗(yàn)仿真板,其他按默認(rèn)設(shè)置。正確編譯、鏈接后進(jìn)入調(diào)試模式,點(diǎn)擊Peripherals->51實(shí)驗(yàn)仿真板,打開(kāi)實(shí)驗(yàn)仿真板,選擇Run(全速運(yùn)行),此時(shí)實(shí)驗(yàn)仿真板沒(méi)有變化,用鼠標(biāo)點(diǎn)擊上方的K1按鈕,松開(kāi)后即可看到Led“流動(dòng)”起來(lái),初始狀態(tài)是由下往上流動(dòng),點(diǎn)擊K3按鈕,可改變LED的流動(dòng)方向,改為由上往下流動(dòng),點(diǎn)擊K4按鈕,又可將流動(dòng)方向變換回來(lái)。點(diǎn)擊K2按鈕,可使流動(dòng)停止,所有LED“熄滅”。

   1.1 程序分析

  本程序中運(yùn)用到了兩種選擇結(jié)構(gòu)的程序:if和switch,if語(yǔ)句最常用的形式是:

   if(關(guān)系表達(dá)式)語(yǔ)句1 else 語(yǔ)句2

   1.2 關(guān)系運(yùn)算符和關(guān)系表達(dá)式

  所謂“關(guān)系運(yùn)算”實(shí)際上是兩個(gè)值作一個(gè)比較,判斷其比較的結(jié)果是否符合給定的條件。關(guān)系運(yùn)算的結(jié)果只有2種可能,即“真”和“假”。例:3>2的結(jié)果為真,而3<2的結(jié)果為假。

  C語(yǔ)言一共提供了6種關(guān)系運(yùn)算符:“<”(小于)、“<=”(小于等于)、“>”(大于)、“>=(大于等于)”、“==”(等于)和“!=”(不等于)。

  用關(guān)系運(yùn)算符將兩個(gè)表達(dá)式連接起來(lái)的式子,稱為關(guān)系表達(dá)式。例:

  a>b,a+b>b+c,(a=3)>=(b=5)等都是合法的關(guān)系表達(dá)式。關(guān)系表達(dá)式的值只有兩種可能,即“真”和“假”。在C語(yǔ)言中,沒(méi)有專門的邏輯型變量,如果運(yùn)算的結(jié)果是“真”,用數(shù)值“1”表示,而運(yùn)算的結(jié)果是“假”則用數(shù)值“0”表示。

  如式子:x1=3>2的結(jié)果是x1等于1,原因是3>2的結(jié)果是“真”,即其結(jié)果為1,該結(jié)果被“=”號(hào)賦給了x1,這里須注意,“=”不是等于之意(C語(yǔ)言中等于用“==”表示),而是賦值號(hào),即將該號(hào)后面的值賦給該號(hào)前面的變量,所以最終結(jié)果是x1等于1。

  式子:x2=3<=2的結(jié)果是x2=0,請(qǐng)自行分析。

  2 邏輯運(yùn)算符和邏輯表達(dá)式

  用邏輯運(yùn)算符將關(guān)系表達(dá)式或邏輯量連接起來(lái)的式子就是邏輯表達(dá)式。C語(yǔ)言提供了三種邏輯運(yùn)算符:“&&”(邏輯與)、“||”(邏輯或)和“!”(邏輯非)。

  C語(yǔ)言編譯系統(tǒng)在給出邏輯運(yùn)算的結(jié)果時(shí),用“1”表示真,而用“0”表示假,但是在判斷一個(gè)量是否是“真”時(shí),以0代表“假”,而以非0代表“真”,這一點(diǎn)務(wù)必要注意。以下是一些例子:

 。1) 若a=10,則!a的值為0,因?yàn)?0被作為真處理,取反之后為假,系統(tǒng)給出的假的值為0。

 。2) 如果a=--2,結(jié)果與上完全相同,原因也同上,初學(xué)時(shí)常會(huì)誤以為負(fù)值為假,所以這里特別提醒注意。

 。3) 若a=10,b=20,則a&&b的值為1,a||b的結(jié)果也為1,原因?yàn)閰⒂谶壿嬤\(yùn)算時(shí)不論a與b的值究竟是多少,只要是非零,就被當(dāng)作是“真”,“真”與“真”相與或者相或,結(jié)果都為真,系統(tǒng)給出的結(jié)果是1。

  3 if語(yǔ)句

  if語(yǔ)句是用來(lái)判定所給定的條件是否滿足根據(jù)判定的結(jié)果(真或假)決定執(zhí)行給出的兩種操作之一。

  C語(yǔ)言提供了三種形式的if語(yǔ)句

  1. if(表達(dá)式) 語(yǔ)句 

  如果表達(dá)式的結(jié)果為真,則執(zhí)行語(yǔ)句,否則不執(zhí)行

2. if(表達(dá)式) 語(yǔ)句1 else 語(yǔ)句2

 如果表達(dá)式的結(jié)果為真,則執(zhí)行語(yǔ)句1,否則執(zhí)行語(yǔ)句2

3.if(表達(dá)式1) 語(yǔ)句1

else if(表達(dá)式2) 語(yǔ)句2

else if(表達(dá)式3) 語(yǔ)句3



else if(表達(dá)式m) 語(yǔ)句m

else 語(yǔ)句n

這條語(yǔ)句執(zhí)行如圖14所示。

  圖14
    上述程序中的如下語(yǔ)句:

if((KeyV|0xc3)==0xff) //無(wú)鍵按下

return(0);

  是第一種if語(yǔ)句的應(yīng)用。該語(yǔ)句中“|”符號(hào)是C語(yǔ)言中的位運(yùn)算符,按位相或的意思,相當(dāng)于匯編語(yǔ)言中“ORL”指令,將讀取的P3口的值KeyV與0xc3(即11000011B)按位或,如果結(jié)果為0xff(即11111111B)說(shuō)明沒(méi)有鍵被按下,因?yàn)橹虚g4位接有按鍵,如果有鍵按下,那么P3口值的中間4位中必然有一位或更多位是“0”。該語(yǔ)句中的“return(0)”是返回之意,相當(dāng)于匯編語(yǔ)言中的“ret”指令,通過(guò)該語(yǔ)句可以帶返回值,即該號(hào)中的數(shù)值,返回值就是這個(gè)函數(shù)的值,在這個(gè)函數(shù)被調(diào)用時(shí),用了如下的形式:KValue=Key();因此,返回的結(jié)果是該值被賦給Kvalue這個(gè)變量。因此,如果沒(méi)有鍵被按下,則直接返回,并且Kvalue的值將變?yōu)?。如果有鍵被按下,那么return(0)將不會(huì)被執(zhí)行。

  程序其他地方還有這樣的用法,請(qǐng)注意觀察與分析。

程序中:

if(Start)

{… 燈流動(dòng)顯示的代碼 }

else

P1=0xff; //否則燈全滅

  是if語(yǔ)句的第二種用法,其中Start是一個(gè)位變量,該變量在main函數(shù)的中被定義,并賦以初值0,該變量在按鍵K1被按下后置為1,而K2按下后被清為0,用來(lái)控制燈流動(dòng)是否開(kāi)始。這里就是判斷該變量并決定燈流動(dòng)是否開(kāi)始的代碼,觀察if后面括號(hào)中的寫法,與其他語(yǔ)言中寫法很不一樣,并沒(méi)有一個(gè)關(guān)系表達(dá)式,而僅僅只有一個(gè)變量名,C根據(jù)這個(gè)量是0還是1來(lái)決定程序的走向,如果為1則執(zhí)行燈流動(dòng)顯示的代碼,如果為0,則執(zhí)行P1=0xff;語(yǔ)句?梢(jiàn),在C語(yǔ)言中,數(shù)據(jù)類型的概念比其他很多的編程語(yǔ)言要“弱化”,或者說(shuō)C更著重從本質(zhì)的角度去考慮問(wèn)題,if后面的括號(hào)中不僅可以是關(guān)系表達(dá)式,也可以是算術(shù)表達(dá)式,還可以就是一個(gè)變量,甚至是一個(gè)常量,不管怎樣,C總是根據(jù)這個(gè)表達(dá)式的值是零還是非零來(lái)決定程序的走向,這個(gè)特點(diǎn)是其他中所沒(méi)有的,請(qǐng)注意理解。

  if語(yǔ)句的第三種用法在本程序中沒(méi)有出現(xiàn),下面我們舉一例說(shuō)明。在上述的鍵盤處理函數(shù)Key中,如果沒(méi)鍵被按下,返回值是0,如果有鍵被按下,經(jīng)過(guò)去鍵抖的處理,將返回鍵值,程序中的“return(KeyV);”即返回鍵值。當(dāng)K1被按下(P3.2接地)時(shí),返回值是0xfb(11111011B),而K2被按下(P3.3接地)時(shí),返回值是0xf7(11110111B),K3被按下(P3.4接地)時(shí),返回值是0xef(11101111B),K4被按下(P3.5接地)時(shí),返回值是0xdf(11011111B),該值將被賦給主程序中調(diào)用鍵盤程序的變量KValue。程序用了另一種選擇結(jié)構(gòu)switch進(jìn)行處理,關(guān)于switch將在稍后介紹。下面用if語(yǔ)句來(lái)改寫:

if(KValue==0xfb)

{Start=1;}

else if(KValue==0xf7)

{Start=0;}

else if(KValue==0xef)

{UpDown=1;}

else if(KValue==0xdf)

{UpDown=0;}

else

{//意外處理}

……

  程序中第一條語(yǔ)句判斷Kvalue是否等于0xfb,如果是就執(zhí)行Start=1;執(zhí)行完畢即退出if語(yǔ)句,執(zhí)行if語(yǔ)句下面的程序,如果Kvalue不等于0xfb就轉(zhuǎn)去下一個(gè)else if即判斷Kvalue是否等于0xf7,如果等于則執(zhí)行Start=0;,并退出if語(yǔ)句…這樣一直到最后一個(gè)else if后面的條件判斷完畢為止,如果所有的條件都不滿足,那么就去執(zhí)行else后面的語(yǔ)句(通常這意味著出現(xiàn)了異常,在這里來(lái)統(tǒng)一處理這種異常情況)。

4 if語(yǔ)句的嵌套

  在if語(yǔ)句中又包含一個(gè)或多個(gè)語(yǔ)句稱為if語(yǔ)句的嵌套。一般形式如下

if()

if() 語(yǔ)句1

else 語(yǔ)句2

else

if() 語(yǔ)句3

else 語(yǔ)句4

應(yīng)當(dāng)注意if與else的配對(duì)關(guān)系,else總是與它上面的最近的if配對(duì)。如果寫成

if()

if()語(yǔ)句1

else

語(yǔ)句2

  編程者的本意是外層的if與else配對(duì),縮進(jìn)的if語(yǔ)句為內(nèi)嵌的if語(yǔ)句,但實(shí)際上else將與縮進(jìn)的那個(gè)if配對(duì),因?yàn)閮烧咦罱瑥亩爝~岐義。為避免這種情況,建議編程時(shí)使用大括號(hào)將內(nèi)嵌的if語(yǔ)句括起來(lái),這樣可以避免出現(xiàn)這樣的問(wèn)題。

5 swich語(yǔ)句

  當(dāng)程序中有多個(gè)分支時(shí),可以使用if嵌套實(shí)現(xiàn),但是當(dāng)分支較多時(shí),則嵌套的if語(yǔ)層數(shù)多,程序冗長(zhǎng)而且可讀性降低。C語(yǔ)言提供了switch語(yǔ)句直接處理多分支選擇。Switch的一般形式如下:

switch(表達(dá)式)

{case 常量表達(dá)式1:語(yǔ)句1

case 常量表達(dá)式2:語(yǔ)句2

……

case 常量表達(dá)式n:語(yǔ)句n

default:語(yǔ)句n+1

}

  說(shuō)明:switch后面括號(hào)內(nèi)的“表達(dá)式”,ANSI標(biāo)準(zhǔn)允許它為任何類型;當(dāng)表達(dá)式的值與某一個(gè)case后面的常量表達(dá)式相等時(shí),就執(zhí)行此case后面的語(yǔ)句,若所有的case中的常量表達(dá)式的值都沒(méi)有與表達(dá)式值匹配的,就執(zhí)行default后面的語(yǔ)句;每一個(gè)case的常量表達(dá)式的值必須不相同;各個(gè)case和default的出現(xiàn)次序不影響執(zhí)行結(jié)果。

  另外特別需要說(shuō)明的是,執(zhí)行完一個(gè)case后面的語(yǔ)句后,并不會(huì)自動(dòng)跳出switch,轉(zhuǎn)而去執(zhí)行其后面的語(yǔ)句,如上述例子中如果這么寫

switch (KValue)

{ case 0xfb: Start=1; 

case 0xf7: Start=0;

case 0xef: UpDown=1;

case 0xdf: UpDown=0;

}

if(Start)

{ ……}

  假如KValue的值是0xfb,則在轉(zhuǎn)到此處執(zhí)行“Start=1;”后,并不是轉(zhuǎn)去執(zhí)行switch語(yǔ)句下面的if語(yǔ)句,而是將從這一行開(kāi)始,依次執(zhí)行下面的語(yǔ)句即“Start=0;”、“UpDown=1;”“UpDown=0;”,顯然,這樣不能滿足要求,因此,通常在每一段case的結(jié)束加入“break;”語(yǔ)句,使流程序退出switch結(jié)構(gòu),即終止switch語(yǔ)句的執(zhí)行。
  • 上一篇: 分支程序設(shè)計(jì)
  • 下一篇: C語(yǔ)言的一些特點(diǎn)
  • 發(fā)表評(píng)論   告訴好友   打印此文  收藏此頁(yè)  關(guān)閉窗口  返回頂部
    熱點(diǎn)文章
     
    推薦文章
     
    相關(guān)文章
    網(wǎng)友評(píng)論:(只顯示最新5條。)
    關(guān)于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機(jī)電之家 | 會(huì)員助手 | 免費(fèi)鏈接

    點(diǎn)擊這里給我發(fā)消息66821730(技術(shù)支持)點(diǎn)擊這里給我發(fā)消息66821730(廣告投放) 點(diǎn)擊這里給我發(fā)消息41031197(編輯) 點(diǎn)擊這里給我發(fā)消息58733127(審核)
    本站提供的機(jī)電設(shè)備,機(jī)電供求等信息由機(jī)電企業(yè)自行提供,該企業(yè)負(fù)責(zé)信息內(nèi)容的真實(shí)性、準(zhǔn)確性和合法性。
    機(jī)電之家對(duì)此不承擔(dān)任何保證責(zé)任,有侵犯您利益的地方請(qǐng)聯(lián)系機(jī)電之家,機(jī)電之家將及時(shí)作出處理。
    Copyright 2007 機(jī)電之家 Inc All Rights Reserved.機(jī)電之家-由機(jī)電一體化網(wǎng)更名-聲明
    電話:0571-87774297 傳真:0571-87774298
    杭州濱興科技有限公司提供技術(shù)支持

    主辦:杭州市高新區(qū)(濱江)機(jī)電一體化學(xué)會(huì)
    中國(guó)行業(yè)電子商務(wù)100強(qiáng)網(wǎng)站

    網(wǎng)站經(jīng)營(yíng)許可證:浙B2-20080178-1