下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、VisualC+实现微秒级精度定时器I 如国 i 在工产控制系统中,有许多需要定时完成的操作,如:定时显示当前时间,定时刷新屏幕上的进度条,上位机定时向下位机发送命令和传送数据等。特别是在对控制性能要求较高的控制系统和数据采集系统中,就更需要精确定时操作。众所周知,Windows 是基于消息机制的系统,任何事件的执行都是通过发送和接收消息来完成的。这样就带来了一些问题,如一旦计算机的 CPU 被某个进程占用,或系统资源紧张时,发送到消息队列中的消息就暂时被挂起,得不到实时处理。因此,不能简单地通过 Windows 消息引发一个对定时要求严格的事件。另外,由于在 Windows 中已经封装了计算
2、机底层硬件的访问,所以要想通过直接利用访问硬件来完成精确定时,也比较困难。在实际应用时,应针对具体定时精度的要求,采取与之相适应的定时方法。本实例实现了一中微秒级的精确定时,程序的界面提供了两个Edit编辑框,其中一个编辑框输入用户理想的定时长度,另外一个编辑框返回实际的时间长度,经过大量的实验测试,一般情况下误差不超过5 个微秒。程序的运行界面如图一所示:图一、实现微秒级的精确定时器一、实现方法VisualC+中提供了很多关于时间操作的函数,利用它们控制程序能够精确地完成定时和计时操作。VisaulC+中的 WM_TIME 辅息映射能进行简单的时间控制。首先调用函数 SetTimer()设置
3、定时间隔(退出程序时别忘了调用和 SetTimer()配对使用的 KillTimer()函数),如 SetTimer(0,200,NULL)即为设置 200ms 的时间间隔。然后在应用程序中增加定时响应函数OnTimer(),并在该函数中添加响应的处理语句,用来完成到达定时时间的操作。这种定时方法非常简单,但其定时功能如同 Sleep()函数的延时功能一样,精度非常低,只可以用来实现诸如位图的动态显示等对定时精度要求不高的情况。微软公司在其多媒体 Windows 中提供了精确定时器的底层 API 支持。利用多媒体定时器可以很精确地读出系统的当前时间,并且能在非常精确的时间间隔内完成一个事件、函
4、数或过程的调用。利用多媒体定时器的基本功能,可以通过两种方法实现精确定时。1)使用 timeGetTime()函数,该函数定时精度为 ms 级,返回从 Windows 启动开始所经过的时间。由于使用该函数是通过查询的方式进行定时控制的,所以,应该建立定时循环来进行定时事件的控制。2)使用 timeSetEvent()函数,该函数原型如下:MMRESULTtimeSetEvent(UINTuDelay,UINTuResolution,LPTIMECALLBACKIpTimeProjDWORDdwUserUINTfuEvent);该函数的参数说明如下:参数 uDelay 表示延迟时间;参数 uRe
5、solution 表示时间精度,在 Windows 中缺省值为 1ms;lpTimeProc 表示回调函数,为用户自定义函数,定时调用;参数 dwUser 表示用户提供的回调数据;参数 fuEvent 为定时器的事件类型,TIME_ONESHOT表示执行一次;TIME_PERIODIC 周期性执行。具体应用时,可以通过调用 timeSetEvent()函数,将需要周期性执行的任务定义在 lpTimeProc 回调函数中(如:定时采样、控制等),从而完成所需处理的事件。需要注意的是:任务处理的时间不能大于周期间隔时间。另外,在定时器使用完毕后,应及时调用 timeKillEvent()将之释放。
6、下面这段代码的主要功能是设置两个时钟定时器,一个间隔是 1ms,一个间隔是 2s。每执行一次,把当前系统时钟值输入文件cure.out中,以比较该定时器的精确度。# defineONE_MILLI_SECOND1/定义 1ms 和 2s 时钟间隔,以 ms 为单位;# defineTWO_SECOND2000#defineTIMER_ACCURACY1/定义时钟分辨率,以 ms 为单位UINTwTimerRes_1ms,wTimerRes_2s;/定义时间间隔UINTwAccuracy;/定义分辨率UINTTimerID_1ms,TimerID_2s;/定义定时器句柄/CCureApp:CCu
7、reApp():fout(cure.out,ios:out)打开输出文件cure.out/给时间间隔变量赋值wTimerRes_1ms=ONE_MILLI_SECOND;wTimerRes_2s=TWO_SECOND;TIMECAPStc;/ 利 用 函 数timeGetDevCaps取 出 系 统 分 辨 率 的 取 值 范 围 , 如 果 无 错 则 继 续 ;if(timeGetDevCaps(&tc,sizeof(TIMECAPS)=TIMERR_NOERROR)wAccuracy=min(max(tc.wPeriodMin,/分辨率的值不能超出系统的取值范围TIMER_ACC
8、URACY),tc.wPeriodMax);/调用 timeBeginPeriod 函数设置定时器的分辨率timeBeginPeriod(wAccuracy);/设置定时器InitializeTimer();CCureApp:CCureApp()fout结束时钟fout+ms:1ms:)/加装 1ms 定时器voidCCureApp:StartOneMilliSecondTimer()(if(TimerID_1ms=timeSetEvent(wTimerRes_1ms,wAccuracy,(LPTIMECALBACK)OneMilliSecondProc,/回调函数;(DWORD)this,/
9、用户传送到回调函数的数据;TIME_PERIODIC)=0)/周期调用定时处理函数;(AfxMessageBox(不能进行定时!,MB_OK|MB_ICONASTERISK);)elsefout16ms 计时:endl;/不等于 0 表明加装成功,返回此定时器的句柄;)在精度要求较高的情况下,如要求定时误差不大于 1ms 时,还可以利用 GetTickCount()函数返回自计算机启动后的时间,该函数的返回值是 DWORD1,表示以 ms 为单位的计算机启动后经历的时间间隔。通过两次调用 GetTickCount()函数,然后控制它们的差值来取得定时效果.下列的代码可以实现 50ms 的精确定
10、时,其误差是毫秒级的。/起始值和中止值DWORDdwStart,dwStop;dwStop=GetTickCount();while(TRUE)/上一次的中止值变成新的起始值dwStart=dwStop;/此处添加相应控制语句dodwStop=GetTickCount();while(dwStop50dwStart);用上述两种方式取得的定时效果虽然在许多场合已经满足实际的要求,但由于它们的精度只有毫秒级的,而且在要求定时时间间隔小时,实际定时误差大。对于精确度要求更高的定时操作,则应该使用QueryPerformanceFrequency()和 QueryPerformanceCounter
11、()函数。这两个函数是 VisualC+提供并且仅供 Windows95 及其后续版本使用,其精度与 CPU 的时钟频率有关,它们要求计算机从硬件上支持精确定时器。QueryPerformanceFrequency()函数和 QueryPerformanceCounter()函数的原型如下:BOOLQueryPerformanceFrequency(LARGE_INTEGER*lpFrequency);BOOLQueryPerformanceCounter(LARGE_INTEGER*lpCount);上述两个函数的参数的数据类型 LARGE_INTEGE 既可以是一个 8 字节长的整型数,
12、也可以是两个 4字节长的整型数的联合结构,其具体用法根据编译器是否支持 64 位而定。该类型的定义如下:typedefunion_LARGE_INTEGERstructDWORDLowPart;/4 字节整型数LONGHighPart;/4 字节整型数;LONGQuadPart;/8 字节整型数LARGE_INTEGER;使用 QueryPerformanceFrequency()和 QueryPerformanceCounter()函数进行精确定时的步骤如下:1、首先调用 QueryPerformanceFrequency()函数取得高精度运行计数器的频率 f,单位是每秒多少次(n/s),此
13、数一般很大;2、在需要定时的代码的两端分别调用 QueryPerformanceCounter()以取得高精度运行计数器的数值 n1、n2,两次数值的差值通过 f 换算成时间间隔,t=(n2-n1)/f,当 t 大于或等于定时时间长度时,启动定时器;二、编程步骤1、启动 VisualC+6.0,生成一个基于对话框的应用程序,将程序命名为HightTimer;2、在对话框面板中添加控件,布局如图一所示,其中包含两个静态文本框,两个编辑框和两个按纽。上面和下面位置的编辑框的 ID 分别为 IDC_TESTSIDC_ACTUALEXIT按纽的 ID 为 IDOK,TEST按纽 ID 为 ID_TES
14、T;3、通过 ClassWizard 添加成员变量,两个编辑框控件分别对应为 DWORDm_dwTesUDWORDm_dwAct 另外添加TEST按纽的鼠标单击消息处理函数;4、添加代码,编译运行程序。三、程序代码/LARGE_INTEGERMySleep(LARGE_INTEGERInterval)/功能:执行实际的延时功能,Interval 参数为需要执行的延时与时间有关的数量,此函数返回执行后实际所用的时间有关的数量;LARGE_INTEGERprivious,current,Elapse;QueryPerformanceCounter(&privious);current=pr
15、ivious;while(current.QuadPart-privious.QuadPartInterval.QuadPart)QueryPerformanceCounter(¤t);Elapse.QuadPart=current.QuadPart-privious.QuadPart;returnElapse;voidCHightTimerDlg:OnTest()/TODO:AddyourcontrolnotificationhandlercodehereUpdateData(TRUE);/取输入的测试时间值到与编辑框相关联的成员变量 m_dwTest 中;LARGE_I
16、NTEGERfrequence;/取高精度运行计数器的频率,若硬件不支持则返回 FALSEif(!QueryPerformanceFrequency(&frequence)MessageBox(Yourcomputerhardwaredoesntsupportthehigh-resolutionperformancecounter,NotSupport,MB_ICONEXCLAMATION|MB_OK);LARGE_INTEGERtest,ret;/通过频率换算微秒数到对应的数量(与 CPU 寸钟有关),1 秒=1000000 微秒;test.QuadPart=frequence.QuadPart*m_dwTest/1000000;ret=MySleep(test);/调用此函数开
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026国网江西省电力公司高校毕业生提前批招聘笔试参考题库浓缩500题及答案详解(有一套)
- 备战2026中考英语语法百题分类训练 专题09 冠词100题(中考真题+中考模拟)(原卷版)
- 2026秋季国家管网集团云南公司高校毕业生招聘笔试参考题库(浓缩500题)带答案详解(培优)
- 瘦吧减肥合同
- 2026秋季国家管网集团共享运营分公司高校毕业生招聘笔试参考题库(浓缩500题)含答案详解(夺分金卷)
- 2023国网陕西省电力公司高校毕业生提前批招聘笔试参考题库附答案
- 2026广西北部湾投资集团有限公司高校毕业生校园招聘考试参考试题(浓缩500题)含答案详解(夺分金卷)
- 2026年山东能源集团兖矿新疆能化有限公司技能操作岗位人员招考前自测高频考点模拟试题浓缩300题附答案
- 2026国网上海市电力公司高校毕业生提前批招聘(约450人)笔试备考题库浓缩500题附答案详解(培优)
- 2025至2030中国钢铁金融行业市场发展分析及发展趋势与投资机会报告
- 2025年茶艺师职业技能鉴定理论试卷(含茶艺文化)及答案
- 感染后闭塞性细支气管炎(PIBO)专家共识(2025)解读
- 直播安全消防知识培训课件
- 深圳应急贷款知识培训课件
- 纪念抗战胜利 坚定民族信念
- 2025年下半年四川甘孜州考试招聘事业单位人员138人考试参考试题及答案解析
- 2025云南省交通投资建设集团有限公司下属曲靖管理处收费员招聘(76人)考试参考试题及答案解析
- 2025年法院书记员职位选拔综合能力测试题(附答案)
- 养老机构劳务合同标准版范本
- 2025驻村工作队员工作总结
- 2025四川省现代种业发展集团华峰汇农农业科技有限公司招聘3人考试参考试题及答案解析
评论
0/150
提交评论