陸捷 鄒靜
(武昌工學(xué)院信息工程學(xué)院 湖北省武漢市 430065)
CC2530F256 單片機(jī)結(jié)合TI 公司的ZigBee 2007 協(xié)議棧,可以廣泛應(yīng)用于2.4GHz 的IEEE802.15.4、ZigBee 和RF4CE 應(yīng)用,是一個(gè)真正的無(wú)線片上系統(tǒng)解決方案[1]。它集成了增強(qiáng)型8051 微控制器內(nèi)核、2.4GHz RF 收發(fā)器,以及外設(shè)、內(nèi)存、時(shí)鐘、電源管理等模塊。很多基于ZigBee 技術(shù)的無(wú)線傳感網(wǎng)應(yīng)用,都是采用該型號(hào)單片機(jī)作為網(wǎng)絡(luò)節(jié)點(diǎn)的微控制器[2~7]。
在開(kāi)發(fā)這些單片機(jī)應(yīng)用程序的過(guò)程中,經(jīng)常需要解決精確延時(shí)的問(wèn)題,例如按鍵去抖、數(shù)據(jù)傳輸?shù)炔僮?,延時(shí)的時(shí)長(zhǎng)在幾十微秒到幾秒之間不等[8]。實(shí)現(xiàn)精確延時(shí)的方法通常有兩種:一種是硬件延時(shí),另一種是軟件延時(shí)。硬件延時(shí)就是采用片上的定時(shí)器外設(shè)來(lái)計(jì)數(shù)延時(shí)。這種方法不占用CPU 的運(yùn)行資源,工作效率高,延時(shí)精確。但是CC2530 只有4 個(gè)定時(shí)器,一般用于Z-Stack 協(xié)議棧,不適用于普通的等待延時(shí),因此,很多情況下采用軟件延時(shí)的方法。軟件延時(shí)主要采用for 循環(huán)體或while 循環(huán)體來(lái)實(shí)現(xiàn)。采用這種方法,如果能夠確定調(diào)用延時(shí)函數(shù)執(zhí)行了多少個(gè)指令周期,就能夠?qū)崿F(xiàn)精確延時(shí)。但是,很多采用C51 編譯器的開(kāi)發(fā)人員不知道如何根據(jù)實(shí)際情況來(lái)確定for 循環(huán)或while 循環(huán)的循環(huán)次數(shù)。有的開(kāi)發(fā)人員利用示波器來(lái)驗(yàn)證不同循環(huán)次數(shù)對(duì)應(yīng)的延時(shí)周期。但是,為了實(shí)現(xiàn)更長(zhǎng)時(shí)間的延時(shí)而循環(huán)調(diào)用較短時(shí)長(zhǎng)的延時(shí)函數(shù)時(shí),發(fā)現(xiàn)延時(shí)周期會(huì)有偏差。這些都是因?yàn)闆](méi)有準(zhǔn)確分析出調(diào)用延時(shí)函數(shù)所需的指令個(gè)數(shù),從而無(wú)法確定調(diào)用延時(shí)函數(shù)所需的時(shí)間。本文采用IAR 的反匯編工具,來(lái)分析for 循環(huán)的匯編代碼,準(zhǔn)確計(jì)算執(zhí)行循環(huán)代碼所需的時(shí)間,從而確定調(diào)用延時(shí)函數(shù)的總時(shí)間。
for 語(yǔ)句的執(zhí)行過(guò)程是:第一步是執(zhí)行初值表達(dá)式,其作用是給循環(huán)變量賦初值。第二步是判斷條件表達(dá)式是否為真。如果結(jié)果為假則退出for 循環(huán);如果非假則執(zhí)行循環(huán)體。循環(huán)體執(zhí)行完畢之后再執(zhí)行增量表達(dá)式,接著循環(huán)執(zhí)行第二步。
分析for 語(yǔ)句的執(zhí)行過(guò)程可以看出,初值表達(dá)式執(zhí)行且只執(zhí)行1 次。假定for 語(yǔ)句的循環(huán)次數(shù)為b,b ≥0,那么,條件表達(dá)式、循環(huán)體和增量表達(dá)式三者都將循環(huán)執(zhí)行b 次。另外,在執(zhí)行for 循環(huán)的末尾,還要執(zhí)行一次判斷表達(dá)式,此時(shí)判斷條件表達(dá)式為0,從而退出for 循環(huán)。也就是說(shuō),如果b=0,那么條件表達(dá)式至少要執(zhí)行1 次。
圖1:初值表達(dá)式的反匯編代碼
圖2:條件表達(dá)式的反匯編代碼
圖3:增量表達(dá)式的反匯編代碼
圖4:CCTIMER1 寄存器中的計(jì)數(shù)值
圖5:1s 延時(shí)函數(shù)的CCTIMER1 計(jì)數(shù)值
圖6:10ms 延時(shí)函數(shù)的CCTIMER1 的計(jì)數(shù)值
分析for 語(yǔ)句的執(zhí)行過(guò)程之后,就可以精確計(jì)算執(zhí)行for 語(yǔ)句的總時(shí)間。已知執(zhí)行代碼的指令總數(shù)與指令周期的乘積,就是執(zhí)行代碼的總時(shí)間。那么,只要計(jì)算出for 循環(huán)的指令總數(shù),就可以計(jì)算出執(zhí)行時(shí)間。
IAR EmbeddedWorkbench for 8051 集成開(kāi)發(fā)軟件中有反匯編工具,在調(diào)試模式下可以在Disassembly 窗口中調(diào)看C 代碼對(duì)應(yīng)的匯編代碼。以循環(huán)語(yǔ)句“for(b=65535;b>0;b--);”為例。第一步是執(zhí)行初值表達(dá)式“b=65535;”。圖1 是Disassembly 窗口中初值表達(dá)式的反匯編代碼。如圖所示,增量b 的數(shù)據(jù)類型是16 位的無(wú)符號(hào)整型,執(zhí)行初值表達(dá)式需要2 條“MOV”語(yǔ)句和1 條“SJMP”語(yǔ)句,共3 條匯編語(yǔ)句,共需7 個(gè)指令周期。
第二步是執(zhí)行條件表達(dá)式,其反匯編代碼如圖2 所示。條件表達(dá)式對(duì)應(yīng)著“MOV”、“ORL”和“JZ”3 條匯編語(yǔ)句,共需5 個(gè)指令周期。循環(huán)體為空,不占用指令周期。
接著是執(zhí)行增量表達(dá)式,其反匯編代碼如圖3 所示。增量表達(dá)式對(duì)應(yīng)著4 條“MOV”、1 條“ADD”和1 條“ADDC”共6 條匯編語(yǔ)句,共需10 個(gè)指令周期。第二步中,條件表達(dá)式和增量表達(dá)式要循環(huán)執(zhí)行b=65535次,那么這兩部分代碼的指令總數(shù)為(5+10)b。
最后是執(zhí)行1 次條件表達(dá)式并退出for 循環(huán),同樣需要5 個(gè)指令周期。綜上所述,循環(huán)體為空的單重for 循環(huán)的指令總數(shù)c 為初值表達(dá)式、循環(huán)執(zhí)行的條件表達(dá)式和增量表達(dá)式以及退出for 循環(huán)的條件表達(dá)式三部分的指令總和,即
綜上所述,林政資源管理要以生態(tài)建設(shè)為主要目標(biāo),正確樹(shù)立林政資源管理與生態(tài)建設(shè)之間的關(guān)系,從多個(gè)層面入手逐步強(qiáng)化自身的生態(tài)保護(hù)意識(shí),結(jié)合當(dāng)前生態(tài)建設(shè)的實(shí)際情況合理劃分林政資源管理內(nèi)容,在憲法的框架之下進(jìn)一步健全與林業(yè)資源有關(guān)的法律法規(guī),科學(xué)協(xié)調(diào)林政資源管理中的個(gè)關(guān)系,確保林政資源管理與生態(tài)建設(shè)達(dá)到有效銜接,從而提高林政資源管理工作的質(zhì)量。
式(1)的前提是for 循環(huán)體為空。如果循環(huán)體不為空,在式(1)中就要增加執(zhí)行循環(huán)體的指令個(gè)數(shù)。假設(shè)執(zhí)行一次for 語(yǔ)句循環(huán)體所需的指令周期數(shù)為x,循環(huán)體要循環(huán)執(zhí)行b 次,那么其指令周期數(shù)為bx。代入式(1)可得出,循環(huán)體不為空的for 語(yǔ)句的指令總數(shù)為
如果要實(shí)現(xiàn)幾十毫秒到幾分鐘的長(zhǎng)延時(shí),就需要用到兩重for循環(huán)嵌套。
假設(shè)把循環(huán)體為空的for 語(yǔ)句作為另一個(gè)for 語(yǔ)句的循環(huán)體,構(gòu)成兩重for 循環(huán)嵌套。令外層for 語(yǔ)句的循環(huán)次數(shù)為a,內(nèi)層for語(yǔ)句的循環(huán)次數(shù)為b,那么內(nèi)層for 語(yǔ)句要循環(huán)執(zhí)行a 次。由式(1)推導(dǎo)出執(zhí)行內(nèi)層for 語(yǔ)句的指令總數(shù)為(7+15b+5)a。將其代入式(2),得到滿足假設(shè)條件的兩重for 循環(huán)的指令總數(shù)c 為
整理得
如果把for 循環(huán)作為一個(gè)函數(shù)進(jìn)行調(diào)用,那么還要考慮調(diào)用函數(shù)和返回主函數(shù)所需的時(shí)間。調(diào)用函數(shù)對(duì)應(yīng)“LCALL”匯編指令,返回主函數(shù)對(duì)應(yīng)“RET”匯編指令,共需10 個(gè)指令周期。因此,在式(3)中增加10 個(gè)指令周期就是調(diào)用延時(shí)函數(shù)的指令總數(shù),即
IAR EmbeddedWorkbench for 8051 中集成有C-SPY 調(diào)試器。它實(shí)現(xiàn)了一個(gè)64 位的指令計(jì)數(shù)寄存器CCTIMER1,能夠顯示兩個(gè)斷點(diǎn)之間累計(jì)的時(shí)鐘周期。假設(shè)a=65535,b=1,代入式(4)計(jì)算得到c=2752492。這與CCTIMER1寄存器中的值是一致的,如圖4所示。
CC2530 包含增強(qiáng)型8051 微控制器,一個(gè)指令周期就是一個(gè)時(shí)鐘周期。如果把延時(shí)的指令周期總數(shù)作為已知量代入式(4)中,式(4)就簡(jiǎn)化為二元二次方程,可以計(jì)算求解a 和b 的最優(yōu)值。然后編寫(xiě)for 循環(huán)延時(shí)函數(shù),調(diào)用該延時(shí)函數(shù)就可以實(shí)現(xiàn)CC2530 的軟件精確延時(shí)。
式(4)中的變量a 和b 是16 位無(wú)符號(hào)整型數(shù),最大取值為65535。而且指令總數(shù)c 也不能超過(guò)無(wú)符號(hào)長(zhǎng)整型的取值范圍。那么,可以通過(guò)編程來(lái)窮舉a 和b 的所有組合,從而找出滿足方程的a 和b 的解。這里要注意,采用兩重for 循環(huán)的延時(shí)應(yīng)當(dāng)在134s 以內(nèi)。另外,在實(shí)際工程應(yīng)用中,還要考慮晶振的累積誤差,因此不宜延時(shí)過(guò)長(zhǎng)時(shí)間。
1s 延時(shí)是指調(diào)用該函數(shù)并返回主函數(shù)的總時(shí)間是1s。假設(shè)CC2530 運(yùn)行時(shí)鐘為32MHz,那么一個(gè)指令周期的時(shí)長(zhǎng)為也就是說(shuō),CC2530 延時(shí)1s,需要執(zhí)行32 兆條指令。代入式(4)得到二元二次方程
通過(guò)編程求解方程(5)發(fā)現(xiàn)無(wú)整數(shù)解。那么可以考慮求解最接近32 兆的最優(yōu)整數(shù)解。進(jìn)一步研究發(fā)現(xiàn),當(dāng)a 和b 分別取39653和52 時(shí),方程(5)左邊等于31999993,相當(dāng)于存在的偏差。那么,可以在for 循環(huán)外增加7 個(gè)NOP 指令,來(lái)修正該偏差。也就是說(shuō),1s 延時(shí)函數(shù)采用兩重for 循環(huán)和NOP 匯編指令來(lái)編寫(xiě)。其中外循環(huán)次數(shù)設(shè)置為39653 次,內(nèi)循環(huán)次數(shù)設(shè)置為52 次,在兩重for 循環(huán)之外再增加7 個(gè)NOP 匯編指令。通過(guò)C-SPY 仿真器可以得出,調(diào)用該1s 延時(shí)函數(shù)的執(zhí)行指令總數(shù)與CCTIMER1 寄存器中的值是一致的,如圖5 所示。
同理,CC2530 延時(shí)100ms 需要執(zhí)行3.2 兆條指令。通過(guò)編程求解方程(5),得出100ms 延時(shí)函數(shù)的實(shí)現(xiàn)方法是a 和b 分別取值11 和19392,并在for 嵌套循環(huán)外增加1 個(gè)NOP 指令。
當(dāng)延時(shí)小于30ms 時(shí),可以用循環(huán)體為空的單重for 循環(huán)來(lái)編寫(xiě)延時(shí)函數(shù)。那么,為了計(jì)算調(diào)用該延時(shí)函數(shù)的指令周期總數(shù),需要在式(1)中增加函數(shù)調(diào)用并返回主函數(shù)的10 個(gè)指令周期。即調(diào)用該延時(shí)函數(shù)的指令總數(shù)c 為
例如實(shí)現(xiàn)10ms延時(shí)函數(shù)時(shí),CC2530需要執(zhí)行320k個(gè)指令周期,代入式(6)中得到一元一次方程
同樣,通過(guò)編程在[0,65535]的范圍內(nèi)窮舉所有的整數(shù)值,發(fā)現(xiàn)方程(7)無(wú)整數(shù)解。當(dāng)a 取值21331,方程(7)的左邊為319987,與方程右邊還相差13。同上所述,采用13 個(gè)NOP 指令來(lái)進(jìn)行修正偏差。那么,10ms 延時(shí)函數(shù)的實(shí)現(xiàn)方法是:采用循環(huán)體為空的單重for 循環(huán),循環(huán)次數(shù)設(shè)置為21331,并在for 循環(huán)外增加13 個(gè)NOP 指令。C-SPY 的仿真結(jié)果表明該方法是正確的,如圖6 所示。
CC2530 的開(kāi)發(fā)人員經(jīng)常需要解決調(diào)用延時(shí)函數(shù)來(lái)實(shí)現(xiàn)精確延時(shí)的問(wèn)題。解決這個(gè)問(wèn)題需要準(zhǔn)確計(jì)算調(diào)用延時(shí)函數(shù)所需的指令周期數(shù)。通過(guò)IAR EmbeddedWorkbench for 8051 集成開(kāi)發(fā)環(huán)境中的反匯編工具,分析單重for 循環(huán)和雙重for 循環(huán)的指令周期個(gè)數(shù),建立以循環(huán)次數(shù)為變量的方程。然后采用窮舉法求解方程的最優(yōu)整數(shù)解,從而確定for 語(yǔ)句的循環(huán)次數(shù),最后用若干NOP 指令進(jìn)行修正。C-SPY 仿真結(jié)果表明,采用這種方法編寫(xiě)的延時(shí)函數(shù),能夠?qū)崿F(xiàn)CC2530 單片機(jī)采用軟件延時(shí)的方式進(jìn)行精確延時(shí)。
這種方法普遍適用于分析和實(shí)現(xiàn)各型號(hào)單片機(jī)的軟件精確延時(shí)。但是需要注意以下三個(gè)問(wèn)題:一是不同單片機(jī)的指令周期不同,那么推算指令的總數(shù)就會(huì)不同。即便是相同型號(hào)的單片機(jī),也要考慮外部時(shí)鐘、內(nèi)部時(shí)鐘、時(shí)鐘分頻系數(shù)等影響指令周期的各種因素。二是執(zhí)行不同編程語(yǔ)言所需的指令周期不同。例如C 語(yǔ)言編寫(xiě)的代碼需要編譯成匯編語(yǔ)言才能確定其指令周期數(shù)。而匯編語(yǔ)言則更直接。三是針對(duì)不同數(shù)據(jù)類型的處理,會(huì)生成不同的匯編代碼。例如單字節(jié)整型變量和雙字節(jié)整型變量的賦值運(yùn)算、四則運(yùn)算的匯編代碼是不同的,那么就要充分考慮for 語(yǔ)句循環(huán)次數(shù)的取值范圍,并定義相應(yīng)的數(shù)據(jù)類型。綜上所述,不同型號(hào)單片機(jī)的軟件精確延時(shí)問(wèn)題,需要根據(jù)具體情況具體分析。分析問(wèn)題的思路和方法是相同的,但是不可隨意套用計(jì)算公式。