機電之家資源網(wǎng)
單片機首頁|單片機基礎|單片機應用|單片機開發(fā)|單片機文案|軟件資料下載|音響制作|電路圖下載 |嵌入式開發(fā)
培訓信息
贊助商
循環(huán)程序設計
循環(huán)程序設計
 更新時間:2008-7-27 16:15:16  點擊數(shù):2
【字體: 字體顏色
  前面的課程中學習了分支程序的設計,下面學習程序設計中另一種常用的程序結(jié)構――循環(huán)結(jié)構。
  1.循環(huán)程序簡介
  在一個實用的程序中,循環(huán)結(jié)構是必不可少的。循環(huán)是反復執(zhí)行某一部分程序行的操作。有兩類循環(huán)結(jié)構:
 。1)當型循環(huán),即當給定的條件成立時,執(zhí)行循環(huán)體部分,執(zhí)行完畢回來再次判斷條件,如果條件成立繼續(xù)循環(huán),否則退出循環(huán)。
 。2)直到型循環(huán),即先執(zhí)行循環(huán)體,然后判斷給定的條件,只要條件成立就繼續(xù)循環(huán),直到判斷出給定的條件不成立時退出循環(huán)。
下面我們就通過一些例子來看C語言提供的循環(huán)語句,及如何利用這些循環(huán)語句寫循環(huán)程序。
  例1 使P1口所接LED以流水燈狀態(tài)顯示
#include "reg51.h"
#include"intrins.h" //該文件包含有_crol_(…)函數(shù)的說明
void mDelay(unsigned int DelayTime)
{ unsigned int  j=0;
for(;DelayTime>0;DelayTime--)
{ for(j=0;j<125;j++) {;} }}
void main()
{ unsigned char OutData=0xfe; 
while(1)
{ P1=OutData;
OutData=_crol_(OutData,1); //循環(huán)左移
mDelay(1000); /*延時1000毫秒*/
}}
  程序分析:輸入源程序,并命名為exam31.c,建立并設置工程。這個例子使用實驗仿真板演示的過程請讀者自行完成,如果在演示時,發(fā)現(xiàn)燈“流動”的速度太快,幾乎不能看清,那么可以將mDelay(1000)中的1000改大一些,如2000、3000或更大。軟件仿真無法實現(xiàn)硬件實驗一樣的速度,這是軟件仿真的固有弱點,下面介紹如何用我們提供的具有仿真功能的實驗電路板來實現(xiàn)這個例子。
將實驗板帶的串口電纜一端連接到PC機的串口,另一端連到實驗板上,設置工程,選中Debug頁,點擊右側(cè)的“Use Keil Monitor-51 Drive”,選中“Load Application at Start”和“Go Till main”,如圖1所示。選擇完成后,點擊“Setting”按鈕,選擇你所用的PC上的串口(COM1或COM2),波特率(通?梢允褂38400),其他設置一般不需要更改,如圖2所示。點擊“OK”回到Debug頁面后即可完成設置。

圖15 選擇keil Monitor51進行程序調(diào)試

圖16 設置Keil Monitor51的調(diào)試參數(shù)
  編譯、連接正確后,點擊菜單DebugStart/Stop Debug Session,可以看到在窗口右下角的命令窗口提示正確連接到了Monitor-51,如圖3所示。此時,即可使用Keil提供的單步、過程單步、執(zhí)行到當前行、設置斷點等調(diào)試方法進行程序的調(diào)試。

圖15 正確連接上了Keil Monitor51

  程序分析:這段程序中在兩處用到了循環(huán)語句,首先是主程序中使用了“while(1){……}”這樣的循環(huán)語句寫法;其次是延時程序,使用了for循環(huán)語句的形式。這些循環(huán)語句是怎么樣使用的呢?下面我們就對循環(huán)語句的用法作一個具體的介紹。
  2.循環(huán)語句
  2.1 while語句
  While語句用到實現(xiàn)“當型”循環(huán)結(jié)構,其一般形式如下:
while(表達式) 語句
  當表達式為非0值(真)時,執(zhí)行while語句中的內(nèi)嵌語句。其特點是:先判斷表達式,后執(zhí)行語句。
  在例1中,表達式使用了一個常數(shù)“1”,這是一個非零值,即“真”,條件總是滿足,語句總是會被執(zhí)行,構成了無限循環(huán),這使得{}中的程序一直不斷地執(zhí)行下去,直到斷電為止。下面再舉一例說明:
  例2:當K1鍵被按下時,流水燈工作,否則燈全部熄滅。
#include "reg51.h"
#include"intrins.h" //該文件包含有_crol_(…)函數(shù)的說明
void mDelay(unsigned int DelayTime)
{ ……與例1同}
void main()
{ unsigned char OutData=0xfe; 
while(1)
{ P3|=0x3c;
while((P3|0xfb)!=0xff)
{ P1=OutData;
OutData=_crol_(OutData,1); //循環(huán)左移
mDelay(1000); /*延時1000毫秒*/}
P1=0xff;  
}}
  程序分析:程序中第二個while語句表達式用來判斷K1鍵是否被按下,如被按下,則執(zhí)行循環(huán)體內(nèi)的程序,否則執(zhí)行“P1=0xff;”程序行,實現(xiàn)的題目的要求。有關實驗,請讀者自行完成。
  2.2 do-while語句
  do-while語句用來實現(xiàn)“直到型”循環(huán),特點是先執(zhí)行循環(huán)體,然后判斷循環(huán)條件是否成立。其一般形式如下:
do
  循環(huán)體語句
while(表達式)
  對同一個問題,既可以用while語句處理,也可以用do-while語句處理。但是這兩個語句是有區(qū)別的,下面我們用do-while語句改寫例2。
  例3:用do-while語句實現(xiàn)如下功能:K1按下,流水燈工作,K2松開,燈全熄滅。
#include "reg51.h"
#include"intrins.h" //該文件包含有_crol_(…)函數(shù)的說明
void mDelay(unsigned int DelayTime)
{……與例1同 }
void main()
{ unsigned char OutData=0xfe; 
while(1)
{ P3|=0x3c;
do
{ P1=OutData;
OutData=_crol_(OutData,1); //循環(huán)左移
mDelay(1000); /*延時1000毫秒*/
} while((P3|0xfb)!=0xff)
P1=0xff;
}}
  程序分析:和例2相比,該程序除main函數(shù)中用do-while替代while外,沒有其他的不同,初步設想,如果while()括號中的表達式為“真”即K1鍵被按下,應該執(zhí)行程序體,否則不執(zhí)行,效果與例2相同。但是事實上,實際做這個練習就會發(fā)現(xiàn),不論K1是否被按下,流水燈都在工作,為何會有這么樣的結(jié)果呢?
  單步運行程序可以發(fā)現(xiàn),如果K1鍵被按下,的確執(zhí)行循環(huán)體內(nèi)的程序,與設想相同。而當K1沒有被按下時,按設想,循環(huán)體內(nèi)的程序不應該被執(zhí)行,但事實上,do后面的語句至少要被執(zhí)行一次才去判斷條件是否成立,所以程序依然會去執(zhí)行do后的循環(huán)體部分,只是在判斷條件不成立(K1沒有被按下)后,轉(zhuǎn)去執(zhí)行P1=0xff;然后又繼續(xù)循環(huán),而下一次循環(huán)中又會先執(zhí)行一次循環(huán)體部分,因此,K1是否被按下的區(qū)別僅在于“P1=0xff;”這一程序行是否會被執(zhí)行到。
  2.3 for語句
  C語言中的for語句使用最為靈活,不僅可以用于循環(huán)次數(shù)已經(jīng)確定的情況,而且可以用于循環(huán)次數(shù)不確定而只給出循環(huán)結(jié)束條件的情況。
  for語句的一般形式為:
for(表達式1;表達式2;表達式3) 語句
它的執(zhí)行過程是:
(1) 先求解表達式1
(2) 求解表達式2,其值為真,則執(zhí)行for語句中指定的內(nèi)嵌語句(循環(huán)體),然后執(zhí)行第(3)步,如果為假,則結(jié)束循環(huán)。
(3) 求解表達式3
(4) 轉(zhuǎn)回上面的第(2)步繼續(xù)執(zhí)行。
for語句典型的應用是這樣一種形式:
for(循環(huán)變量初值;循環(huán)條件;循環(huán)變量增值) 語句 
  例1中的延時程序有這樣的程序行:“for(j=0;j<125;j++) {;} ”,執(zhí)行這行程序時,首先執(zhí)行j=0,然后判斷j是否小于125,如果小于125則去執(zhí)行循環(huán)體(這里循環(huán)體沒有做任何工作),然后執(zhí)行j++,執(zhí)行完后再去判斷j是否小于125……如此不斷循環(huán),直到條件不滿足(j>=125)為止。
如果用while語句來改寫,應該這么寫
j=0;
while(j<125)
{ j++; }
  可見,用for語句更簡單、方便。
  如果變量初值在for語句前面賦值,則for語句中的表達式1應省略,但其后的分號不能省略。例1延時程序中有:“for(;DelayTime>0;DelayTime--){…}”的寫法,省略掉了表達式1,因為這里的變量DelayTime是由參數(shù)傳入的一個值,不能在這個式子里賦初值。
  表達式2也可以省略,但是同樣不能省略其后的分號,如果省略該式,將不判斷循環(huán)條件,循環(huán)無終止地進行下去,也就是認為表達式始終為真。
表達式3也可以省略,但此時編程者應該另外設法保證循環(huán)能正常結(jié)束。
表達式1、2和3都可以省略,即形成如for(;;)的形式,它的作用相當于是while(1),即構一個無限循環(huán)的過程。
  循環(huán)可以嵌套,如上述延時程序中就是兩個for語句嵌套使用構成二重循環(huán),C語言中的三種循環(huán)語句可以相互嵌套。
3.break語句
  在一個循環(huán)程序中,可以通過循環(huán)語句中的表達式來控制循環(huán)程序是否結(jié)束,除此之外,還可以通過break語句強行退出循環(huán)結(jié)構。
  例4:開機后,全部LED不亮,按下K1則從LED1開始依次點亮,至LED8后停止并全部熄滅,等待再次按下K1鍵,重復上述過程。如果中間K2鍵被按下,LED立即全部熄滅,返回起始狀態(tài)。
#include "reg51.h"
#include"intrins.h" //該文件包含有_crol_(…)函數(shù)的說明
void mDelay(unsigned int DelayTime)
{…與例1同}
void main()
{ unsigned char OutData=0xfe; 
unsigned char i;
while(1)
{ P3|=0x3c;
if((P3|0xfb)!=0xff) //K1鍵被按下
{ for(i=0;i<8;i++)
{ mDelay(1000); /*延時1000毫秒*/
OutData=0xfe;
if((P3|0xf7)!=0xff) //K2鍵被按下
break;
OutData=_crol_(OutData,i);
P1&=OutData;
}
}
P1=0xff;
}
}
  請讀者輸入程序、建立工程,使用實驗仿真板或者實驗板來驗證這一功能,注意,K2按下的時間必須足夠長,因為這里每1s才會檢測一次K2是否被按下。本程序文件夾下的exam34.avi記錄了實驗過程,可供參考。
  程序分析:開機后,檢測到K1鍵被按下,執(zhí)行一個for(i=0;i<8;i++){…}的循環(huán),即循環(huán)8次后即停止,而在這段循環(huán)體中,又用到了如下的程序行:“ if((P3|0xf7)!=0xff) break;”即判斷K2是否按下,如果K2被按下,則立即結(jié)束本次循環(huán)。
  4.continue語句
  該語句的用途是結(jié)束本次循環(huán),即跳過循環(huán)體中下面的語句,接著進行下一次是否執(zhí)行循環(huán)的判定。
  Continue語句和break語句的區(qū)別是:continue語句只結(jié)束本次循環(huán),而不是終止整個循環(huán)的執(zhí)行;而break語句則是結(jié)束整個循環(huán)過程。
  例5:將上述例4中的break語句改為continue語句,會有什么結(jié)果?
程序分析:開機后,檢測到K1鍵被按下,各燈開始依次點亮,如果K2鍵沒有被按下,將循環(huán)8次,直到所有燈點亮,又加到初始狀態(tài),即所有燈滅,等待K1按鍵。如果K2鍵被按下,不是立即退出循環(huán),而只是結(jié)束本次循環(huán),即不執(zhí)行continue語句下面的“OutData=_crol_(OutData,i); P1&=OutData;”語句,但要繼續(xù)轉(zhuǎn)去判斷循環(huán)條件是否滿足,因此,不論K2鍵是否被按下,循環(huán)總是要經(jīng)過8次才會終止,差別在于是否執(zhí)行了上述兩行程序。如果上述程序行有一次未被執(zhí)行,意味著有一個LED未被點亮,因此,如果按下K2過一段時間(1、2s)松開,中間將會有一些LED不亮,直到最后一個LED被點亮,又回到全部熄滅的狀態(tài),等待K1被按下。本程序文件夾中的exam35.avi記錄了實驗現(xiàn)象,可供參考。
  練習:每點亮2個LED后,第三個LED不亮,請編程實現(xiàn)。
  • 上一篇: 單片機內(nèi)部資源編程
  • 下一篇: 分支程序設計
  • 發(fā)表評論   告訴好友   打印此文  收藏此頁  關閉窗口  返回頂部
    熱點文章
     
    推薦文章
     
    相關文章
    網(wǎng)友評論:(只顯示最新5條。)
    關于我們 | 聯(lián)系我們 | 廣告合作 | 付款方式 | 使用幫助 | 機電之家 | 會員助手 | 免費鏈接

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

    主辦:杭州市高新區(qū)(濱江)機電一體化學會
    中國行業(yè)電子商務100強網(wǎng)站

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