精確延時的實現

2021-07-04 20:38:51 字數 1648 閱讀 2129

大家平時寫練習程式,包括**上的範例程式,很多延時都直接用的 sleep() 實現。這個延時有個缺點,那就是無法統計**執行的時間。請看下圖:

由圖可以看到,使用 api 函式 sleep() 的問題,就是會忽略掉程式的執行時間。很多時候,程式的執行時間是不固定的,所以這就導致使用 sleep 的延時並不精確,即便 sleep 使用相同的延時,也可能造成不同電腦上執行速度不同的結果。

圖中,理想的延時函式會將程式的執行時間部分考慮進去,這樣就可以實現很均勻的延時。下面討論實現方法。

本次延時要從上次的延時結束開始計算,就必須要記錄每次延時執行的具體時刻,而不僅僅是乙個時間長度。所以,可以簡單的使用 clock() 函式實現,**如下:

// 精確延時函式(可以精確到 1ms,精度 ±1ms)

// by yangw80, 2011-5-4

void

hpsleep

(int ms)

直接用函式 hpsleep 替換 sleep 就可以很直觀的看到效果。例如,《自由運動的點》這個程式,就是用的前述函式實現精確延時。

和 clock() 函式類似的還有 gettickcount() 函式,clock() 的精度高一些,其精度取決於常量 clocks_per_sec,通常在 1ms。根據微軟 msdn 的描述,gettickcount() 的精度在 10ms~16ms 之間。

以上**可以實現微秒級的延時。如果需要更高的精確度,可以使用多**定時器。做為範例,以下**實現微秒級的延時,並封裝成類:

// **名稱:精確到微秒的延時類(基於多**定時器)

// **編寫:yangw80

// 最後修改:2011-5-4

//      2013-11-2 修改為靜態呼叫

//#pragma once

#include

class

mmtimer

;large_integer

mmtimer::m_clk;

longlong

mmtimer::m_oldclk;

int mmtimer::m_freq =0;

// 延時

void mmtimer::

sleep

(int ms)

unsigned

int c = ms * m_freq;

m_oldclk += c;

queryperformancecounter

(&m_clk);

if(m_clk.quadpart > m_oldclk)

m_oldclk = m_clk.quadpart;

else

dowhile

(m_clk.quadpart < m_oldclk);

}

看明白了前面的敘述,這個**應該很容易就能看懂。

使用方法:將以上**拷貝到新建的 mmtimer.h 中,然後在主程式中加上 #include "mmtimer.h",在需要 sleep 的地方執行 mmtimer::sleep 方法。

為了簡單起見,只寫了乙個 .h 檔案。更標準一些的做法,是將前述**再分離出乙個 mmtimer.cpp 檔案,甚至改掉 mmtimer 這個名字,或者封裝成庫等等,這些就不再多說了,本文只想闡述乙個方法。

for迴圈實現C語言精確延時

for迴圈實現c語言精確延時 晶振12mhz,乙個機器週期1us.一.500ms延時子程式 程式 void delay500ms void 產生的彙編 c 0x0800 7f0f mov r7,0x0f c 0x0802 7eca mov r6,0xca c 0x0804 7d51 mov r5,0...

Systick精確延時0913

1.系統滴答定時器systick,核心自帶的24位遞減計數器,可計數2 24 1 16777215,計數到0後產生中斷標誌位countflag 時鐘可 於sysclk的8分頻或sysclk 2.systick相關暫存器 val load ctrl 3.systick的ctrl的第16位countfl...

MATLAB中如何用迴圈實現精確延時

前面在用matlab控制硬體的時候,在每次採集的過程中需要等一段固定的時間再採集訊號。所以這裡就會需要用到延時函式來精確延時,首先想到的就是函式pause time 但執行時發現錯誤,後來弄清楚了,pause的作用是暫停,而不是延時。在執行pause時,程式各個系統都暫停了,也要把我的採集硬體部分暫...