51單片機C語言延時函數(shù)怎么定義
C語言定義延時函數(shù)主要通過無意義指令的執(zhí)行來達到延時的目的。C程序中可使用不同類型的變量來進行延時設(shè)計。經(jīng)實驗測試,使用unsigned char類型具有比unsigned int更優(yōu)化的代碼,在使用時應(yīng)該使用unsigned char作為延時變量。 以某晶振為12MHz的單片機為例,晶振為12MHz即一個機器周期為1us。
定義一個延時xms毫秒的延時函數(shù)
void delay(unsigned int xms) // xms代表需要延時的毫秒數(shù)
{
unsigned int x,y;
for(x=xms;x》0;x--)
for(y=110;y》0;y--);
}
51單片機C語言延時函數(shù)的使用
下面給出一個經(jīng)典的延時函數(shù)。
一。 500ms延時子程序
程序:
void delay500ms(void)
{
unsigned char i,j,k;
for(i=15;i》0;i--)
for(j=202;j》0;j--)
for(k=81;k》0;k--);
}
計算分析:
程序共有三層循環(huán)
一層循環(huán)n:R5*2 = 81*2 = 162us DJNZ 2us
二層循環(huán)m:R6*(n+3) = 202*165 = 33330us DJNZ 2us + R5賦值 1us = 3us
三層循環(huán): R7*(m+3) = 15*33333 = 499995us DJNZ 2us + R6賦值 1us = 3us
循環(huán)外: 5us 子程序調(diào)用 2us + 子程序返回 2us + R7賦值 1us = 5us
延時總時間 = 三層循環(huán) + 循環(huán)外 = 499995+5 = 500000us =500ms
計算公式:延時時間=[(2*R5+3)*R6+3]*R7+5
二。 200ms延時子程序
程序:
void delay200ms(void)
{
unsigned char i,j,k;
for(i=5;i》0;i--)
for(j=132;j》0;j--)
for(k=150;k》0;k--);
}
三。 10ms延時子程序
程序:
void delay10ms(void)
{
unsigned char i,j,k;
for(i=5;i》0;i--)
for(j=4;j》0;j--)
for(k=248;k》0;k--);
}
四。 1s延時子程序
程序:
void delay1s(void)
{
unsigned char h,i,j,k;
for(h=5;h》0;h--)
for(i=4;i》0;i--)
for(j=116;j》0;j--)
for(k=214;k》0;k--);
}
關(guān)于單片機C語言的精確延時,網(wǎng)上很多都是大約給出延時值沒有準確那值是多少,也就沒有達到精確高的要求,而本函數(shù)克服了以上缺點,能夠精確計數(shù)出要延時值且精確達到1us,本舉例所用CPU為STC12C5412系列12倍速的單片機,只要修改一下參數(shù)值其它系例單片機也通用,適用范圍寬。
共有三條延時函數(shù)說明如下:
函數(shù)調(diào)用分兩級:一級是小于10US的延時,二級是大于10US的延時
//====================小于10US的【用1US級延時】====================
//----------微秒級延時---------
for(i=X;i》X;i--) 延時時間=(3+5*X)/12 提示(單位us, X不能大于255)
//================大于10US《小于21.9955Ms的可用【10US級延時函數(shù)】===========
void Delay10us(uchar Ms)
{
uchar data i;
for(;Ms》0;Ms--)
for(i=26;i》0;i--);
}
i=[(延時值-1.75)*12/Ms-15]/4
如想延時60US則 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再調(diào)用上面的【10US級延時函數(shù)】Delay10us(6); 則就精確延時60US;
如果想延時64US可以用這二種函數(shù)組合來用: Delay10us(6); for(i=9;i》X;i--) 共延時64US
四。 1s延時子程序
程序:
void delay1s(void)
{
unsigned char h,i,j,k;
for(h=5;h》0;h--)
for(i=4;i》0;i--)
for(j=116;j》0;j--)
for(k=214;k》0;k--);
}
關(guān)于單片機C語言的精確延時,網(wǎng)上很多都是大約給出延時值沒有準確那值是多少,也就沒有達到精確高的要求,而本函數(shù)克服了以上缺點,能夠精確計數(shù)出要延時值且精確達到1us,本舉例所用CPU為STC12C5412系列12倍速的單片機,只要修改一下參數(shù)值其它系例單片機也通用,適用范圍寬。
共有三條延時函數(shù)說明如下:
函數(shù)調(diào)用分兩級:一級是小于10US的延時,二級是大于10US的延時
//====================小于10US的【用1US級延時】====================
//----------微秒級延時---------
for(i=X;i》X;i--) 延時時間=(3+5*X)/12 提示(單位us, X不能大于255)
//================大于10US《小于21.9955Ms的可用【10US級延時函數(shù)】===========
void Delay10us(uchar Ms)
{
uchar data i;
for(;Ms》0;Ms--)
for(i=26;i》0;i--);
}
i=[(延時值-1.75)*12/Ms-15]/4
如想延時60US則 i=[(60-1.75)*12/6-15]/4=25.375≈26; 修改i的值=26,再調(diào)用上面的【10US級延時函數(shù)】Delay10us(6); 則就精確延時60US;
如果想延時64US可以用這二種函數(shù)組合來用: Delay10us(6); for(i=9;i》X;i--) 共延時64US
下面給出有關(guān)在C51中延時子程序設(shè)計時要注意的問題(一些經(jīng)驗之談)
1、在C51中進行精確的延時子程序設(shè)計時,盡量不要或少在延時子程序中定義局部變量,所有的延時子程序中變量通過有參函數(shù)傳遞。
2、在延時子程序設(shè)計時,采用do…while,結(jié)構(gòu)做循環(huán)體要比for結(jié)構(gòu)做循環(huán)體好。
3、在延時子程序設(shè)計時,要進行循環(huán)體嵌套時,采用先內(nèi)循環(huán),再減減比先減減,再內(nèi)循環(huán)要好。
一。 500ms延時子程序
程序:
void delay500ms(void)
{
unsigned char i,j,k;
for(i=15;i》0;i--)
for(j=202;j》0;j--)
for(k=81;k》0;k--);
}
產(chǎn)生的匯編:
C:0x0800 7F0F MOV R7,#0x0F
C:0x0802 7ECA MOV R6,#0xCA
C:0x0804 7D51 MOV R5,#0x51
C:0x0806 DDFE DJNZ R5,C:0806
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
二。 200ms延時子程序
程序:
void delay200ms(void)
{
unsigned char i,j,k;
for(i=5;i》0;i--)
for(j=132;j》0;j--)
for(k=150;k》0;k--);
}
產(chǎn)生的匯編
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E84 MOV R6,#0x84
C:0x0804 7D96 MOV R5,#0x96
C:0x0806 DDFE DJNZ R5,C:0806
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
三。 10ms延時子程序
程序:
void delay10ms(void)
{
unsigned char i,j,k;
for(i=5;i》0;i--)
for(j=4;j》0;j--)
for(k=248;k》0;k--);
}
產(chǎn)生的匯編
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E04 MOV R6,#0x04
C:0x0804 7DF8 MOV R5,#0xF8
C:0x0806 DDFE DJNZ R5,C:0806
C:0x0808 DEFA DJNZ R6,C:0804
C:0x080A DFF6 DJNZ R7,C:0802
C:0x080C 22 RET
四。 1s延時子程序
程序:
void delay1s(void)
{
unsigned char h,i,j,k;
for(h=5;h》0;h--)
for(i=4;i》0;i--)
for(j=116;j》0;j--)
for(k=214;k》0;k--);
}
產(chǎn)生的匯編
C:0x0800 7F05 MOV R7,#0x05
C:0x0802 7E04 MOV R6,#0x04
C:0x0804 7D74 MOV R5,#0x74
C:0x0806 7CD6 MOV R4,#0xD6
C:0x0808 DCFE DJNZ R4,C:0808
C:0x080A DDFA DJNZ R5,C:0806
C:0x080C DEF6 DJNZ R6,C:0804
C:0x080E DFF2 DJNZ R7,C:0802
C:0x0810 22 RET
5,另外一些關(guān)于延時的例子http://www.ceet.hbnu.edu.cn/bbs/viewthread.php?tid=3749,作者:小秋
晶振:12MHz
1:5~500us
void delay(unsigned char i)
{
while(--i) ;
}
計算方法:ix2+5 可完成5~515us的延時
2:10us~2ms
void delay(unsigned char i)
{
for( ;i》0 ;i--) ;
}
計算方法:ix8+10 可完成10us~2.050ms的延時
3:2ms~130ms
void delay(unsigned char i,unsigned char j)
{
for( ;j》0 ;j--)
for( ;i》0 ;i--) ;
}
計算方法:(ix2+3)xj+5 u
評論
查看更多