http://qsyang.yeah.net
现代微机原理与接口技术
1
第 6章 定时与计数技术
6.1 概 述
6.1.1 定时与计数
1.定时定义,提供的时间基准。
分类,内部定时、外部定时。
2.计数定时与计数本质上是一致的。
计数的信号随机,定时的信号具有周期性。
3.应用
http://qsyang.yeah.net
现代微机原理与接口技术
2
6.1.2 定时方法
1.软件定时通过软件指令周期方法定时,如执行循环程序。
增加 CPU负担,通用性差,一般用于短延时。
2.不可编程硬件定时采用中小规模 IC构成。
不增加 CPU负担,成本低,定时值不可改变。
3.可编程硬件定时采用可编程计数器完成,软件可改变计数值。
可编程定时 /计数器,实质上定时和计数本质上都是脉冲计数器,定时计的是内部基准时钟源产生的脉冲,
计数是计外部脉冲。
http://qsyang.yeah.net
现代微机原理与接口技术
3
6.1.3 定时 /计数器基本原理
1.内部逻辑
CPU接口:
译码、操作外设接口:
时钟信号、
控制、输出内部逻辑:
REG
2.工作过程设初值、控制、输出
http://qsyang.yeah.net
现代微机原理与接口技术
4
6.2 Intel 8254
8253→8254→82801BA 。
6.2.1 8254-2基本功能
3个独立的 16位定时 /计数器( T/C);
每个 T/C功能:
可按二、十进制( BCD)计数;
有 6种不同的工作方式;
最高频率 10MHz; (82801BA为 14.31818MHz)
有读回状态功能。 (8253没有 )
http://qsyang.yeah.net
现代微机原理与接口技术
5
6.2.2 8254-2结构与引脚
1.内部逻辑总线缓冲器 [8位 R/W],写工作方式、计数初值、当前计数值
http://qsyang.yeah.net
现代微机原理与接口技术
6
2.计数器内部逻辑
16位当前计数值锁存器 OL
16位减 1计数器 CE
16位计数初值寄存器 CR
OUT
(减 1至 0时)
MSBLSB锁存后读出当前值
MSBLSB装入 /读出初值
&
CLK
GATE
CR,16位写入 [两次 ]、清零
CE,16位写入、计数、输出
OL,16位先锁存再读出状态 REG,8位先锁存再读出注意,GATE信号的作用与应用,重写 CR的效果。
计数初值,N=fCLKi/fOUTi,在不同工作方式及定时 /计数时的应用不同。
http://qsyang.yeah.net
现代微机原理与接口技术
7
3.外部引脚
(1)译码,CS与 A1A0:
(2)读 /写,RD,WR;
http://qsyang.yeah.net
现代微机原理与接口技术
8
4.CPU操作功能及命令
I/O端口地址,8254提供四个端口 (使用 A1A0);
命令,初始化 —设置工作方式、设置计数器初值;
操 作 —重写计数器初值、取状态命令。
状态,当前计数值、工作方式及当前状态。
I/O端口操作冲突时解决方法:
写工作方式与写读取状态命令采用特征位方法;
读取当前计数值或读取状态采取时序方法。
8254命令关系表:
http://qsyang.yeah.net
现代微机原理与接口技术
9
操 作 特征位 时序
D7D6
0 1 0 0 0 计数初值写入 0#计数器 ** 无
0 1 0 0 1 计数初值写入 1#计数器 ** 无
0 1 0 1 0 计数初值写入 2#计数器 ** 无
0 1 0 1 1 向控制字 REG写控制字 00~10 无写,读计数值 /状态,命令
11 无
0 0 1 0 0 读 0#计数器当前计数值 无 前一命令 A1A0=11时,
D7D6为 11且 D5为 0或 D7D6
为非 11且 D5D4为 00时,
读取的是当前计数值;
D7D6为 11且 D4为 0读取的是状态。
读 0#计数器状态 无
0 0 1 0 1 读 1#计数器当前计数值 无读 1#计数器状态 无
0 0 1 1 0 读 2#计数器当前计数值 无读 2#计数器状态 无
0 0 1 1 1 无操作
1 * * * * 禁止使用
0 1 1 * * 无操作
CS RD WR A1 A0
http://qsyang.yeah.net
现代微机原理与接口技术
10
6.2.3 8254-2命令及编程
1.工作方式控制字( A1A0=11)
特征位,D7D6=00~10,D5D4=01~11;
D7D6选择计数器,00- T/C0; 01- T/C1; 10- T/C2
D5D4选择读 /写方式,01-只写低字节; 10-只写高字节; 11-先写低字节再写高字节( 16位)
D3D2D1选择工作方式,000~ 101六种工作方式,
X10-方式 2,X11-方式 3
例,MOV AL,01110100B ; T/C1,先低后高字节
OUT 43H,AL ;方式 2,二进制方式
http://qsyang.yeah.net
现代微机原理与接口技术
11
2.计数初值
(1)不同通道的计数初值写到不同地址中;
A1A0=00~10
(2)每次写入一个字节;
(3)根据控制字定义,决定高、低字节写入方法。
(4)初始值的范围是:
二进制为 65536(0000H)~1(0001H)。
十进制为 10000(0000H)~1(00001H)。
http://qsyang.yeah.net
现代微机原理与接口技术
12
3.T/C初始化
(1)写工作方式控制字
(2)设置计数初值例,MOV AL,01110101B; T/C1,先低后高字节,方式 2,BCD
OUT 43H,AL
MOV AX,2000H ; 计数初值为 2000
OUT 41H,AL ;
MOV AL,AH
OUT 41H,AL ;
MOV AL,00010110B; T/C0,只低字节,方式 3,二进制
OUT 43H,AL
OUT 40H,50H ; 计数初值为 50H( 80)
注意,(1)每个使用的 T/C均要初始化;
(2)计数初值的设置与 T/C的 CLK密切相关;
(3)计数初值的设置方法由控制字决定。
http://qsyang.yeah.net
现代微机原理与接口技术
13
4.T/C数据读取
(1)读取当前计数值方法 1
工作方式控制字 (A1A0=11)D7D6= 00~ 01,D5D4=00
(a)锁存当前计数值或禁止计数
(b)读取当前计数值例,MOV AL,01000101B; T/C1,锁存;先低后高字节,方式 2,BCD
OUT 43H,AL
IN AL,41H
MOV AH,AL
IN AL,41H
XCHG AH,AL ; AX为 T/C1当前计数值
http://qsyang.yeah.net
现代微机原理与接口技术
14
(2)读取当前计数值方法 2—使用读回命令特征位,D7D6=11。 (A1A0=11)
功能选择,锁存状态- D5D4=10;
锁存计数值- D5D4=01;
锁存状态与计数值- D5D4=00。 (先读状态再读计数值)
计数器选择,D1=1—T/C0,D2=1—T/C1,D3=1—T/C2
特点,控制字同时只能锁存单个通道,
读回命令可同时锁存多个通道。
http://qsyang.yeah.net
现代微机原理与接口技术
15
例,MOV AL,11010100B ; T/C1,锁存计数值
OUT 43H,AL
IN AL,41H;
MOV AH,AL
IN AL,41H
XCHG AH,AL ; AX为当前计数值
MOV AL,11011010B ; T/C0,T/C2锁存计数值
OUT 43H,AL
IN AL,40H;
MOV AH,AL
IN AL,40H
XCHG AH,AL ; AX为 T/C0当前计数值
IN AL,42H;
MOV AH,AL
IN AL,42H
XCHG AH,AL ; AX为 T/C2当前计数值
http://qsyang.yeah.net
现代微机原理与接口技术
16
(3)读取计数器当前状态 —使用读回命令例,MOV AL,11100100B ; T/C1,锁存状态值
OUT 43H,AL
IN AL,41H ;若 AL=00110101,表示 T/C1;为方式 2,BCD码,先低后高;读 /写,当前 OUT为低电平
MOV AL,11100010B ;T/C0,锁存状态值
OUT 43H,AL
IN AL,40H ;若 AL=00010110,表示 T/C0;为方式 3,二进制码,只有低;字节,当前 OUT为低电平读出的状态字格式:
http://qsyang.yeah.net
现代微机原理与接口技术
17
6.2.4 8254-2工作方式
1.方式 0—计数结束时中断特点,一次计数;
GATE高允许、下降 暂停,低 禁止,上升 继续 计数;
WR#写 [重写 ]后下一脉冲下降沿 重新 计数;
OUT在控制字或计数初值写完时变低、计数值为 0时变高 (N+1个低 )。
http://qsyang.yeah.net
现代微机原理与接口技术
18
2.方式 1—硬件可重触发单稳特点,一次计数;
GATE上升 重新,高与下降和低 不影响 计数;
WR#写 [重写 ]在下次 GATE从 0到 1的跳变时有效;
OUT在写入控制字后变高,开始计数时变低、计数值为 0时变高 (N个低 )。
http://qsyang.yeah.net
现代微机原理与接口技术
19
3.方式 2—频率发生器特点,多次计数;
GATE上升 重新,高允许、下降 停止,低 禁止 计数;
WR#写 [重写 ]在下次计数时有效;
OUT在计数值为 1时输出宽度为 1个 CLK的负脉冲 (周期为 N,频率为 1/N)。
http://qsyang.yeah.net
现代微机原理与接口技术
20
4.方式 3—方波发生器特点,多次计数;
GATE上升 重新,高允许、下降 停止,低 禁止 计数;
WR#写 [重写 ]在下次计数时有效;
OUT在写入控制字后变高,计数开始后,采用每脉冲计数减 2:
当计数初值为偶数时,计数到 0时反向。脉冲宽度 T× n/2
当计数初值为奇数时,OUT变高的第一 CLK减 1后装入 CE,其余每个脉冲计数减 2。 OUT正脉冲时,计数到 0的下一个 CLK时
OUT反向 OUT正脉冲宽度为 T× (n+1)/2 ; OUT负脉冲时在计数到 0
时反向。负脉冲宽度为 T× (n-1)/2
http://qsyang.yeah.net
现代微机原理与接口技术
21
特点,一次计数;
GATE上升 重新,高允许、下降停止、低禁止计数;
WR#写 [重写 ]会立即 重新 计数(软件触发);
OUT在写入控制字及计数当中为高电平,计数值为 0
时输出 1个 CLK的负脉冲。
5.方式 4—软件触发选通
http://qsyang.yeah.net
现代微机原理与接口技术
22
6.方式 5—硬件触发选通特点,一次计数;
GATE上升 重新,高与下降和低不影响计数;
WR#写 [重写 ]在下次 GATE从 0到 1的跳变时有效;
OUT在计数值为 0时输出 1个 CLK的负脉冲。
http://qsyang.yeah.net
现代微机原理与接口技术
23
方式 0 方式 1 方式 2 方式 3 方式 4 方式 5
OUT输出状态 写入控制字后变 0,
计数结束变 1,并维持至重写控制字或计数初值写入控制字后变 1,
GATE上升沿触发变 0,
开始计数,
计数结束变
1
写入控制字后变 1,计数到 1变 0,
维 持 一 个
Tclk变 1
写入控制字后变 1,装入初值且
GATE=1 则
OUT变 1,计数到变 0,重装初值继续计数,计数到则反向写入控制字后变 1,计数 结束 变 0,
维持一个
Tclk变 1
写入控制字后变 1,
GATE上升沿触发开始计数,计数结束输出一个 CLK 的负脉冲初值自动重装 无 无 计数到 0 重装根据初值奇偶分别重装;
无 无计数过程中改变初值立即有效 GATE触发后有效计数到 1 或
GATE触发后有效计数结束或
GATE触发后有效立即有效 GATE触发后有效
GA
TE
0 禁止计数 无影响 禁止计数 禁止计数 禁止计数 无影响下降沿 暂停计数 无影响 停止计数 停止计数 停止计数 无影响上升沿 继续计数 从初值开始重新计数从初值开始重新计数从初值开始重新计数从初值开始重新计数从初值开始重新计数
1 允许计数 无影响 允许计数 允许计数 允许计数 无影响
http://qsyang.yeah.net
现代微机原理与接口技术
24
6.2.5 8254-2应用举例
1.分频器设计用 8254(地址 40H~43H)将 5MHz的脉冲变为 1Hz的脉冲。
初值 =fCLK/fOUT=5× 106> 65536,怎么办?
CLK0
GATE0
OUT0
CLK1
GATE1
OUT1
CLK2
GATE2
OUT2
D0~D7
A1
A0
RD
WR
CS
5MHz
1Hz
MOV AL,00110111B; T/C0
OUT 43H,AL
MOV AX,5000H
OUT 40H,AL
MOV AL,AH
OUT 40H,AL
MOV AL,01110101B; T/C1
MOV AX,1000H
OUT 41H,AL
MOV AL,AH
OUT 41H,AL
需要 2个 T/C级联,T/C0采用方式 3产生连续分频方波,
做 T/C1的 CLK,T/C1 采用方式 2产生 1Hz脉冲。两个
T/C的 GATE统一控制。
http://qsyang.yeah.net
现代微机原理与接口技术
25
2.占空比 4:5的方波发生器
8254的 CLK0的时钟频率是 8KHz,问
1) T/C0最大定时时间是多少?
2)要求 8254端口地址为 90H,92H,94H和 96H,请使用 74LS138译码器加简单门电路完成地址连线。
3)现在要求使用该 8254产生周期为 9秒,占空比为 4:9
的方波,请在上面的电路图中完成电路,并编写初始化程序。
答:
1) TCLK0=1/fCLK0=1/8000=0.125ms
最大定时时间= 65536× 0.25ms=8.192秒
http://qsyang.yeah.net
现代微机原理与接口技术
26
2)
D7~D0
IOW
IOR
Y2
A1
A2
A7
A5A4
A3
≥1
≥1
A8
A9
A6
A0
CLK1
GATE1
D7~D0
WR
RD
A0
A1
8254
CS
CB
A
74LS138
G1
G2A
G2B
CLK0
GATE0
OUT0
CLK0
GATE0
OUT0
OUT1
8KHz
1Hz 5V
占空比
4:9,周期 9秒的方波
3)
http://qsyang.yeah.net
现代微机原理与接口技术
27
MOV AL,00110111B; T/C0
OUT 96H,AL
MOV AX,8000H
OUT 90H,AL
MOV AL,AH
OUT 90H,AL
MOV AL,01110111B; T/C1
MOV AX,9H
OUT 92H,AL
MOV AL,AH
OUT 92H,AL
http://qsyang.yeah.net
现代微机原理与接口技术
28
3.包装流水线控制某产品的包装流水线中,一个包装箱能装 24罐饮料。装箱时希望流水线上每通过 24罐饮料,
流水线要停 4秒以等待包装箱封口,然后继续通过下一箱的 24罐。流水线就是这样周而复始的运作。试利用一片 8254来完成流水线控制中的定时和计数功能。假设 8254的端口地址为
8CH~8FH,采用的时钟频率是 2KHz。
http://qsyang.yeah.net
现代微机原理与接口技术
29
思路,用 8254的计数通道 1作为计数器,用于 24个罐的计数;计数通道 2作为定时器,定时为 4S。当计数通道
1的 OUT脚出现 0到 1的跳变的时候,将启动计数通道 2
开始定时,而计数通道 2定时阶段将控制计数通道 1停止计数,只有其定时结束并停止定时阶段才可再次启动计数通道 1开始计数。 计数通道 1工作在方式
2,计数初值 24
计数通道 2工作在方式
1,计数初值 8000
CLK0
GATE0
OUT0
CLK1
GATE1
OUT1
CLK2
GATE2
OUT
2
D0~D7
A1
A0
RD
WR
CS
流水线信号
fCLK
控制流水线停和运行的信号
http://qsyang.yeah.net
现代微机原理与接口技术
30;初始化程序;计数通道 1初始化
MOV AL,01010100B
OUT 8FH,AL
MOV AL,24
OUT 8DH,AL;初始化计数通道 2
MOV AL,10110010B
OUT 8F,AL
MOV AX,8000
OUT 8EH,AL
MOV AL,AH
OUT 8EH,AL
http://qsyang.yeah.net
现代微机原理与接口技术
31
6.3 8254在微机中应用
PC系列机定时系统结构框图来自主板上 74LS138的 Y2
,地址范围是 40H~5FH,
加上 A1A0两根地址线,组成 8254的端口地址是 40H
,41H,42H,43H。
返回 1 返回 2
http://qsyang.yeah.net
现代微机原理与接口技术
32
6.3.1 计数器 0—系统定时器工作方式,3方式,计数初值,65536。
1.系统定时器连接到 8259A的 IRQ0(中断类型号为 8)上。
fOUT0=1.1931816MHz/65536=18.2Hz,
即:每秒产生 18.2次中断用于日时钟计时。
应用,系统 BIOS的 INT 8H用作日时钟计时;
INT 8H调用 INT 1CH作为用户定时中断接口。
2.软盘驱动器马达自动延迟控制
http://qsyang.yeah.net
现代微机原理与接口技术
33
6.3.2 计数器 1—动态存储器定时刷新控制工作方式,2方式,计数初值,18。
连接到 8237的 DREQ0上,定时产生负脉冲。
脉冲宽度 =1/ 1.1931816MHz=838ns,
脉冲周期 =18/1.1931816MHz=15.08μs,
即:每隔 15.08μs产生一个脉冲用于刷新。
http://qsyang.yeah.net
现代微机原理与接口技术
34
6.3.3 计数器 2—扬声器音频发生器工作方式,3方式,计数初值,由调用程序控制。
与 8255的 PB口 D1信号“与”后连接到扬声器上,控制扬声器发声频率及时长。
8255控制发声,8254的 OUT2=1,CPU控制 8255的 PB
口的 D1位的电平实现;
8254控制发声,8255的 PB口的 D1位为高电平,控制
8254的 T/C2的 OUT2实现。
通过改变 OUT2的方波信号频率,就可以改变扬声器发声的音调。
CR预置值= CLK2脉冲频率 /发声的频率转图
http://qsyang.yeah.net
现代微机原理与接口技术
35;功能:按照指定的时间间隔发 896Hz声音;调用,CX=指定时间;返回:无
BEEP PROC FAR
IN AL,61H
MOV AH,AL
PUSH AX
MOV AL,10110110B
OUT 43H,AL
MOV AX,0533H; =1.1931816MHz/896Hz
OUT 42H,AL
MOV AL,AH
OUT 42H,AL
POP AX
http://qsyang.yeah.net
现代微机原理与接口技术
36
OR AL,03H ;置 61H端口 D0,D1均为 1,;打开扬声器
OUT 61H,AL
NOP
L1,LOOP L1 ;延迟
AND AL,FD ;置 61H端口 D1为 0,;封锁 OUT2输出
OUT 61H,AL
MOV AL,AH
OUT 61H,AL
RET
BEEP ENDP 转图
http://qsyang.yeah.net
现代微机原理与接口技术
37
6.4 实时钟电路及其应用
6.4.1 MC146818特性及工作原理
MC146818外部引脚图
http://qsyang.yeah.net
现代微机原理与接口技术
38
MC146818在系统中连接框图
http://qsyang.yeah.net
现代微机原理与接口技术
39
实时钟工作原理示意图
http://qsyang.yeah.net
现代微机原理与接口技术
40
偏移地址 信息内容 偏移地址 信息内容
0 秒 7 日
1 报警秒 8 月
2 分 9 年
3 报警分 0A 状态寄存器 A
4 时 0B 状态寄存器 B
5 报警时 0C 状态寄存器 C
6 星期几 0D 状态寄存器 D
32H 日 期 世 纪
COMS RAM实时钟信息存放位置表可以用 INT 1A功能读取或设置这些值。
http://qsyang.yeah.net
现代微机原理与接口技术
41
6.4.2 实时钟状态寄存器
6.4.3 RT/CMOS RAM操作
815EP芯片组 82801BA的 RTC电路包含 128字节标准
CMOS RAM 区和 128字节扩展 CMOS RAM区。
访问 RT/CMOS RAM的端口地址范围从 70H~77H。
其中,70H和 71H用来访问标准 CMOS RAM 区,
72H,73H用来访问扩展 CMOS RAM 区。
1,状态寄存器 A
2,状态寄存器 B
3,状态寄存器 C
4,状态寄存器 D
http://qsyang.yeah.net
现代微机原理与接口技术
42
MOV AL,6H ; 6H是存放 "星期几 "的单元偏移地址
OUT 70H,AL ;送地址端口
JMP $+2 ;芯片 I/O延时要求
IN AL,71H ;读数据端口
MOV AH,AL ; AH中存放的是当前,星期几,的信息; 0表示星期日
http://qsyang.yeah.net
现代微机原理与接口技术
43
6.4.4 CMOS 密码的破解基本原理是破坏 CMOS中的设置,使得开机后必须重新设置 CMOS,从而破解密码。
mov AL,2EH
out 70H,AL
mov AL,00H
out 71H,AL
mov AL,2FH
out 70H,AL
mov AL,00H
out 71H,AL
CMOS中偏移为 2EH和 2FH的位置放的是标准校验和
http://qsyang.yeah.net
现代微机原理与接口技术
44
6.5 Win32编程中的时钟(自学)
6.5.1 使用基于 WM_TIMER消息的定时器
1.使用 Win32 SDK函数
必须使用# include,Windows.h”
必须使用 User32.lib
http://qsyang.yeah.net
现代微机原理与接口技术
45
http://qsyang.yeah.net
现代微机原理与接口技术
46
UINT_PTR SetTimer( HWND hWnd,// handle to window
UINT_PTR nIDEvent,// timer identifier
UINT uElapse,// time-out value
TIMERPROC lpTimerFunc // timer procedure
);
BOOL KillTimer( HWND hWnd,// handle to window
UINT_PTR uIDEvent // timer identifier );
http://qsyang.yeah.net
现代微机原理与接口技术
47
LONG APIENTRY MainWndProc( HWND hwnd,// handle to main
window
UINT message,// type of message
WPARAM wParam,// additional information
LPARAM lParam) // additional information
{
……
switch (message) {
……
case WM_TIMER,// Process the timer event.
case WM_DESTROY,// Destroy the timer.
KillTimer(hwnd,IDT_MOUSETRAP);
PostQuitMessage(0);
break;
……
}
http://qsyang.yeah.net
现代微机原理与接口技术
48
2.使用 MFC类 CWnd的成员函数
UINT SetTimer( UINT nIDEvent,// Specifies a nonzero timer
// identifier.
UINT nElapse,// Specifies the time-out value,
// in milliseconds.
void (CALLBACK EXPORT* lpfnTimer)(HWND,
UINT,UINT,DWORD) // Specifies the address of the
// application-supplied TimerProc callback function that processes
// the WM_TIMER messages,If this parameter is NULL,the
// WM_TIMER messages are placed in the application’s message
// queue and handled by the CWnd object.
);
BOOL KillTimer( int nIDEvent );
http://qsyang.yeah.net
现代微机原理与接口技术
49
void CMainFrame::OnStartTimer()
{
m_nTimer = SetTimer(1,2000,0);
}
void CMainFrame::OnStopTimer()
{
KillTimer(m_nTimer);
}
void CMainFrame::OnTimer(UINT nIDEvent)
{
MessageBeep(0xFFFFFFFF); // Beep
// Call base class handler,
CMDIFrameWnd::OnTimer(nIDEvent);
}
http://qsyang.yeah.net
现代微机原理与接口技术
50
缺点:
WM_TIMER消息的优先级比较低,定时时间不能精确保证。
定时精度低,最小精度为 54.915ms,约 18.2次 /秒。
http://qsyang.yeah.net
现代微机原理与接口技术
51
6.5.2 使用多媒体定时器
1.使用 Win32 SDK函数
必须使用 #include "Mmsystem.h"
必须使用 Winmm.lib
http://qsyang.yeah.net
现代微机原理与接口技术
52
http://qsyang.yeah.net
现代微机原理与接口技术
53
1,确定最大和最小周期
MMRESULT timeGetDevCaps(
LPTIMECAPS ptc,// Pointer to a TIMECAPS structure.
UINT cbtc //Size,in bytes,of the TIMECAPS
structure
);
typedef struct {
UINT wPeriodMin; //Minimum supported resolution
UINT wPeriodMax; //Maximum supported resolution
} TIMECAPS;
http://qsyang.yeah.net
现代微机原理与接口技术
54
2,建立最小时间精度
MMRESULT timeBeginPeriod( UINT uPeriod //Minimum timer
resolution,in milliseconds,for the application or device driver.
);
MMRESULT timeEndPeriod( UINT uPeriod );
和上面的 timeBeginPeriod是一对,其中 uPeriod 要完全一样,
timeBeginPeriod是启动定时器的时候用,timeEndPeriod是结束定时器时用。
http://qsyang.yeah.net
现代微机原理与接口技术
55
3,启动和取消定时器
MMRESULT timeSetEvent( UINT uDelay,//Event delay,in
milliseconds.
UINT uResolution,// Resolution of the timer event,in
milliseconds,
LPTIMECALLBACK lpTimeProc,//Pointer to a callback
function that is called once upon expiration of a single event or
periodically upon expiration of periodic events.
DWORD dwUser,// User-supplied callback data
UINT fuEvent // Timer event type,TIME_ONESHOT
// TIME_PERIODIC
);
MMRESULT timeKillEvent( UINT uTimerID );
http://qsyang.yeah.net
现代微机原理与接口技术
56
获取定时器最小周期
#define TARGET_RESOLUTION 1 // 1-millisecond target
resolution
TIMECAPS tc;
UINT wTimerRes;
if (timeGetDevCaps(&tc,sizeof(TIMECAPS)) !=
TIMERR_NOERROR)
{
// Error; application can't continue.
}
wTimerRes = min(max(tc.wPeriodMin,TARGET_RESOLUTION),
tc.wPeriodMax);
timeBeginPeriod(wTimerRes);
http://qsyang.yeah.net
现代微机原理与接口技术
57
设置回调函数
UINT SetTimerCallback(NPSEQ npSeq,// sequencer data
UINT msInterval) // event interval
{ npSeq->wTimerID = timeSetEvent( msInterval,// delay
wTimerRes,// resolution(global variable)
OneShotCallback,// callback function
(DWORD)npSeq,// user data
TIME_ONESHOT ); // single timer event
if(! npSeq->wTimerID) return ERR_TIMER;
else return ERR_NOERROR;
}
http://qsyang.yeah.net
现代微机原理与接口技术
58
void CALLBACK OneShotTimer(UINT wTimerID,
UINT msg,
DWORD dwUser,
DWORD dw1,
DWORD dw2)
{
NPSEQ npSeq; // pointer to sequencer data
npSeq = (NPSEQ)dwUser;
npSeq->wTimerID = 0; // invalidate timer ID (no longer in
use)
TimerRoutine(npSeq); // handle tasks
}
回调函数
http://qsyang.yeah.net
现代微机原理与接口技术
59
void DestroyTimer(NPSEQ npSeq) {
if(npSeq->wTimerID) { // is timer event pending?
timeKillEvent(npSeq->wTimerID); // cancel the event
npSeq->wTimerID = 0; }
}
取消定时器