c#微秒级定时器的实现,

  c#微秒级定时器的实现,

  在工业生产控制系统中,有许多操作需要定时完成,如定时显示当前时间,定时刷新屏幕上的进度条,定时从上位机向下位机发送命令和数据等。特别是在控制性能要求很高的控制系统和数据采集系统中,精确的定时操作更是必不可少。众所周知,Windows是一个基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。这就带来了一些问题,比如一旦计算机的CPU被某个进程占用,或者系统资源紧张,发送到消息队列的消息就被暂时挂起,无法实时处理。所以不能简单的通过Windows消息引发一个有严格计时要求的事件。另外,由于对计算机底层硬件的访问已经封装在Windows中,直接使用访问硬件很难完成精确计时。在实际应用中,应根据具体的计时精度要求,采用合适的计时方法。

  这个例子实现了一微秒级的精确定时。程序的界面提供了两个“编辑”编辑框,其中一个输入用户的理想计时长度,另一个返回实际时间长度。经过大量的实验测试,误差一般小于5微秒。程序运行界面如图1所示:

  图一。微秒级精密定时器的实现

  一、实施方法

  Visual C提供了许多关于时间操作的函数,通过这些函数,控制程序可以准确地完成计时和定时操作。Visaul C中的WM_TIMER消息映射可以进行简单的时间控制。首先调用函数SetTimer()设置计时间隔(退出程序时别忘了调用与SetTimer()配对的KillTimer()函数)。例如,settimer (0,200,NULL)是200ms的时间间隔。然后在应用程序中加入定时响应函数OnTimer(),在这个函数中加入响应处理语句,完成到达定时时间的操作。这种计时方法很简单,但是它的计时功能和Sleep()函数的delay函数一样,精度很低,只能用于实现位图的动态显示等对计时精度要求不高的场合。

  微软在其多媒体窗口中为精确计时器提供底层API支持。多媒体定时器可以准确地读取系统的当前时间,并且可以在非常准确的时间间隔内完成一个事件、函数或过程的调用。利用多媒体定时器的基本功能,有两种方法可以实现精确定时。1)使用timeGetTime()函数,该函数具有毫秒级的计时精度,并返回从窗口开始所经过的时间。因为此函数用于通过查询来控制定时,所以应该建立一个定时周期来控制定时事件。2)使用timeSetEvent()函数,其原型如下:mmresult timesetevent (uintdelay,UINT uResolution,LPTIMECALLBACK lpTimeProc,DWORD dwUser,UINT fuevent);

  该函数的参数描述如下:参数uDelay表示延迟时间;参数uResolution表示时间精度,Windows中默认值为1ms;LpTimeProc代表回调函数,是自定义函数,定期调用;参数dwUser表示用户提供的回调数据;参数fuEvent是定时器的事件类型,TIME_ONESHOT表示执行一次;TIME_PERIODIC:定期执行。在应用中,可以调用timeSetEvent()函数来定义lpTimeProc回调函数中需要定期执行的任务(如定时采样、控制等。),从而完成需要处理的事件。请注意,任务处理时间不能大于周期间隔时间。另外,定时器用完之后,要及时调用timeKillEvent()来释放。下面这段代码的主要作用是设置两个时钟定时器,一个间隔1ms,一个间隔2s。每次执行时,将当前系统时钟值输入到“cure.out”文件中,以比较计时器的准确性。

  # define ONE_MILLI_SECOND 1 //以ms为单位定义1ms和2s时钟间隔;

  #定义两秒2000

  # define TIMER_ACCURACY 1 //定义时钟分辨率,以女士为单位

  UINT wTimerRes_1ms,wTimerRes _ 2s//定义时间间隔

  UINT wAccuracy//定义分辨率

  UINT TimerID_1ms,TimerID _ 2s//定义定时器句柄

  ///////////////////////////////

  CCU re prep:CCU re prep():fout( cure。out ,ios:out) //打开输出文件治愈。出去;

  {

  //给时间间隔变量赋值

  wTimerRes _ 1 ms=ONE _ MILLI _ SECOND;

  wTimerRes _ 2s=两秒钟

  时间上限TC;

  //利用函数timeGetDevCaps取出系统分辨率的取值范围,如果无错则继续;

  if(timeGetDevCaps(&tc,sizeof(time caps))==TIMERR _ no error)

  {

  wAccuracy=最小值(最大值(TC。wperiodmin,//分辨率的值不能超出系统的取值范围

  TIMER_ACCURACY)、TC。wperiodmax);

  //调用时间开始周期函数设置定时器的分辨率

  timeBeginPeriod(wAccuracy);

  //设置定时器

  初始化timer();

  }

  }

  ccureprep:~ ccureprep()

  {

  富特结束时钟endl//结束时钟

  timeKillEvent(time rid _ 1 ms);//删除两个定时器

  time kill事件(time rid _ 2s);//删除设置的分辨率

  timeEndPeriod(wAccuracy);

  }

  void ccureprep:初始化计时器()

  {

  startonemillisendtimer();

  starttwossecondtimer();

  }

  //1毫秒定时器的回调函数,类似于中断处理程序,一定要声明为全局电脑语言函数,

  //否则编译会有问题

  void PASCAL onemilliseconproc(UINT wTimerID,UINT msg,DWORD dwUser,

  双字dw1、双字dw2)

  {

  //定义计数器

  静态int ms=0;

  CCU re prep * app=(CCU re prep *)dw用户;

  //取得系统时间,以女士为单位

  DWORD osBinaryTime=GetTickCount();

  //输出计数器值和当前系统时间

   app-fout ++ ms :1毫秒:

  }

  //加装一毫秒定时器

  void ccureprep:startonemillisendtimer()

  {

  if((time rid _ 1 ms=time setevent(wTimerRes _ 1 ms,wAccuracy,

  (LPTIMECALBACK)OneMil liSecondProc,//回调函数;

  (DWORD)这个,//用户传送到回调函数的数据;

  TIME_PERIODIC))==0)//周期调用定时处理函数;

  {

  AfxMessageBox(不能进行定时!,MB _ OK MB _ icon星号);

  }

  其他

  16毫秒计时: endl//不等于0表明加装成功,返回此定时器的句柄;

  }

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • vue中的定时器清不掉,vue设置定时器调用方法,vue如何设置定时器和清理定时器
  • js定时方法,js的定时器函数
  • js定时方法,js的定时器函数,js定时器的使用(实例讲解)
  • js定时器重复执行怎么停止,js每隔几秒执行一次
  • js定时器重复执行怎么停止,js每隔几秒执行一次,js定时器(执行一次、重复执行)
  • js定时器重复执行怎么停止,,js定时器(执行一次、重复执行)
  • js中2种定时器的使用及清除的实现过程,js中两种定时器的设置及清除
  • js中2种定时器的使用及清除的实现过程,js中两种定时器的设置及清除,JS中2种定时器的使用及清除的实现
  • ,,Qt定时器和随机数详解
  • ,,Qt基础开发之Qt多线程类QThread与Qt定时器类QTimer的详细方法与实例
  • ,,IOS 中NSTimer定时器的使用
  • C语言定时器,c语言定时器程序编写
  • C语言定时器,c语言定时器程序编写,C语言实现简单的定时器
  • java 定时器的多种实现方式有哪些,java定时器的实现方式有几种
  • java 定时器的多种实现方式有哪些,java定时器的实现方式有几种,Java 定时器的多种实现方式
  • 留言与评论(共有 条评论)
       
    验证码: