天天看點

單片機延時程式的實作

第一種方法:

https://blog.csdn.net/leizi_chn/article/details/7257714

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–);

}

産生的彙編:

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     
           

計算分析:

程式共有三層循環
一層循環n:R5*2 = 81*2 = 162us                  DJNZ  2us
二層循環m:R6*(n+3) = 202*165 = 33330us          DJNZ  2us + R5指派 1us = 3us
三層循環: R7*(m+3) = 15*33333 = 499995us        DJNZ  2us + R6指派 1us = 3us
循環外:   5us            子程式調用 2us + 子程式傳回 2us + R7指派 1us  = 5us
延時總時間 = 三層循環 + 循環外 = 499995+5 = 500000us =500ms
           

計算公式:延時時間=[(2*R5+3)*R6+3]*R7+5

第二種方法

https://blog.csdn.net/leizi_chn/article/details/7257714

在keil C51中,直接調用庫函數:

#include<intrins.h> // 聲明了void nop(void);

nop(); // 産生一條NOP指令

作用:對于延時很短的,要求在us級的,采用“nop”函數,這個函數相當彙編NOP指令,延時幾微秒。NOP指令為單周期指令,可由晶振頻率算出延時時間,對于12M晶振,延時1uS。

第三種方法

https://blog.csdn.net/xqn2017/article/details/78141710

頭檔案中加入#inlude <stdio.h>

定義一個内聯函數,然後調用這個函數,不過得測一下平台調用内聯函數的開銷,而不僅僅是nop指令的個數,在自己的測試中,調用大概是9個cycle,而nop指令是1個cycle,是以我假設為9倍的線性關系進行打樁,每個平台會不一樣,包括用到的器件的主頻等等,這裡隻是提供一種參考方法

#inluce <stdio.h>

assembly inline void insert_nop()

{

asm_begin

nop

asm_end

}