时钟-给设备打拍子
概述
在计算机系统中,为了使所有设备之间的通信井然有序,各通信设备间必须有统一的节奏,不能各干各的,这个节奏就被称为定时或时钟
时钟并不是计算机处理速度的衡量,而是一种使设备间相互配合而避免发生冲突的节拍。时钟只是一种时间的度量,只是一种节奏,其时间长度并不统一,各种设备都有自己的时钟,也就是有自己的工作节拍
- 比如处理器的时钟和外部设备的时钟肯定不是一个数量级
- 让处理器这种高速设备以外部设备低速时钟工作,处理器肯定会觉得很闲
- 而让低速的外部设备以处理器的时钟节拍工作,外部设备也许急得不知所措
时钟信号并不是专指处理器的时钟,也并不特指IRQ0上的时钟,表达的意思仅仅是设备自己的工作节拍、频率
时钟的分类
内部时钟
内部时钟是指处理器中内部元件,如运算器、控制器的工作时序,主要用于控制、同步内部工作过程的步调
内部时钟是由晶体振荡器产生的,简称晶振,它位于主板上,其频率经过分频之后就是主板的外频,处理器和南北桥之间的通信就基于外频
Intel处理器将此外频乘以某个倍数(也称为倍频)之后便称为主频
处理器取指令、执行指令中所消耗的时钟周期,都是基于主频的。内部时钟是由处理器固件结构决定的
外部器内部元件的工作速度是最快的,所有内部时钟的时间单位粒度比较精细,通常都是纳秒(ns)级
外部时钟
外部时钟是指处理器与外部设备或外部设备之间通信采用的一种时序,比如IO接口和处理器之间在A/D转换时的工作时序、两个串口设备之间进行数据传输时也要事先同步时钟等
外部设备的速度对于处理器来说就很慢了,所以其时钟的时间单位粒度较大,一般是毫秒(ms)级或秒(s)级
如何保证运行在不同时钟节拍下的设备能够同步通信?
应以处理器的内部时钟为依据来设计外部设备的时钟,既要符合处理器内部运行时序的规定,又要满足外部设备工作时序的要求
定时计数器就是用来解决时序配合问题的
已知处理器的内部时钟信号有晶振产生,故计时精准稳定。但晶振产生的信号频率过高,因此必须将其送到定时计数器分频,这才能产生所需要的各种定时信号
外部定时
软件实现
int cycle_cnt = 90000;
while (cycle_cnt --> 0)
让处理器执行9万次空循环,通过这种延迟方式达到一定的定时作用
但这种空兜处理器的代价是白白消耗时钟周期,处理器的资源是很宝贵的
硬件实现
这一类硬件称为定时器
计时器的功能就是定时发信号。当到达了所计数的时间,计数器可以自动发一个输出信号,可以用该信号向处理器发出中断,这样处理器可以执行相应的中断处理程序。或者用该信号直接启动某些外部设备
硬件定时器是独立的,可以同处理器并行工作,所以用硬件定时器定时的好处是节省处理器时间
可编程定时计数器
常用可编程定时计数器有 Intel 8253/8254/82C54。8253用的是倒计时的方式
如何修改计数值?
正计时
每一次时钟脉冲发生时,将当前计数值加1,直到与设定的目标终止值相等时,提示时间已到,典型的例子就是闹钟
倒计时
先设定好计数器的值,每一次时钟脉冲发生时将计数值减1,直到为0时提示时间已到,典型的例子就是电风扇的定时
8253入门
8253结构
在8253内部有3个独立的计数器,图7-45
的右侧的3个计数器,分别是计数器0~计数器2,它们的端口分别是0x40~0x42
计数器又称为通道,每个计数器都完全相同,都是16位大小
它们是独立的,也就是这三个计数器的工作是不依赖的,可以同时工作,各干各的。原因是各个计数器都有自己的一套寄存器资源,工作时自己用自己的,互不干涉
寄存器资源包括一个16位的计数初值寄存器、一个计数器执行部件和一个输出锁存器。其中,计数器执行部件是计数器中真正进行计数工作的元器件,其本质是个减法计数器
计数器的三个引角: CLK、GATE、OUT
CLK
CLK 表示时钟输入信号,即计数器自己工作的节拍,也就是计数器自己的时钟频率
每当此引脚收到一个时钟信号,减法计数器就将计数值减1
连接到此引脚的脉冲频率最高位10MHz, 8253为2MHz
GATE
GATE表示门控输入信号,在某些工作方式下用于控制计数器是否可以开始计数,在不同工作方式下GATE的作用不同,到时候同工作方式一同介绍
OUT
OUT表示计数器输出信号。当定时工作结束,也就是计数值为0时,根据计数器的工作方式,会在OUT引脚上输出相应的信号
此信号用来通知处理器或某个设备:定时完成
这样处理器或外部设备便可以执行相应的行为动作
计数流程
计数开始之前的计数初值保存在计数初值寄存器中,计数器执行部件(减去计数器)将此初值载入后,计数器的CLK引脚每收到一个脉冲信号,计数器执行部件(减法计数器)便将计数值减1,同时将当前计数值保存在输出锁存器
当计数值减到0时,表示定时工作结束,此时将通过OUT引脚发出信号,此信号可以用来向处理器发出中断请求,也可以直接启动某个设备工作
计数器内部各个结构的功能
计数初值寄存器、计数器执行部件和输出锁存器都是16位宽度的寄存器,所有高8位和低8位都可以单独访问
计数初值寄存器
计数初值寄存器用来保存计数器的初始值,它是16位宽度,对8253初始化时写入的计数初始值就保存在计数计数初值寄存器
它的作用是为计数器执行部件准备初始计数值,之后的计数过程与它无关。当计数器选择了某种重复计数的工作方式后,比如工作方式2和工作方式3,还需要将此计数初值重新装载到计数器执行部件中
计数器执行部件是计数器中真正"计数"的部件,计数的工作是由计数器执行部件完成的,所以它才是真正实际的计数器
减法计数器
8283是个倒计时计数器,原因是计数器执行部件是个16位的减法计数器,它从初值寄存器中拿到起始值,载入到自己的寄存器后便开始递减计数(注意:计数过程中不断变化的值称为当前计数值,它保存在执行部件自己的寄存器中,初值寄存器中的值不受影响)
输出锁存器
输出锁存器也称为当前计数值锁存器,用于把当前减去计数器中的计数值保存下来,其目的就是为了让外界可以随时获取当前计数器
计数器中的计数值是不断变化的,处理器无法直接从计数器中获取当前计数值
原因是这样的
- 计数器的使命就是通过计数的方式实现定时功能,必须要求精准,所有绝不能为了获取计数值而停止计数
为了获取任意时刻的计数值,8253只有将它送到输出寄存器,此锁存器起到暂存寄存器的作用。这样处理器便能从输出锁存器中获取瞬时计数值
8253 计数器
计数器0的作用是产生时钟信号,这个时钟是指连接到主片IRQ0引脚上的那个时钟,也就是计数器0决定时钟中断信号的发生频率