新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM的延時 LPC2100系列延時的研究

ARM的延時 LPC2100系列延時的研究

作者: 時間:2016-11-24 來源:網(wǎng)絡(luò) 收藏
ARM延時問題一直是比較令人頭疼的問題,因?yàn)锳RM是流水工作,并且在程序跳轉(zhuǎn)的時候不遵循流水規(guī)律,所以不像51單片機(jī)一樣好計(jì)算,今天為了調(diào)18B20,因此把ARM的延時問題研究了一下??偨Y(jié)起來,有三種計(jì)算方法。

1.做好看一下編譯出來的匯編語句,再自己用筆做個加減乗除,算出結(jié)果。
這種方法最直接,但是最麻煩,因?yàn)?strong>匯編指令的時間不好計(jì)算,并且要弄明白流水的工作原理,一個指令執(zhí)行的時間等,因此對于像我這樣的菜鳥級人物,這種方法雖然最直觀,但是不可取。
2.用定時器的中斷獲得精確的延時。
定時器中斷獲得的延時非常精確,現(xiàn)將代碼舉例如下:
void __irq IRQ_Timer0 (void)
{
++timeval;
T0IR = 0x01; 清除中斷標(biāo)志 VICVectAddr = 0x00; //通知VIC中斷處理結(jié)束
}
void time0_init(void) //定時器0初始化
{
timeval = 0;
T0TC = 0; //定時器設(shè)置為0 T0PR = 0; //時鐘不分頻 T0MCR = 0x03; //設(shè)置T0MR0匹配后復(fù)位T0TC,并產(chǎn)生中斷標(biāo)志 T0MR0 = Fpclk/1000; //1毫秒鐘定時 T0TCR = 0x01; //啟動定時器

VICIntSelect = 0x00; //所有中斷通道設(shè)置為IRQ中斷
VICVectCntl0 = 0x20 | 0x04;//設(shè)置定時器0中斷通道分配最高優(yōu)先級
VICVectAddr0 = (uint32)IRQ_Timer0;//設(shè)置中斷服務(wù)程序地址 VICIntEnable = 1 << 0x04;//使能定時器0中斷
IRQEnable(); //IRQ中斷使能

void wait(uint32 t) //延時
{
unsigned long i;
if (t<1)
t="1";
i = timeval;
while ((i + t) != timeval);
}
這樣在主函數(shù)里面用wait(10) 就延時10毫秒了。這種延時相當(dāng)精確,但是占用了一個定時器,比較浪費(fèi),并且可移植性也比較差,因此在并非要求精確定時的情況下,一半不建議采用。
3.用等待作延時。
此方法最經(jīng)典的用法就是書本上經(jīng)常用的用法:
void DelayNS (uint32 dly)
{
uint32 i;

for ( ; dly>0; dly--)
for (i=0; i<50000; i++);
}
那么這個程序到底延時多長時間呢,有很多人一直用,但是并不知道延時多長時間,就像我,以前一直不知道這個程序到底延時多長時間,直到昨天用示波器觀察了一下,才明白這個程序在主頻為11.0592*4M的情況下延時大概為5.6毫秒,因此延時1毫秒的程序就寫出來了,代碼如下:
void Delay(uint32 time) //1毫秒延時
{
uint32 i;
for(;time>0;time--)
for(i=8929;i>0;i--);
}
10微秒和1微秒延時程序分別如下:
void delay(uint32 time) //10微秒延時
{
uint32 i;
for(;time>0;time--)
for(i=84;i>0;i--);
}
void delay_1(uint32 time) //1微秒延時
{
uint32 i;
for(;time>0;time--)
for(i=5;i>0;i--);
}
這樣在主函數(shù)里就可以用以上函數(shù)基本上達(dá)到非精確延時的目的了。這種方法延時不大精確,但是不占用資源,并且可移植性很好,因此建議在非精確定時的情況下采用此方法進(jìn)行定時。


關(guān)鍵詞: ARM延時LPC2100系

評論


技術(shù)專區(qū)

關(guān)閉