In the industrial production control system, there are many operations that need to be done regularly, such as: Timing display the current time, periodically refresh the progress bar on the screen, the host computer timing down the machine to send commands and transmit data. Especially in the control system and data acquisition system requiring high control performance, precise timing operation is more necessary. As we all know, Windows is a messaging-based system, and any event execution is done by sending and receiving messages. This brings some problems, such as when the CPU of a computer is occupied by a process, or when system resources are tight, messages sent to message queues are temporarily suspended and cannot be processed in real time. Therefore, you cannot simply raise an event that is strictly timed by Windows messages. In addition, because of the access to the underlying hardware of the computer that is already encapsulated in Windows, it is also difficult to achieve precise timing by directly using the access hardware. In practical application, the timing method should be adopted to meet the requirement of specific timing precision.
This example realizes the precise timing of a microsecond level, the program's interface provides two edit boxes, one for the user's ideal timing length, the other for the actual length of time, and after a large number of experimental tests, the general error is no more than 5 microseconds. The running interface of the program is shown in Figure one:
Figure I, realize the precise timer of microsecond level
One, the realization method
Visual C + + provides a number of functions on time operations that can be used to accurately perform timing and timing operations. The WM_TIMER message mapping in Visaul C + + can perform simple time control. Call the function SetTimer () first to set the timed interval (don't forget to call the KillTimer () function used by the SetTimer () pair when exiting the program), such as SetTimer (0,200,null), which is the time interval for setting 200ms. It then adds the timed response function OnTimer () in the application and adds the processing statement of the response to the function to complete the operation at timed time. This timing method is very simple, but its timing function as the sleep () function of the delay function, the precision is very low, can only be used to achieve such as the dynamic display of bitmaps, such as the timing of the accuracy of the situation is not high.
Microsoft provides the low-level API support for precise timers in its multimedia windows. The multimedia timer can be used to accurately read out the current time of the system and to complete an event, function, or process call at a very precise time interval. Using the basic function of the multimedia timer, the precise timing can be realized by two methods. 1) using the timeGetTime () function, which has a timed precision of MS, returns the time elapsed since Windows started. Due to the use of this function is a query to control the timing of the time, so we should establish a timed cycle to control the timing of events. 2 uses the timeSetEvent () function, which is a prototype of the following:
MMRESULT timeSetEvent(UINT uDelay,UINT uResolution,LPTIMECALLBACK lpTimeProc,
DWORD dwUser,UINT fuEvent);
The parameters of the function are described as follows: The parameter udelay represents the delay time, the parameter uresolution represents the time precision, the default value in Windows is 1ms;lptimeproc, the callback function, and the user-defined function, timed call; The parameter dwuser represents the user-supplied callback data, fuevent the event type of the timer, time_oneshot the execution once; Time_periodic: Periodic execution. When applied, the tasks that need to be performed periodically can be defined in the Lptimeproc callback function (such as timed sampling, control, etc.) by calling the timeSetEvent () function to complete the event that needs to be handled. It should be noted that the task processing time cannot be greater than the cycle time interval. In addition, after the use of the timer, should promptly call Timekillevent () to release. The main function of the following code is to set up two clock timers, one interval is 1ms, and one interval is 2s. For each execution, enter the current system clock value into the file "Cure.out" to compare the timer's accuracy.
# define One_milli_second 1//define 1ms and 2s clock intervals, in MS;
# define Two_second # define Timer_accuracy 1// Define the clock resolution, in MS-unit
UINT wtimerres_1ms,wtimerres_2s//define interval
UINT waccuracy;//define resolution
UINT TIMERID_1MS,TIMERID_ 2s; Define timer handle
///////////////////////////////
Ccureapp::ccureapp (): Fout ("Cure.out", ios::out)//Open output file Cure.out ';
{
//Assign a value to a time interval variable
wtimerres_1ms = One_milli_second;
Wtimerres_2s = Two_second;
Timecaps TC;
//Use function Timegetdevcaps to take out the range of system resolution, if it is correct, continue;
if (Timegetdevcaps (&tc,sizeof (timecaps) ==timerr_noerror)
{
Waccuracy=min (the value of Max (Tc.wperiodmin,//resolution cannot exceed system range
Timer_accuracy), Tc.wperiodmax);
Call the Timebeginperiod function to set the resolution of the timer
Timebeginperiod (waccuracy);
Set timer
Initializetimer ();
}
Ccureapp:: ~ccureapp ()
{
Fout << end Clock << endl;//End Clock
timekillevent (timerid_1ms); Delete Two timer
Timekillevent (TIMERID_2S);//Remove Settings Resolution
Timeendperiod (Waccuracy);
}
void Ccureapp::initializetimer ()
{
Startonemillisecondtimer ();
Starttwosecondtimer ();
}
//1ms Timer callback function, similar to interrupt handler, be sure to declare as global PASCAL function,
//Otherwise compile problem
void PASCAL Onemillisecondproc (UINT Wtimerid, UINT Msg,dword dwuser,
DWORD dwl,dword dw2)
{
///define counter
static int ms = 0;
Ccureapp *app = (Ccureapp *) Dwuser;
//Get system time, in MS Unit
DWORD osbinarytime = GetTickCount ();
Output counter value and current system time
app->fout<<++ms<<: 1ms: "
}
//Add 1ms timer
void Ccureapp:: Startonemillisecondtimer ()
{
if (timerid_1ms = timeSetEvent (wtimerres_1ms, Waccuracy,
(Lptimecalback) Onemil Lisecondproc,//callback function;
(DWORD) This,//user passed data to the callback function;
time_periodic) = = 0)/Cycle call timed processing function;
{
Af Xmessagebox ("Can't be timed!") ", MB_OK | Mb_iconasterisk);
}
Else
Fout << 16ms timing: << Endl; is not equal to 0 indicates a successful reload, returns the handle to this timer;
}