(Conversion) Precise Timing based on Windows in VC

Source: Internet
Author: User
Tags sleep function

 

(Transferred from) http://www.vckbase.com/document/viewdoc? Id = 1301

 

Precise Timing based on Windows in VC

Youzhiyu, Institute of optoelectronic technology, Chinese Emy of Sciences

Download Sample project

In the industrial production control system, there are many operations that require timed completion, such as regularly displaying the current time, regularly refreshing the progress bar on the screen, and regularly sending commands and transmitting data to the lower computer. In particular, real-time control systems and data collection systems that require high control performance require precise and scheduled operations.
As we all know, Windows is a message-based system, and any event is executed by sending and receiving messages. In this way, there are some problems. For example, once a computer's CPU is occupied by a process or the system resources are insufficient, messages sent to the message queue are temporarily suspended and cannot be processed in real time. Therefore, you cannot simply use Windows messages to trigger an event with strict timing requirements. In addition, because the access to the underlying computer hardware has been encapsulated in Windows, it is also difficult to achieve accurate timing by directly using the access hardware. Therefore, in actual application, the appropriate timing method should be adopted according to the specific timing precision requirements.
VC provides a lot of time-related functions, using which the control program can accurately complete timing and timing operations. This article describes in detail seven Windows-based precision timing methods in VC, as shown in:


Figure 1 Image Description

Method 1: WM_TIMER message ing in VC can be used for simple time control. First, call the SetTimer () function to set the timer interval. For example, SetTimer (0,200, NULL) sets the interval of Ms. Then add the scheduled response function OnTimer () to the application, and add the Response Processing statement to the function to complete the operation at the scheduled time. This timing method is very simple and can implement certain timing functions, but its timing function is the same as the delay function of the Sleep () function. Its accuracy is very low, and the minimum timing accuracy is only 30 ms, CPU usage is low, and the priority of timer messages in multi-task operating systems is very low. Therefore, Timer messages cannot be responded to in a timely manner and often cannot meet the needs of applications in real-time control environments. It can only be used to achieve low timing precision requirements, such as dynamic display of Bitmap. For example, Timer1 In the example project.
Method 2: Use the sleep () function in VC to implement latency. Its unit is ms. For example, if the latency is 2 seconds, use sleep (2000 ). The accuracy is very low, and the minimum timing accuracy is only 30 ms. The disadvantage of using the sleep function is that other messages cannot be processed during the delay period. If the time is too long, it will be like a crash, the CPU usage is very high and can only be used in latency programs with low requirements. For example, Timer2 In the example project.
Method 3: Use the COleDateTime class and COleDateTimeSpan class in combination with the WINDOWS message processing process to achieve latency in seconds. For example, Timer3 and Timer3_1 In the example project. The following is a two-second latency code:

COleDateTime start_time = COleDateTime: GetCurrentTime (); COleDateTimeSpan end_time = COleDateTime: GetCurrentTime ()-start_time; while (end_time.GetTotalSeconds () <2) // implement latency of 2 seconds {MSG msg; getMessage (& msg, NULL,); TranslateMessage (& msg); DispatchMessage (& msg); // the preceding four rows can process other messages during the delay or scheduled period, // although this can reduce the CPU usage, // It reduces the latency or timing accuracy and can be removed in practical applications. End_time = COleDateTime: GetCurrentTime ()-start_time;} // in this way, other messages can be processed during latency.

Method 4: In case of high precision requirements, the GetTickCount () function can be used in VC. the return value of this function is DWORD type, the time interval after a computer is started in ms. The accuracy is higher than that of WM_TIMER message ing. in a short period of time, the timing error is 15 ms, and in a long period of time, the timing error is low. If the timing time is too long, it is like a dead machine, the CPU usage is very high and can only be used in latency programs with low requirements. For example, Timer4 and Timer4_1 In the example project. The following code can implement accurate timing within 50 ms:

       DWORD dwStart = GetTickCount();       DWORD dwEnd   = dwStart;       do       {          dwEnd = GetTickCount()-dwStart;       }while(dwEnd <50);

To enable the GetTickCount () function to process other messages during a delay or scheduled period, you can change the code:

       DWORD dwStart = GetTickCount();       DWORD dwEnd   = dwStart;       do       {              MSG   msg;              GetMessage(&msg,NULL,0,0);              TranslateMessage(&msg);               DispatchMessage(&msg);              dwEnd = GetTickCount()-dwStart;       }while(dwEnd <50);

This can reduce the CPU usage and process other messages during the delay or scheduled period, but reduces the latency or scheduled precision.
Method 5: DWORD timeGetTime (void), a multimedia timer function similar to the GetTickCount () function, returns the number of milliseconds that have elapsed since Windows was started. In its multimedia Windows system, Microsoft provides an API for the precise timer at the bottom layer. The multimedia timer can be used to accurately read the current time of the system, in addition, you can call an event, function, or process within a very precise interval. The difference is that before calling the DWORD timeGetTime (void) function, you must add Winmm. lib and Mmsystem. h to the project. Otherwise, the DWORD timeGetTime (void) function is prompted during compilation. Since this function is scheduled to be controlled through queries, a scheduled cycle should be established to control scheduled events. For example, Timer5 and Timer5_1 In the example project.
Method 6: Use the multimedia timer timeSetEvent () function. The timer precision of this function is ms. This function can be used to implement periodic function calls. For example, Timer6 and Timer6_1 In the example project. The function prototype is as follows:

       MMRESULT timeSetEvent( UINT uDelay,                                UINT uResolution,                                LPTIMECALLBACK lpTimeProc,                                WORD dwUser,                                UINT fuEvent )

This function sets a scheduled callback event, which can be a one-time event or periodic event. Once an event is activated, the specified callback function is called. If successful, the code of the event identifier is returned. Otherwise, NULL is returned. Function parameters are described as follows:

UDelay: Specifies the event cycle in milliseconds. Uresolution: Specify the latency precision in milliseconds. The smaller the value, the higher the timer event resolution. The default value is 1 ms. LpTimeProc: point to a callback function. DwUser: stores user-provided callback data. FuEvent: Specify the timer event type: TIME_ONESHOT: uDelay only generates one event TIME_PERIODIC in milliseconds: events are generated cyclically every uDelay millisecond.

For specific applications, you can call the timeSetEvent () function to define the tasks to be periodically executed in the LpTimeProc callback function (such as scheduled sampling and control ), to complete the event to be processed. Note that the task processing time cannot be greater than the cycle interval. In addition, after the timer is used, call timeKillEvent () to release it in time.
Method 7: Use the QueryPerformanceFrequency () and QueryPerformanceCounter () functions for scheduled operations with higher precision requirements. These two functions are accurate time functions provided by VC only for Windows 95 and later versions, and require computers to support accurate timers on hardware. For example, Timer7, Timer7_1, Timer7_2, and Timer7_3 In the example project.
The following is a prototype of the QueryPerformanceFrequency () and QueryPerformanceCounter () functions:

       BOOL  QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);       BOOL  QueryPerformanceCounter(LARGE_INTEGER *lpCount);

The data type ARGE_INTEGER can be an 8-byte long integer or a combination of two 4-byte long integer values. The specific usage depends on whether the compiler supports 64-bit. This type is defined as follows:

Typedef union _ LARGE_INTEGER {struct {DWORD LowPart; // 4-byte integer LONG HighPart; // 4-byte integer}; LONGLONG QuadPart; // 8-byte integer} LARGE_INTEGER;

Before timing, call the QueryPerformanceFrequency () function to obtain the clock frequency of the machine's Internal timer, and then call the QueryPerformanceCounter () function before and after a strictly scheduled event, the precise time of the event calendar is calculated based on the difference between the two counts and the clock frequency. Run the following code to implement accurate timing within 1 ms:

LARGE_INTEGER litmp; LONGLONG QPart1, QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency (& litmp); dfFreq = (double) litmp. quadPart; // obtain the counter clock frequency QueryPerformanceCounter (& litmp); QPart1 = litmp. quadPart; // obtain the initial value do {QueryPerformanceCounter (& litmp); QPart2 = litmp. quadPart; // get the abort value dfMinus = (double) (QPart2-QPart1); dfTim = dfMinus/dfFreq; // get the corresponding time value, unit: seconds} while (dfTim <0.001 );

Its timing error is no more than 1 microsecond, and its precision is related to machine configurations such as CPU. The following program is used to test the exact duration of the function Sleep (100:

LARGE_INTEGER litmp; LONGLONG QPart1, QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency (& litmp); dfFreq = (double) litmp. quadPart; // obtain the counter clock frequency QueryPerformanceCounter (& litmp); QPart1 = litmp. quadPart; // get the initial value Sleep (100); QueryPerformanceCounter (& litmp); QPart2 = litmp. quadPart; // get the abort value dfMinus = (double) (QPart2-QPart1); dfTim = dfMinus/dfFreq; // get the corresponding time value, in seconds

Due to the error of the Sleep () function, each execution result of the preceding program has a slight error. The following code implements precise timing in 1 microsecond:

LARGE_INTEGER litmp; LONGLONG QPart1, QPart2; double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency (& litmp); dfFreq = (double) litmp. quadPart; // obtain the counter clock frequency QueryPerformanceCounter (& litmp); QPart1 = litmp. quadPart; // obtain the initial value do {QueryPerformanceCounter (& litmp); QPart2 = litmp. quadPart; // get the abort value dfMinus = (double) (QPart2-QPart1); dfTim = dfMinus/dfFreq; // get the corresponding time value, unit: seconds} while (dfTim <0.000001 );

Its timing error generally does not exceed 0.5 microseconds, and its accuracy is related to the configurations of machines such as CPU. (End)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.