⑴ 單片機延時程序是怎麼實現的
延時是靠CPU執行無關指令,把時間浪費掉。
具體來說,DJNZ指令需要2個周期,循環250次就是500個周期,兩層循環就是500*500個周期,你調用一次DELAY子程序,CPU就空轉250000個周期(注意這個計算不精確),如果晶振是12MHz,那就意味著時間過去了250ms,也就是延時250ms
⑵ 51 單片機延時程序
我以2ms為例說明一下:
單片機的晶振周期為12hz,則執行一條代碼為一個機器周期,為1微妙(ua),所以2ms=10*200(ua),
對r2賦值200(4位二進制數最大值為256,所以只能取到200)即#c8h。再對r2循環20次就實現了2ms延時。至於100ms、
200ms、
1s等等方法類似,只是調整相應的初值。多設置幾次循環就行。
程序代碼如下:
delay:
mov
r1,#0ah
;賦值r1為10次
delay1:
mov
r2,#c8h
;賦值r2為200次
delay2:
djnz
r2,$
;r2自減到0,不到0繼續等待
djnz
r1,delay1
;r2減到0後r1自減1,重新給r2賦初值後繼續循環,直到r1到0為止,延時結束
ret
⑶ 單片機C語言延遲程序
下面的延時的基本程序(中斷加計數器)
********
void
T0_int(void)
interrupt
1
{
TH0
=
0x4C;
//重新裝載,50MS定時器初值
TL0
=
0x00;
T0_count++;
if(T0_count==20)
//1S到
{
T0_count
=
0;
//在這寫程序
}
}
main()
{
TMOD
=
0x01;//定時器0,工作方式1,16位計數
TH0
=
0x4C;
//50MS定時器初值
TL0
=
0x00;
IE
=
0x82;
//開總中斷,開T0中斷
EA
=
1;
ET0
=
1;
TR0
=
1;
T0_count
=
0;
i
=
0;
loop:
goto
loop;
}
還有:
for(us=0;us<60;us++);
/*延時500us*/
for(us=0;us<1;us++);
/*
延時15微秒*/
for(us=0;us<5;us++);
/*
延時51微秒*/
⑷ 51單片機用c語言怎麼寫延時函數
延時時間的計算與單片機的晶振頻率有關。若晶振頻率為12Mhz,那麼單片機每震動一次所需要的時間是1/12M s。那麼再來看看單片機執行一次自減所需要的振動次數是96次,假如我們對時間要求不是特別精確的話,可以約等於100來計算。現在通過上面兩個數據可以得出:單片機每執行一次自減所需要的時間是1/12M *100(s),即1/120000 s,逆向計算一下,每1ms需要自減多少次?120次對吧。所以一個簡單的延時功能就誕生了,我們只需要自減120次,就可以延時1ms,如果我們要延時50ms呢,那就自減50*120=6000次。那麼在程序上如何表達呢?我們可以用兩套for循環
void delay(int i){
int x,y;
for(x=i;x>0;x--){
for(y=120;y>0;y--)
}
}
參數 i 代表該函數延時多少ms
⑸ 請幫忙在51系列單片機系統中,編寫一個延時1ms的子程序。謝謝。。
1、首先,在電腦中打開keil軟體,創建好工程,然後添加c文件,如下圖所示。
⑹ 如何用單片機的delay實現延時
單片機中的delay()的單位時間不是系統提供的,而是用戶自己編制的。
如果用循環語句實現的循環,沒法計算,但是可以通過軟體模擬看到具體時間,但是一般精精確延時是沒法用循環語句實現的。
如果想精確延時,一般需要用到定時器,延時時間與晶振有關系,單片機系統一般常選用11.059 2 MHz、12 MHz或6 MHz晶振。第一種更容易產生各種標準的波特率,後兩種的一個機器周期分別為1 μs和2 μs,便於精確延時。本程序中假設使用頻率為12 MHz的晶振。
最長的延時時間可達216=65 536 μs。若定時器工作在方式2,則可實現極短時間的精確延時;如使用其他定時方式,則要考慮重裝定時初值的時間(重裝定時器初值佔用2個機器周期)。
(6)單片機如何實現延時程序代碼擴展閱讀
單片機C語言程序中延時函數delay的原理是:僅僅執行一些,沒有實質性影響的所謂「無意義指令」,比如做比大小啊,做某個int的自加運算啊之類的。
單片機的有些程序需要調用延時程序,合理的安排循環次數以及空操作的個數方法:用匯編的話就根據你的當前晶振頻率去推算你的指令周期,然後結合需要延遲的時間。
編寫延遲程序,用C的話還是要看最後生成的匯編碼是什麼樣的了。最簡單的方法就是寫好程序以後再編譯器里軟模擬看時間。
單片機C語言延時需注意的問題:
標準的C語言中沒有空語句。但在單片機的C語言編程中,經常需要用幾個空指令產生短延時的效果。這在匯編語言中很容易實現,寫幾個nop就行了。
在keil C51中,直接調用庫函數:
#include // 聲明了void _nop_(void);
_nop_(); // 產生一條NOP指令
作用:對於延時很短的,要求在us級的,採用「_nop_」函數,這個函數相當匯編NOP指令,延時幾微秒。NOP指令為單周期指令,可由晶振頻率算出延時時間,對於12M晶振,延時1uS。對於延時比較長的,要求在大於10us,採用C51中的循環語句來實現。
⑺ 單片機匯編程序延時0.3秒和0.5秒怎麼寫
延時0.3秒程序(12M):
DELAY3:
MOVR2,#200
DL1:
MOVR3,#250
DJNZR3,$
MOVR3,#250
DJNZR3,$
MOVR3,#250
DJNZR3,$
DJNZR2,DL1
RET
延時0.5秒程序:
DELAY5:
MOVR2,#5
DLY1:
MOVR3,#200
DLY2:
MOVR4,#250
DJNZR4,$
DJNZR3,DLY2
DJNZR2,DLY1
RET
⑻ 51單片機中延時程序
1. sleep()是以毫秒計算的,延時5秒是sleep(5*1000);,延時5分是sleep(5*1000*60);
2.包含的頭文件看你用的什麼編輯軟體。
3.我用的VC++是用包含在#include<windows.h>頭文件中。
#include<stdio.h>#include<windows.h>//Sleep()的頭文件 main() { int i;
int n=10;for(i=1;i<=n;i++) {printf("%d",i);Sleep(5*1000*60);} //
這里修改延時時間,
有些人說是用#include<dos.h>做頭文件你自己試下吧。
還用Sleep的S是大寫的,不是小寫的。
⑼ 51單片機中怎麼得到精確延時
51單片機的幾種精確延時實現延時通常有兩種方法:一種是硬體延時,要用到定時器/計數器,這種方法可以提高CPU的工作效率,也能做到精確延時;另一種是軟體延時,這種方法主要採用循環體進行。 x0dx0ax0dx0a1 使用定時器/計數器實現精確延時 x0dx0ax0dx0a 單片機系統一般常選用11.059 2 MHz、12 MHz或6 MHz晶振。第一種更容易產生各種標準的波特率,後兩種的一個機器周期分別為1 μs和2 μs,便於精確延時。本程序中假設使用頻率為12 MHz的晶振。最長的延時時間可達216=65 536 μs。若定時器工作在方式2,則可實現極短時間的精確延時;如使用其他定時方式,則要考慮重裝定時初值的時間(重裝定時器初值佔用2個機器周期)。 x0dx0ax0dx0a 在實際應用中,定時常採用中斷方式,如進行適當的循環可實現幾秒甚至更長時間的延時。使用定時器/計數器延時從程序的執行效率和穩定性兩方面考慮都是最佳的方案。但應該注意,C51編寫的中斷服務程序編譯後會自動加上PUSH ACC、PUSH PSW、POP PSW和POP ACC語句,執行時佔用了4個機器周期;如程序中還有計數值加1語句,則又會佔用1個機器周期。這些語句所消耗的時間在計算定時初值時要考慮進去,從初值中減去以達到最小誤差的目的。 x0dx0ax0dx0a2 軟體延時與時間計算 x0dx0ax0dx0a 在很多情況下,定時器/計數器經常被用作其他用途,這時候就只能用軟體方法延時。下面介紹幾種軟體延時的方法。 x0dx0ax0dx0a2.1 短暫延時 x0dx0ax0dx0a 可以在C文件中通過使用帶_NOP_( )語句的函數實現,定義一系列不同的延時函數,如Delay10us( )、Delay25us( )、Delay40us( )等存放在一個自定義的C文件中,需要時在主程序中直接調用。如延時10 μs的延時函數可編寫如下: x0dx0ax0dx0a void Delay10us( ) { x0dx0a _NOP_( ); x0dx0a _NOP_( ); x0dx0a _NOP_( ); x0dx0a _NOP_( ); x0dx0a _NOP_( ); x0dx0a _NOP_( ); x0dx0a } x0dx0ax0dx0a Delay10us( )函數中共用了6個_NOP_( )語句,每個語句執行時間為1 μs。主函數調用Delay10us( )時,先執行一個LCALL指令(2 μs),然後執行6個_NOP_( )語句(6 μs),最後執行了一個RET指令(2 μs),所以執行上述函數時共需要10 μs。 可以把這一函數當作基本延時函數,在其他函數中調用,即嵌套調用\[4\],以實現較長時間的延時;但需要注意,如在Delay40us( )中直接調用4次Delay10us( )函數,得到的延時時間將是42 μs,而不是40 μs。這是因為執行Delay40us( )時,先執行了一次LCALL指令(2 μs),然後開始執行第一個Delay10us( ),執行完最後一個Delay10us( )時,直接返回到主程序。依此類推,如果是兩層嵌套調用,如在Delay80us( )中兩次調用Delay40us( ),則也要先執行一次LCALL指令(2 μs),然後執行兩次Delay40us( )函數(84 μs),所以,實際延時時間為86 μs。簡言之,只有最內層的函數執行RET指令。該指令直接返回到上級函數或主函數。如在Delay80μs( )中直接調用8次Delay10us( ),此時的延時時間為82 μs。通過修改基本延時函數和適當的組合調用,上述方法可以實現不同時間的延時。 x0dx0ax0dx0a2.2 在C51中嵌套匯編程序段實現延時 x0dx0ax0dx0a 在C51中通過預處理指令#pragma asm和#pragma endasm可以嵌套匯編語言語句。用戶編寫的匯編語言緊跟在#pragma asm之後,在#pragma endasm之前結束。 x0dx0ax0dx0a 如:#pragma asm x0dx0a ? x0dx0a 匯編語言程序段 x0dx0a ? x0dx0a #pragma endasm x0dx0ax0dx0a 延時函數可設置入口參數,可將參數定義為unsigned char、int或long型。根據參數與返回值的傳遞規則,這時參數和函數返回值位於R7、R7R6、R7R6R5中。在應用時應注意以下幾點: x0dx0ax0dx0a ◆ #pragma asm、#pragma endasm不允許嵌套使用; x0dx0a ◆ 在程序的開頭應加上預處理指令#pragma asm,在該指令之前只能有注釋或其他預處理指令; x0dx0a ◆ 當使用asm語句時,編譯系統並不輸出目標模塊,而只輸出匯編源文件; x0dx0a ◆ asm只能用小寫字母,如果把asm寫成大寫,編譯系統就把它作為普通變數; x0dx0a ◆ #pragma asm、#pragma endasm和 asm只能在函數內使用。 x0dx0ax0dx0a 將匯編語言與C51結合起來,充分發揮各自的優勢,無疑是單片機開發人員的最佳選擇。 x0dx0ax0dx0a2.3 使用示波器確定延時時間 x0dx0ax0dx0a 利用示波器來測定延時程序執行時間。方法如下:編寫一個實現延時的函數,在該函數的開始置某個I/O口線如P1.0為高電平,在函數的最後清P1.0為低電平。在主程序中循環調用該延時函數,通過示波器測量P1.0引腳上的高電平時間即可確定延時函數的執行時間。方法如下: x0dx0ax0dx0a sbit T_point = P1^0; x0dx0a void Dly1ms(void) { x0dx0a unsigned int i,j; x0dx0a while (1) { x0dx0a T_point = 1; x0dx0a for(i=0;i<2;i++){ x0dx0a for(j=0;j<124;j++){;} x0dx0a } x0dx0a T_point = 0; x0dx0a for(i=0;i<1;i++){ x0dx0a for(j=0;j<124;j++){;} x0dx0a } x0dx0a } x0dx0a } x0dx0a void main (void) { x0dx0a Dly1ms(); x0dx0a } x0dx0ax0dx0a 把P1.0接入示波器,運行上面的程序,可以看到P1.0輸出的波形為周期是3 ms的方波。其中,高電平為2 ms,低電平為1 ms,即for循環結構「for(j=0;j<124;j++) {;}」的執行時間為1 ms。通過改變循環次數,可得到不同時間的延時。當然,也可以不用for循環而用別的語句實現延時。這里討論的只是確定延時的方法。 x0dx0ax0dx0a2.4 使用反匯編工具計算延時時間 x0dx0ax0dx0a 用Keil C51中的反匯編工具計算延時時間,在反匯編窗口中可用源程序和匯編程序的混合代碼或匯編代碼顯示目標應用程序。為了說明這種方法,還使用「for (i=0;i ⑽ C51單片機延時程序,需要不精確延時2小時,請問大神怎麼寫延時代碼,謝謝!
可以有很多辦法,一是調整參數,使其延時5分鍾或6分鍾,循環24次或20次。二是將延時函數的形參改為長整型(32位)延時時間擴大65536倍。三是使用定時器,每次定時50mS,累計144000次,便是2小時,使用定時器(中斷)的好處是在延時期間還可以干許多事情,例如顯示剩餘時間,檢測設備工作狀態或者調整延時時間等,而你的純軟體延時期間想干其它事情比較困難。