足球比分直播

定时器85078.doc

返回
定时器85078.doc_第1页
第1页 / 共6页
定时器85078.doc_第2页
第2页 / 共6页
定时器85078.doc_第3页
第3页 / 共6页
定时器85078.doc_第4页
第4页 / 共6页
定时器85078.doc_第5页
第5页 / 共6页
点击查看更多>>
资源描述:
VC 中 基 于 Windows 的 精 确 定 时中 国 科 学 院 光 电 技 术 研 究 所 游 志 宇示 例 工 程 下 载在 工 业 生 产 控 制 系 统 中 , 有 许 多 需 要 定 时 完 成 的 操 作 , 如 定 时 显 示 当 前 时 间 ,定 时 刷 新 屏 幕 上 的 进 度 条 , 上 位 机 定 时 向 下 位 机 发 送 命 令 和 传 送 数 据 等 。 特 别 是在 对 控 制 性 能 要 求 较 高 的 实 时 控 制 系 统 和 数 据 采 集 系 统 中 , 就 更 需 要 精 确 定 时 操 作 。众 所 周 知 , Windows 是 基 于 消 息 机 制 的 系 统 , 任 何 事 件 的 执 行 都 是 通 过 发 送和 接 收 消 息 来 完 成 的 。 这 样 就 带 来 了 一 些 问 题 , 如 一 旦 计 算 机 的 CPU 被 某 个 进程 占 用 , 或 系 统 资 源 紧 张 时 , 发 送 到 消 息 队 列 中 的 消 息 就 暂 时 被 挂 起 , 得 不 到实 时 处 理 。 因 此 , 不 能 简 单 地 通 过 Windows 消 息 引 发 一 个 对 定 时 要 求 严 格 的事 件 。 另 外 , 由 于 在 Windows 中 已 经 封 装 了 计 算 机 底 层 硬 件 的 访 问 , 所 以 , 要 想通 过 直 接 利 用 访 问 硬 件 来 完 成 精 确 定 时 , 也 比 较 困 难 。 所 以 在 实 际 应 用 时 , 应 针对 具 体 定 时 精 度 的 要 求 , 采 取 相 适 应 的 定 时 方 法 。VC 中 提 供 了 很 多 关 于 时 间 操 作 的 函 数 , 利 用 它 们 控 制 程 序 能 够 精 确 地 完 成 定 时和 计 时 操 作 。 本 文 详 细 介 绍 了 VC 中 基 于 Windows 的 精 确 定 时 的 七 种 方 式 , 如 下图 所 示 图 一 图 像 描 述 方 式 一 VC 中 的 WM_TIMER 消 息 映 射 能 进 行 简 单 的 时 间 控 制 。 首 先 调 用 函 数SetTimer设 置 定 时 间 隔 , 如 SetTimer0,200,NULL即 为 设 置 200ms 的 时 间 间隔 。 然 后 在 应 用 程 序 中 增 加 定 时 响 应 函 数 OnTimer, 并 在 该 函 数 中 添 加 响 应 的处 理 语 句 , 用 来 完 成 到 达 定 时 时 间 的 操 作 。 这 种 定 时 方 法 非 常 简 单 , 可 以 实 现一 定 的 定 时 功 能 , 但 其 定 时 功 能 如 同 Sleep函 数 的 延 时 功 能 一 样 , 精 度 非 常 低 ,最 小 计 时 精 度 仅 为 30ms, CPU 占 用 低 , 且 定 时 器 消 息 在 多 任 务 操 作 系 统 中 的 优先 级 很 低 , 不 能 得 到 及 时 响 应 , 往 往 不 能 满 足 实 时 控 制 环 境 下 的 应 用 。 只 可 以 用来 实 现 诸 如 位 图 的 动 态 显 示 等 对 定 时 精 度 要 求 不 高 的 情 况 。 如 示 例 工 程 中 的Timer1。 方 式 二 VC 中 使 用 sleep函 数 实 现 延 时 , 它 的 单 位 是 ms, 如 延 时 2 秒 ,用 sleep2000。 精 度 非 常 低 , 最 小 计 时 精 度 仅 为 30ms, 用 sleep 函 数 的 不 利处 在 于 延 时 期 间 不 能 处 理 其 他 的 消 息 , 如 果 时 间 太 长 , 就 好 象 死 机 一 样 , CPU占 用 率 非 常 高 , 只 能 用 于 要 求 不 高 的 延 时 程 序 中 。 如 示 例 工 程 中 的 Timer2。方 式 三 利 用 COleDateTime 类 和 COleDateTimeSpan 类 结 合 WINDOWS的 消 息 处 理 过 程 来 实 现 秒 级 延 时 。 如 示 例 工 程 中 的 Timer3 和 Timer3_1。 以 下是 实 现 2 秒 的 延 时 代 码 COleDateTime start_time COleDateTimeGetCurrentTime;COleDateTimeSpan end_time COleDateTimeGetCurrentTime-start_time;whileend_time.GetTotalSeconds 2 //实 现 延 时 2 秒{ MSG msg;GetMessageTranslateMessage DispatchMessage//以 上 四 行 是 实 现 在 延 时 或 定 时 期 间 能 处 理 其 他 的 消 息 ,//虽 然 这 样 可 以 降 低 CPU 的 占 有 率 ,//但 降 低 了 延 时 或 定 时 精 度 , 实 际 应 用 中 可 以 去 掉 。end_time COleDateTimeGetCurrentTime-start_time;}//这 样 在 延 时 的 时 候 我 们 也 能 够 处 理 其 他 的 消 息 。 方 式 四 在 精 度 要 求 较 高 的 情 况 下 , VC 中 可 以 利 用 GetTickCount函 数 ,该 函 数 的 返 回 值 是 DWORD 型 , 表 示 以 ms 为 单 位 的 计 算 机 启 动 后 经 历 的 时 间 间隔 。 精 度 比 WM_TIMER 消 息 映 射 高 , 在 较 短 的 定 时 中 其 计 时 误 差 为 15ms, 在较 长 的 定 时 中 其 计 时 误 差 较 低 , 如 果 定 时 时 间 太 长 , 就 好 象 死 机 一 样 , CPU 占用 率 非 常 高 , 只 能 用 于 要 求 不 高 的 延 时 程 序 中 。 如 示 例 工 程 中 的 Timer4 和Timer4_1。 下 列 代 码 可 以 实 现 50ms 的 精 确 定 时 DWORD dwStart GetTickCount;DWORD dwEnd dwStart;do{dwEnd GetTickCount-dwStart;}whiledwEnd 50;为 使 GetTickCount函 数 在 延 时 或 定 时 期 间 能 处 理 其 他 的 消 息 , 可 以 把 代 码 改 为 DWORD dwStart GetTickCount;DWORD dwEnd dwStart;do{MSG msg;GetMessageTranslateMessage DispatchMessagedwEnd GetTickCount-dwStart;}whiledwEnd 50;虽 然 这 样 可 以 降 低 CPU 的 占 有 率 , 并 在 延 时 或 定 时 期 间 也 能 处 理 其 他 的 消 息 , 但降 低 了 延 时 或 定 时 精 度 。方 式 五 与 GetTickCount函 数 类 似 的 多 媒 体 定 时 器 函 数 DWORD timeGetTimevoid, 该 函 数 定 时 精 度 为 ms 级 , 返 回 从 Windows 启 动 开 始 经过 的 毫 秒 数 。 微 软 公 司 在 其 多 媒 体 Windows 中 提 供 了 精 确 定 时 器 的 底 层 API持 , 利 用 多 媒 体 定 时 器 可 以 很 精 确 地 读 出 系 统 的 当 前 时 间 , 并 且 能 在 非 常 精 确 的 时间 间 隔 内 完 成 一 个 事 件 、 函 数 或 过 程 的 调 用 。 不 同 之 处 在 于 调 用 DWORD timeGetTimevoid 函 数 之 前 必 须 将 Winmm.lib 和 Mmsystem.h 添 加 到 工 程中 , 否 则 在 编 译 时 提 示 DWORD timeGetTimevoid函 数 未 定 义 。 由 于 使 用 该 函 数 是 通 过 查 询 的 方 式 进 行 定 时 控 制 的 , 所 以 , 应 该 建 立 定 时 循 环 来 进 行 定 时 事 件的 控 制 。 如 示 例 工 程 中 的 Timer5 和 Timer5_1。方 式 六 使 用 多 媒 体 定 时 器 timeSetEvent函 数 , 该 函 数 定 时 精 度 为 ms 级 。利 用 该 函 数 可 以 实 现 周 期 性 的 函 数 调 用 。 如 示 例 工 程 中 的 Timer6 和Timer6_1。 函 数 的 原 型 如 下 MMRESULT timeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, WORD dwUser, UINT fuEvent )该 函 数 设 置 一 个 定 时 回 调 事 件 , 此 事 件 可 以 是 一 个 一 次 性 事 件 或 周 期 性 事 件 。事 件 一 旦 被 激 活 , 便 调 用 指 定 的 回 调 函 数 , 成 功 后 返 回 事 件 的 标 识 符 代 码 , 否 则返 回 NULL。 函 数 的 参 数 说 明 如 下 uDelay 以 毫 秒 指 定 事 件 的 周 期 。Uresolution 以 毫 秒 指 定 延 时 的 精 度 , 数 值 越 小 定 时 器 事 件 分辨 率 越 高 。 缺 省 值 为 1ms。LpTimeProc 指 向 一 个 回 调 函 数 。DwUser 存 放 用 户 提 供 的 回 调 数 据 。FuEvent 指 定 定 时 器 事 件 类 型 TIME_ONESHOT uDelay 毫 秒 后 只 产 生 一 次 事 件TIME_PERIODIC 每 隔 uDelay 毫 秒 周 期 性 地 产 生 事 件 。 具 体 应 用 时 , 可 以 通 过 调 用 timeSetEvent函 数 , 将 需 要 周 期 性 执 行 的 任 务定 义 在 LpTimeProc 回 调 函 数 中 如 定 时 采 样 、 控 制 等 , 从 而 完 成 所 需 处 理 的事 件 。 需 要 注 意 的 是 , 任 务 处 理 的 时 间 不 能 大 于 周 期 间 隔 时 间 。 另 外 , 在 定 时 器 使用 完 毕 后 , 应 及 时 调 用 timeKillEvent将 之 释 放 。 方 式 七 对 于 精 确 度 要 求 更 高 的 定 时 操 作 , 则 应 该 使 用QueryPeranceFrequency和 QueryPeranceCounter函 数 。 这 两 个 函数 是 VC 提 供 的 仅 供 Windows 95 及 其 后 续 版 本 使 用 的 精 确 时 间 函 数 , 并 要 求 计 算机 从 硬 件 上 支 持 精 确 定 时 器 。 如 示 例 工 程 中 的Timer7、 Timer7_1、 Timer7_2、 Timer7_3。QueryPeranceFrequency函 数 和 QueryPeranceCounter函 数 的 原 型如 下 BOOL QueryPeranceFrequencyLARGE_INTEGER * lpFrequency;BOOL QueryPeranceCounterLARGE_INTEGER * lpCount;数 据 类 型 ARGE_INTEGER 既 可 以 是 一 个 8 字 节 长 的 整 型 数 , 也 可 以 是 两 个 4字 节 长 的 整 型 数 的 联 合 结 构 , 其 具 体 用 法 根 据 编 译 器 是 否 支 持 64 位 而 定 。 该类 型 的 定 义 如 下 typedef union _LARGE_INTEGER{struct{DWORD LowPart ;// 4 字 节 整 型 数LONG HighPart;// 4 字 节 整 型 数};LONGLONG QuadPart ;// 8 字 节 整 型 数}LARGE_INTEGER ;在 进 行 定 时 之 前 , 先 调 用 QueryPeranceFrequency函 数 获 得 机 器 内 部定 时 器 的 时 钟 频 率 , 然 后 在 需 要 严 格 定 时 的 事 件 发 生 之 前 和 发 生 之 后 分 别 调 用QueryPeranceCounter函 数 , 利 用 两 次 获 得 的 计 数 之 差 及 时 钟 频 率 , 计 算 出事 件 经 历 的 精 确 时 间 。 下 列 代 码 实 现 1ms 的 精 确 定 时 LARGE_INTEGER litmp; LONGLONG QPart1,QPart2;double dfMinus, dfFreq, dfTim; QueryPeranceFrequencydfFreq doublelitmp.QuadPart;// 获 得 计 数 器 的 时 钟 频率QueryPeranceCounterQPart1 litmp.QuadPart;// 获 得 初 始 值do{QueryPeranceCounterQPart2 litmp.QuadPart;//获 得 中 止 值dfMinus doubleQPart2-QPart1;dfTim dfMinus / dfFreq;// 获 得 对 应 的 时 间 值 , 单 位为 秒}whiledfTim0.001;其 定 时 误 差 不 超 过 1 微 秒 , 精 度 与 CPU 等 机 器 配 置 有 关 。 下 面 的 程 序 用 来测 试 函 数 Sleep100的 精 确 持 续 时 间 LARGE_INTEGER litmp; LONGLONG QPart1,QPart2;double dfMinus, dfFreq, dfTim; QueryPeranceFrequencydfFreq doublelitmp.QuadPart;// 获 得 计 数 器 的 时 钟 频率QueryPeranceCounterQPart1 litmp.QuadPart;// 获 得 初 始 值Sleep100;QueryPeranceCounterQPart2 litmp.QuadPart;//获 得 中 止 值dfMinus doubleQPart2-QPart1;dfTim dfMinus / dfFreq;// 获 得 对 应 的 时 间 值 , 单 位 为 秒 由 于 Sleep函 数 自 身 的 误 差 , 上 述 程 序 每 次 执 行 的 结 果 都 会 有 微 小 误 差 。 下 列代 码 实 现 1 微 秒 的 精 确 定 时 LARGE_INTEGER litmp; LONGLONG QPart1,QPart2;double dfMinus, dfFreq, dfTim; QueryPeranceFrequencydfFreq doublelitmp.QuadPart;// 获 得 计 数 器 的 时 钟 频率QueryPeranceCounterQPart1 litmp.QuadPart;// 获 得 初 始 值do{QueryPeranceCounterQPart2 litmp.QuadPart;//获 得 中 止 值dfMinus doubleQPart2-QPart1;dfTim dfMinus / dfFreq;// 获 得 对 应 的 时 间 值 , 单 位为 秒}whiledfTim0.000001;其 定 时 误 差 一 般 不 超 过 0.5 微 秒 , 精 度 与 CPU 等 机 器 配 置 有 关 。 完
展开阅读全文
收藏
下载资源

加入会员免费下载





足球比分直播