創(chuàng)客飛夢空間 首先,讓杰杰來介紹一下我們的美女小編 “CK” 這篇文章是我們的美女小編 CK 的處女作,她可是忙了一下午的,非常認(rèn)真負(fù)責(zé),非常棒了,鼓勵一下,我得給她加個雞腿了,嗯~,我沒找錯人哈哈哈,你們可以在后臺找到她的哈哈哈,她回不回復(fù)我就不知道了。。。 一上來就貼個代碼: 我們熟悉的單片機(jī)編程: 這種結(jié)構(gòu)基本上都是在main函數(shù)開始完成一些初始化,然后在主循環(huán)里周期性地調(diào)用一些函數(shù)。
這應(yīng)該是最常見的結(jié)構(gòu)了吧,學(xué)過單片機(jī)的都知道在 main 函數(shù)里面的那個“while(1)”。筆者也對這個 while(1) 印象深刻,因?yàn)樗屛颐靼琢藛纹瑱C(jī)程序運(yùn)行的歸宿就在這。 在不考慮中斷的情況下,整個單片機(jī)的最根本任務(wù)就是這個 while(1) 循環(huán)。在此稱它為“主循環(huán)”,認(rèn)為 main 函數(shù)及其調(diào)用的所有子函數(shù)(以及子函數(shù)再次調(diào)用的函數(shù)……)都在一個“主進(jìn)程”里。
在初學(xué)單片機(jī)時(shí),大部分精力都放在單片機(jī)和各個模塊的驅(qū)動上,所以在開始相當(dāng)長的一段時(shí)間里采用的都是這種程序結(jié)構(gòu)。而 Fun1、Fun2……這些函數(shù)完成的功能也都是比較簡單的,每個函數(shù)完成一個簡單的小功能,然后順序執(zhí)行就可以組合完成某個功能。 需要強(qiáng)調(diào)的是,這些函數(shù)雖然功能簡單,但是占用 CPU 資源不一定少,比如最簡單的一個獨(dú)立按鍵掃描程序: 注意到這個程序里有一個 5ms 延時(shí)函數(shù),在延時(shí)的這段時(shí)間里單片機(jī)運(yùn)行一些無意義的指令消耗時(shí)間。在此期間其他任務(wù)得不到運(yùn)行,整個進(jìn)程阻塞在延時(shí)函數(shù)這個地方。并且,如果按鍵一直按下沒有釋放的話,程序?qū)⑼A粼?while(key==0); 處。 簡單來說就是,系統(tǒng)一直在等你的釋放,而單片機(jī)運(yùn)算速度特別快,這就是占用了單片機(jī)的所有資源了,這樣子,下一個任務(wù)在你不釋放的時(shí)候就沒辦法得到運(yùn)行。就必須得等到上一個任務(wù)做完了才能做下一個任務(wù)。這樣子做,就是最低效率的了。
主函數(shù)順序調(diào)用結(jié)構(gòu)的特點(diǎn)
首先,正如它的名稱是“順序調(diào)用”,任務(wù)之間的運(yùn)行順序是固定不變的,當(dāng)然不可能有優(yōu)先級區(qū)別,它只適合完成那些周期性循環(huán)的工作。 單片機(jī)在這個任務(wù)運(yùn)行的時(shí)候,其他任務(wù)是得不到運(yùn)行的。并且如果這個任務(wù)由于某種原因卡住了,它將阻塞整個進(jìn)程的運(yùn)行。 任務(wù)執(zhí)行的并行與否是相對而言的,要根據(jù)具體的情況。如果我們的要求不高,當(dāng)然用這種簡單的結(jié)構(gòu)是最方便的了,但是這種簡單的結(jié)構(gòu)也確實(shí)存在很多不足,有很多可以改進(jìn)的地方。
在此我們明確一下這種結(jié)構(gòu)的特點(diǎn): 1、由主循環(huán)調(diào)用的任務(wù)的執(zhí)行順序是固定的。 2、由主循環(huán)調(diào)用的任務(wù)都只能單獨(dú)地運(yùn)行,進(jìn)入一個任務(wù),就不能處理其他任務(wù)。 3、這些任務(wù)執(zhí)行時(shí)間一般會比較長(相對后面幾章改造過的任務(wù)函數(shù)而言),某一個任務(wù)里面的延時(shí)函數(shù)會造成整個進(jìn)程被延時(shí)。
主循環(huán)調(diào)用任務(wù)函數(shù)的一種非常常用的結(jié)構(gòu)。到目前為止,在主進(jìn)程的構(gòu)建方面用得非常多。有點(diǎn)也是有很多的。起碼看起來界面好看很多,并且?guī)в辛诉壿嬓缘臇|西。 如: 可以看到,主循環(huán)其實(shí)不進(jìn)行任何實(shí)際功能的處理,它完成的只是調(diào)用各個任務(wù)函數(shù)。 對于比較大型復(fù)雜的系統(tǒng),main 函數(shù)的主循環(huán)里根本不放要實(shí)際處理的代碼,而是把所有任務(wù)函數(shù)歸到一起,根據(jù)選擇進(jìn)入相應(yīng)的任務(wù)函數(shù),當(dāng)處理完該任務(wù)之后又會回到主循環(huán),由主循環(huán)再次分配任務(wù)。 此時(shí)主循環(huán)的作用就是調(diào)配任務(wù)(當(dāng)然用來調(diào)配任務(wù)的主循環(huán)本身也是一個最基本的任務(wù)),而在被調(diào)配的任務(wù)里面可能還會再次被該任務(wù)調(diào)配的子任務(wù)。 再來看看被調(diào)用的任務(wù)函數(shù),這些函數(shù)已經(jīng)不只是完成一些簡單功能了,它并不是執(zhí)行一些固定操作后返回,每個任務(wù)函數(shù)都有自己的一套控制邏輯,并且“不那么容易返回”。 這些任務(wù)函數(shù)同屬于一個進(jìn)程,但是同一時(shí)刻只有一個可以運(yùn)行。當(dāng)進(jìn)入某個函數(shù)時(shí),可以說進(jìn)程被這個函數(shù)阻塞,其他函數(shù)得不到運(yùn)行。但這也就是我們需要的效果,因?yàn)槊總€函數(shù)都有自己的一套控制邏輯,完全不需要考慮其他界面函數(shù)。而在函數(shù)退出時(shí),可以由該函數(shù)本身指定下一個要進(jìn)入的函數(shù),或者本來就是由于外部修改了 FlagPage 變量才導(dǎo)致該函數(shù)退出的。
這種程序結(jié)構(gòu)特別適合于多種“界面”的功能。一般情況下,主進(jìn)程不會停留在主循環(huán)里,而是偶爾退出到主循環(huán)重新分配下一個將要進(jìn)入的函數(shù),大部分時(shí)間會停留在某個界面函數(shù)里。 此外,這些函數(shù)之間有一些公共變量,這些變量的作用就是被各個函數(shù)使用,甚至用于函數(shù)間通信,輔助完成這些函數(shù)之間的邏輯結(jié)構(gòu)的構(gòu)建。比如 1.1 節(jié)中的那個重要的 FlagPage變量,這個標(biāo)志變量就指明了當(dāng)前工作于哪種工作模式下,任何函數(shù)(包括中斷進(jìn)程中的函數(shù))都可以通過改變此變量來切換工作模式。 也有一些與函數(shù)對應(yīng)的用于完成特定功能的變量。比如用于數(shù)碼管或者顯示屏顯示的現(xiàn)存,這些顯存是有特定用處的,一般其他函數(shù)不會使用(但確實(shí)是公共變量,是可以被使用的)。
將它們明確分類一下,整個系統(tǒng)都有哪些東西呢: 1、整體的程序框架是由各個界面函數(shù)和少數(shù)關(guān)鍵的全局變量構(gòu)建起來的。這是構(gòu)成系 統(tǒng)的主體框架。 2、每個界面函數(shù)在完成特定功能時(shí),會攜帶一些為自己服務(wù)的“私有的”變量和函數(shù)。 3、為整個框架服務(wù)的還有一些常用的變量和函數(shù),它們完成的是一些通用功能,可以把它們理解為“庫函數(shù)”。
以上都是對一個進(jìn)程的結(jié)構(gòu)的討論,并沒有涉及到中斷。
|
|