? ? ? ? 最近在上單片機(jī)原理及應(yīng)用課程,做實驗的時候遇到了軟件延時程序如何計算延時時間的問題,經(jīng)過一陣摸索終于領(lǐng)悟到其中奧秘......耶(比耶)。?延時函數(shù)是使用STC-ISP生成的,晶振為12MHz,指令集是STC-Y1(即89系列),使用do while()循環(huán)實現(xiàn)軟件精確延時。下面講解一下其中的延時時間是如何計算的。?
1. 首先我們先設(shè)置斷點是程序運行到進(jìn)入delay_10ms()函數(shù)前,可以在圖1右下角看到此時程序運行時間為0.00040800sec,此時我們看向反匯編窗口(Disassembly)。請注意圈出來的“LCALL delay_10ms”匯編指令,程序運行到代碼“ int a=100 ”并完成賦值后往下運行遇到delay_10ms(),子程序調(diào)用指令LCALL 完成對delay_10ms()的調(diào)用,該指令消耗24個時鐘周期,即 t1=2us。
?
圖1
2. 接著點擊調(diào)試中的單步執(zhí)行按鈕,使程序轉(zhuǎn)到delay_10ms()中,圖2可以看到,首先執(zhí)行“ MOV R7,#0x14”(即 i=20),接著執(zhí)行“MOV R6,#0x71”,查STC-ISP指令表可知將立即數(shù)賦值給寄存器指令“MOV Rn #data”消耗12個時鐘周期,故上述兩部共消耗 t2=2us。
?圖2
3. i,j賦值完再接著往下是執(zhí)行do{}里面的內(nèi)容“while(--j)”,“DJNZ? R6 , C:005D”指令的意思是寄存器R6里面的內(nèi)容減1不為0則轉(zhuǎn)移到“C:005D”處,即繼續(xù)執(zhí)行j自減。DJNZ指令消耗24個時鐘周期,一共執(zhí)行113次,即113 X 2us = 226us 。
4. 當(dāng)j從113自減到0后,不滿足DJNZ條件,則程序繼續(xù)往下執(zhí)行“ while(--i)”,即判斷do while()的條件。該代碼對應(yīng)匯編指令為“ DJNZ? R7 , C:005D”,即i=20,自減1為19,不為0則轉(zhuǎn)移到C:005D,繼續(xù)執(zhí)行j自減。注意,接下來的步驟很容易算錯,很多人可能誤以為j會再次從113開始自減,但實際不是的,前面存放 j=113 的寄存器R6從113自減到0后,此時再次自減 將從256開始,因為寄存器值從0開始減1后將會變成11111111,即256。這樣,整個循環(huán)時間就很容易得出來了:t3 = 113 X 1?X 2us + 256 X 19 X 2us + 20 X 2us = 9954us
5. delay_10ms()程序結(jié)束后往下是 子程序返回指令RET,該指令功能是返回到子程序調(diào)用指令下一指令處,即返回進(jìn)delay_ms()前的地方。該指令消耗24個時鐘周期,故 t4 = 2us。
綜上:可得delay_10ms()執(zhí)行時間,t = t1 + t2 + t3 + t4 = 2 + 2 + 9954 + 2 = 10000us = 10ms。
驗證:分別在進(jìn)delay_10ms() 和 執(zhí)行完delay_10ms()后設(shè)置斷點調(diào)試,如圖3,可得時間 :
t = 0.01040800sec - 0.00040800sec = 0.01000000sec,即10ms。
?圖3文章來源:http://www.zghlxwxcb.cn/news/detail-511245.html
(第一次寫文章,寫的不好請多多諒解哈)文章來源地址http://www.zghlxwxcb.cn/news/detail-511245.html
到了這里,關(guān)于51單片機(jī)延時程序的延時時間計算的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!