Intel 8254计数器.docx
《Intel 8254计数器.docx》由会员分享,可在线阅读,更多相关《Intel 8254计数器.docx(19页珍藏版)》请在冰豆网上搜索。
Intel8254计数器
PCL-836卡上含有4个Intel8254可编程计数/定时器,
每片Intel8254提供3个独立的16位计数器,高达10MHz的输入频率,
8254逻辑框图
D7~D0:
双向三态数据总线,与系统数据总线连接;
CLK0~CLK2:
计数器0~2的时钟输入
OUT0~OUT2:
计数器0~2的时钟输出
GATE0~GATE2:
计数器0~2的的门控输入;高电平有效
:
写控制信号;低电平有效
:
读控制信号;低电平有效
:
片选信号;低电平有效
A1,A0:
0~2计数器或控制字寄存器选择信号;
A1
A0
选择
0
0
计数器0
0
1
计数器1
1
0
计数器2
1
1
控制字寄存器
计数器内部逻辑框图
(0~2)计数器包括:
8位控制字寄存器、状态寄存器、状态锁存器、控制逻辑器、16位计数初值寄存器(CounterRegister,CR)、16位可预设初值减1计数器(CounterElement,CE)和16位输出锁存器(OutputLatch,OL)。
3个计数器是完全独立的,可以工作在不同的模式。
计数器(0~2)作定时器用:
其CLK端上的输入脉冲应是标准的、精确的;作计数器用:
对其CLK端上的脉冲计数,脉冲宽度可以不等。
采用减一计数器,为0时,从OUT端上输出一个脉冲。
定时时间=时钟脉冲周期×预置的计数初值
CLK
计数脉冲或标准脉冲输入端
OUT
计数值为0时输出一个脉冲
GATE
允许端,当GATE=1时允许计数
对8254的编程通常只需注意两点:
先写控制字,再写计数初值;计数初值必须遵循控制字中设定的格式(只有低字节或只有高字节或者先低后高,由RW1,RW0规定)。
只有当CPU向8254控制字寄存器写入控制字后,即对其初始化之后,8254才能正常地工作。
写入控制字后,所有控制逻辑电路将立即复位,输出端OUT立即进入初始状态。
接着向计数器的计数初值寄存器中写计数初值,在写入初值后,需要经过一个时钟脉冲后,计数器才开始在脉冲下降沿进行减1计数。
通常在时钟脉冲的上升沿时,门控信号GATE被采样。
当A1,A0=11时,控制字寄存器被选择,控制字寄存器中的SC1,SC0则决定着(0~2)计数器中哪个会被选中以写计数初值。
计数初值可以在任何时刻载入,而不影响计数器的编程模式。
如果要载入两个字节的计数值,则在其间不允许发送控制字命令,否则会载入错误的计数值。
但如LSBofCount0->ControlWord2->LSBofCount1则是允许的。
控制字寄存器的格式为:
A1,A0=11,
,
,
D7
D6
D5
D4
D3
D2
D1
D0
SC1
SC0
RW1
RW0
M2
M1
M0
BCD
SC1SC0
工作计数器选择
00
计数器0
01
计数器1
10
计数器2
11
回读命令
RW1RW0
读/写
00
计数器锁存计数值
01
读/写计数器的低字节(LSB)
10
读/写计数器的高字节(MSB)
11
先读/写计数器的低字节,然后再读/写计数器的高字节
M2M1M0
工作模式
000
模式0:
计数结束产生中断
001
模式1:
硬件可重触发单稳态
×10
模式2:
比率发生器(分频器)
×11
模式3:
方波发生器
100
模式4:
软件触发选通
101
模式5:
硬件触发选通
BCD
存储模式
0
16位二进制
1
二进制编码的十进制
CLKpulse(时钟脉冲):
一个上升沿,一个下降沿称为计数器时钟输入
Trigger(触发):
计数器门控输入的上升沿
Counterloading(计数器加载):
计数值CR->CE
工作模式:
Mode0:
INTERRUPTONTERMINALCOUNT计数结束产生中断
当通道处于“Terminalcount”状态时产生中断信号。
经常用来对事件进行计数。
控制字写入后,OUT最初是低电平,然后保持低电平直到计数减到0,此时OUT输出为高电平并保持直到新的计数值或者新的模式0控制字写入计数器中。
GATE=1可以计数;GATE=0不能计数;GATE不影响OUT。
控制字和初始计数值写入计数器后,初始计数值在下一个CLK脉冲被载入,CLK脉冲不增加计数,因此如果初始计数值为N,则在计数初值写入的N+1个CLK脉冲后OUT才变成高电平。
如果新的计数初值写入计数器,它将会在下一个CLK脉冲载入,然后以新的计数值开始计数。
如果高低双字节写入,写第一个字节(低字节)的时候,停止计数,OUT为低电平;写第二个字节(高字节)时,新的计数值在下个CLK脉冲被载入。
如果当GATE=0时,计数初值被写入,在下一个CLK脉冲被载入,后当GATE=1,经过N个脉冲后OUT为高电平。
4
4
Ø写入控制字后,OUT初始为低电平;
ØGATE为高时,写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数,此时OUT为低;期间新的计数值写入将导致在下一个时钟脉冲的下降沿开始新的计数值的计数;GATE为低时,写入计数值N后,在下一个时钟脉冲的下降沿被载入,GATE为高时,计数器才开始计数。
Ø当计数值为0时,OUT立即变为高,该上升沿可用来触发中断;
Ø在计数期间,GATE变为低,将暂停计数,并保留当前计数值(比如N-x),当GATE变为高时,继续减1计数(比如从N-x-1开始);
Ø不能自动循环载入计数值计数;(自己加)
Ø计数值N一次写入,仅一次有效。
Mode1:
Hardwareretriggerableone-shot硬件可重触发单稳态方式
开始时OUT为高电平,GATE上升沿触发的CLK脉冲,OUT变为低电平,并保持低电平直到计数为0,此时OUT变为高电平并保持高电平,直到下一个GATE上升沿触发时的CLK脉冲,计数值将重新载入,并重新计数。
写入控制字和计数初值后,GATE的上升沿触发引起在下一个CLK脉冲时计数初值载入和OUT变为低电平,形成一个单稳态脉冲。
计数初值N产生由N个CLK脉冲周期长度的单稳态脉冲。
在任何GATE的上升沿触发后,OUT保持低电平达N个CLK脉冲。
单稳态脉冲是可重复的,不用重写同样的计数初值,只要重触发即可重计数。
GATE不影响OUT。
如果计数器没有被重触发,新计数值的写入不影响当前的单稳态。
2
(上图有问题,需GATE的上升沿触发才使计数器在下一个时钟脉冲的下降沿开始减1计数)
Ø写入控制字后,OUT初始为高电平;
Ø写入计数值N后,需GATE的上升沿触发后才使计数器在下一个时钟脉冲的下降沿载入并开始减1计数,一旦开始计数,OUT为低;
Ø当计数值为0时,OUT变为高,即计数期间,OUT为低,脉宽为N;
Ø在计数期间,GATE的下降沿不影响计数,但GATE的上升沿,将使计数器在下一个时钟脉冲的下降沿重载计数值N,并重新开始计数,这将加宽单稳输出的脉宽。
Ø计数值N一次写入,仅一次有效。
Mode2:
RateGenerator比率发生器
这种模式像N除计数器,
这种模式典型地被用来产生实时时钟中断。
此时OUT初始时被设置为高电平,并以此持续到计数器的值减到1,然后在接下来的一个CLK脉冲期间,OUT管脚将变为低电平,直到计数器的值减到0,OUT管脚又变成高电平,并且计数器的初值被自动地重新加载后,然后重复上述过程。
模式2是周期性的,同样的序列可无限循环。
计数初值为N时,序列可以没N个CLK周期重复。
GATE=1可以计数;GATE=0不能计数。
如果在输出脉冲期间GATE变为低电平,OUT立即变为高电平。
GATE的上升沿触发将使计数初值在下一个CLK脉冲后重载。
计数值被写入后经N个CLK脉冲后,OUT为低电平。
因此GATE输入可以用来与计数器同步,同样也可以用软件来同步。
计数过程中新计数值的写入不影响当前的计数序列。
除非写入新计数值后当前周期结束前计数器被触发,在下一个CLK脉冲后计数器被载入新的计数值,然后开始新的计数。
否则新的计数值会在当前计数周期结束后载入。
模式2中,1计数是非法的。
(此图有问题:
写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数)
Ø写入控制字后,OUT初始为高电平;
ØGATE为高时,写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数,此时OUT为高;
Ø当计数值为1时,OUT变为低,当计数值为0时,OUT变为高,利用计数1—>0这个脉冲时间重载初值,立即重新计数,周而复始(计数为0时即为下一次计数N的开始,不用在等下一个时钟脉冲);
Ø在计数期间,即计数值为0前,如写入新的计数值M,将在本计数周期结束后(即计数为0后)有效,计数器以M计数,即改变输出频率;
Ø在计数期间,GATE变为低,将暂停计数,并保留当前计数值,当GATE变为高时,在下一个时钟脉冲下降沿重载初值并重新计数;
Ø计数值N一次写入,连续有效。
Mode3:
SQUAREWAVEMODE方波信号发生器
模式3典型的用来作波特率发生器。
与模式2很相似,除了OUT的占空比。
OUT初始时是高电平。
当达到初始计数值的一半,余下的计数OUT输出低电平。
模式3是周期性的,序列是无限循环的。
N的初始计数值产生N个CLK周期的宽度的方波。
GATE=1可以计数;GATE=0不能计数。
如果在OUT低电平期间GATE变为低电平,OUT立即变为高电平,不需要等下一个CLK脉冲。
GATE的上升沿触发将使计数初值在下一个CLK脉冲后重载,GATE可以用来与计数器同步。
同样也可以用软件来同步。
计数过程中新计数值的写入不影响当前的计数序列。
除非写入新计数值后当前方波半个周期结束前计数器被触发,在下一个CLK脉冲后计数器被载入新的计数值,然后开始新的计数。
否则新的计数值会在当前半个周期计数结束后载入。
需要补充的是:
偶数计数:
OUT初始为高电平。
初始计数值在CLK脉冲时刻载入,然后在接下来的CLK脉冲中减2计数,计数值为0后,OUT变为低电平,计数器重载计数初值。
不断重复上述过程。
奇数计数:
OUT初始为高电平。
初始计数值减1后在一个CLK脉冲中载入,然后在接下来的CLK脉冲中减2计数,计数值为0后,经过一个CLK脉冲后OUT变为低电平(则高电平的宽度为(N-1)/2+1),计数器重载减1后的计数初值,然后在接下来的CLK脉冲中减2计数,计数值为0后,OUT重新变为高电平,计数器重载减1后的计数初值。
不断重复上述过程。
因此对于奇数计数,OUT高电平的宽度为(N+1)/2,低电平的宽度为(N-1)/2。
(此图有问题:
写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数)
Ø写入控制字后,OUT初始为高电平;
ØGATE为高时,写入偶计数值N后,在下一个时钟脉冲的下降沿计数,此时OUT为高,然后开始减2计数,计数值为0时,OUT变为低,且重置初值后继续减2计数,计数值为0时,OUT变为高,周而复始。
ØGATE为高时,写入奇计数值M后,先减1然后在下一个时钟脉冲的下降沿载入,并开始计数,此时OUT为高,然后开始减2计数,计数值为0时,经过一个时钟脉冲后OUT变为低,并且重载减1后的计数初值进行减2计数,计数值为0时,OUT变为高,周而复始。
Ø写入偶计数值,OUT上可得对称的方波;写入奇计数值,可得相似对称的方波;
Ø在计数期间,GATE变为低,将暂停计数,并保留当前计数值,当GATE变为高时,在下一个时钟脉冲下降沿重载初值并重新计数;
Ø计数值N一次写入,连续有效。
Mode4:
Softwaretriggeredstrobe软件触发选通
OUT初始为高电平。
当计数到0时,OUT经过一个CLK脉冲的低电平,然后再变为高电平。
计数序列通过写计数初值来触发。
GATE=1可以计数;GATE=0不能计数。
GATE不影响OUT。
写入控制字和计数初值后,计数值在下一个CLK脉冲被载入,这个CLK脉冲并不减少计数值,所以对于计数初值为N,OUT在计数初值被写入后的N+1个CLK脉冲后被选通为低电平。
如果计数过程中新的计数值被写入,则在下一个CLK脉冲计数值被载入,接着以新计数值计数。
如果写入的是双字节的计数值,则写第一个字节(低字节)时不影响计数,写第二个字节(高字节)时,允许在下一个CLK脉冲时刻将计数值载入。
允许序列通过软件重触发。
在计数值N被写入后,经过N+1个CLK脉冲宽度,OUT选通为低电平。
(此图有问题:
写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数)
Ø写入控制字后,OUT初始为高电平;
ØGATE为高时,写入计数值N后,在下一个时钟脉冲的下降沿开始减1计数,此时OUT为高。
即由软件触发选通。
(方式0中OUT为低);如果GATE为低时写入计数值N,在过了一个时钟脉冲后,当GATE为高时,立即开始计数。
Ø当计数值为0时,OUT变为低,保持一个时钟脉冲宽度后,OUT变为高,该脉冲(下降沿)可用作触发脉冲。
(方式0中是一上升沿)
Ø在计数期间,GATE变为低,将中止计数,当GATE变为高时,重置初值,并计数。
Ø计数值N一次写入,仅一次有效。
Mode5:
Hardwaretriggeredstrobe硬件触发选通
OUT初始为高电平。
计数器通过GATE的上升沿触发。
当计数到0时,OUT经过一个CLK脉冲的低电平,然后再变为高电平。
写入控制字和计数初值后,直到GATE的上升沿触发后的CLK脉冲中,计数器才载入计数值。
这个CLK脉冲并不减少计数值,所以对于计数初值为N,OUT在被GATE上升沿触发后的N+1个CLK脉冲后被选通为低电平。
GATE上升沿触发导致计数器在下一个CLK脉冲载入计数初值。
计数序列是可以重触发的。
触发后OUT选通N+1个CLK脉冲宽度的低电平。
GATE不影响OUT。
计数过程中写入新的计数值不影响当前的计数序列。
除非在写入新计数值后及当前计数结束前计数器被触发,则在下一个CLK脉冲后计数器载入新的计数值,然后接着开始新的计数。
(此图有问题:
写入计数值N后,在GATE的上升沿到后的下一个时钟脉冲的下降沿开始减1计数)
Ø写入控制字后,OUT初始为高电平;
Ø写入计数值N后,并不触发选通,需GATE的上升沿到后的下一个时钟脉冲的下降沿开始减1计数,此时OUT为高。
Ø计数值为0时,OUT变为低,保持一个时钟脉冲宽度后,OUT变为高,且重置初值,等下一个GATE的上升沿到后的下一个时钟脉冲的下降沿才触发减1计数。
即硬件触发选通。
Ø在计数期间,GATE的上升沿将重置初值并在触发后的下一个时钟脉冲的下降沿开始减1计数。
Ø计数值N一次写入,连续有效。
说明(适用于所有工作方式):
(1)当控制字写入计数器后,所有控制逻辑电路立即处于复位状态,计数器输出端OUT进入规定的初始状态(高电平或低电平)。
(2)计数初值写入计数初值寄存器后,要经过一个时钟周期,计数器才开始计数。
(3)在时钟脉冲的上升沿对门控信号GATE进行采样。
(4)计数器真正开始计数是在时钟脉冲的下降沿。
关于计数初值,需要说明以下几点:
(1)使用任一计数通道,首先要向该通道写入方式控制字,以确定该通道的工作方式,写入的控制字存入通道对应的控制寄存器中。
当控制字D0=0时,即二进制计数,初值可在0000H~FFFFH之间选择,初值为0表示最大值65536(216);当控制字D0=1时,装入初值应为BCD码格式,其值可在0000~9999之间选择,初值为0表示最大值10000(104),在写入指令中还必须写成十六进制数,例如计数初值为79,采用BCD计数,则指令中的79必须写成79H。
(2)控制字D5D4位决定控制字的位数(8位或16位),若为“01”,则只需写入计数值的低8位,高8位自动置0;若为“10”,则只需写入计数值的高8位,低8位自动置0;若为“11”,则计数值为16位,分两次写入,必须先写低8位,后写高8位。
(3)计数初值要写入各计数器对应的端口地址,计数器0对应A1A0=00的端口地址,计数器1对应A1A0=01的端口地址,计数器2对应A1A0=10的端口地址。
GATE信号功能总结
GATE输入总是在CLK的上升沿被采样。
模式0,2,3和4中,GATE输入是电平敏感的,逻辑电平在CLK的上升沿被采样。
在模式1,2,3和5中,GATE输入是上升沿敏感的。
这些模式中,GATE的上升沿在计数器中设置了边沿敏感的触发器。
触发器在CLK的下一个上升沿被采样。
采样后触发器立即被重设。
这样不管GATE的上升沿什么时候出现,都能被检测,也就是说高电平不必保持到CLK的下个上升沿。
需要注意的是,在模式2和3中CLK源不是系统时钟的话,GATE应该在写新的计数值的时候立即被脉冲化。
最小和最大的计数初值
新的计数值被载入,计数器在CLK的下降沿减1。
最大的初始计数值为0:
等于二进制计数值
或者BCD计数值
计数器直到计数到0时才停止。
在模式0,1,4和5中,计数器围绕最高计数值(0XFFFF二进制计数或者9999BCD计数)连续计数。
模式2和3是周期性的,计数器自动重载计数初值和继续计数。
锁存计数器(LatchCounter)
当控制寄存器中的RW1,RW0设置成0时,将把当前通道的计数器值锁存。
此时通过I/O端口可以读到一个稳定的计数器值,因为计数器表面上已经停止向下计数。
需要注意的是一旦发出了锁存命令,就要马上读计数器的值。
时间戳记数器TSC
从Pentium开始,所有的Intel80x86CPU就都又包含一个64位的时间戳记数器(TSC)的寄存器。
该寄存器实际上是一个不断增加的计数器,它在CPU的每个时钟信号到来时加1(也即每一个clock-cycle输入CPU时,该计数器的值就加1)。
汇编指令rdtsc可以用于读取TSC的值。
利用CPU的TSC,操作系统通常可以得到更为精准的时间度量。
假如clock-cycle的频率是400MHZ,那么TSC就将每2.5纳秒增加一次。
在不影响计数过程中读取计数值,有三种方法:
1.简单的读操作
通过A1,A0选择计数器进行读操作,但此时CLK的时钟应该被GATE或外部逻辑禁止。
2.计数器锁存命令
A1,A0=11,
,
,
D7
D6
D5
D4
D3
D2
D1
D0
SC1
SC0
0
0
×
×
×
×
D5,D4——00表示计数锁存命令
×——表示任意值,推荐值为0,保证以后与Intel产品的兼容性
命令一到达,所选计数器的输出锁存器就锁存计数值,保持到CPU读取或者计数器被编程,然后计数值自动释放,输出锁存器跟随减1计数器。
此命令不会影响计数器的工作模式。
在计数值未被读取之前,连续发出多次计数器锁存命令,只有第一次发出的命令是有效的。
两字节的读取不一定是连续的,中间可能有其他行为。
对同一个计数器的读写操作也可以是交叉的,如读低->写新低->读高->写新高。
同样需要注意的是编程的时候两个字节的读写之间不能有控制命令。
3.读回命令(Read-BackCommand)
此命令允许用户检查所选计数器的计数值,编程模式,输出引脚的电流状态和无效计数标志。
此命令写进控制字寄存器中,Read-BackCommand的格式为
A1,A0=11,
,
,
D7
D6
D5
D4
D3
D2
D1
D0
1
1
CNT2
CNT1
CNT0
0
D5:
0=锁存所选计数器的计数值
D4:
0=锁存所选计数器的状态
D3:
1=选择计数器2
D2:
1=选择计数器1
D1:
1=选择计数器0
D0:
保留位。
最好是0
此命令在读多个计数器的计数值时非常有用。
计数器的状态格式为:
D7
D6
D5
D4
D3
D2
D1
D0
Output
Null
Count
RW1
RW0
M2
M1
M0
BCD
D7:
1=输出引脚(OUTPin)是1
0=输出引脚(OUTPin)是0
D6:
1=无效计数值
0=计数值可读
D5~D0:
计数器工作模式(最后写进的控制字)
NullCount位D6表明写进计数初值寄存器(CR)中的计数值被载入计数单元(CE)中。
确切的时间取决于计数器的工作模式及模式中的定义,但直到计数值被载入计数单元(CE)中,它才能获知,之前的读及锁存的操作是不能反映最新载入的计数值。
WritetothecontrolwordregisterNullCount=1
Writetothecountregister(CR)NullCount=1
NewCountisLoadedintoCENullCount=0
1.只有控制字选定的计数器会使其NullCount=1,其他的没有影响
2.如果计数器被编程为双字节计数(先低后高),第二个字节(MSB)被读取以后NullCount=1。
A1,A0=11,
,
,
D7
D6
D5
D4
D3
D2
D1
D0
1
1
CNT2
CNT1
CNT0
0
D5:
0=锁存所选计数器的计数值
D4:
0=锁存所选计数器的状态
D3:
1=选择计数器2
D2:
1=选择计数器1
D1:
1=选择计数器0
D0:
保留位。
最好是0