文章目录
1、定时器
1.1 定时器简介
定时器,又称为计数器,是51单片机的内部资源,即电路的连接和运转都在单片机内部完成。
定时器通常有两个作用:
- 用于系统计时
- 用于替代长时间Delay,使得程序每隔一段固定的时间进行相应操作
型号为STC89C52的单片机包含3个定时器:Timer0/Timer1/Timer2
其中Timer0/Timer1是兼容51单片机的,而Timer2则是STC89C52型号所特有的。
对于T0和T1而言,它们都包含4种工作模式(0、1、2、3),不过我们初学者使用最多的当属T0的模式1。
1.2 定时器构成
定时器由三部分构成:系统时钟、计数单元和中断系统。
以下基于定时器0的模式1进行相关解释
1.2.1 系统时钟
系统时钟,即上图所示的SYSclk,这个东西是用于计时的,即每隔一段时间便向计数单元(上图中的TL0和TH0)提供一个脉冲,如此计时单元便加1。SYSclk有两个模式12T和6T,STC89C52的型号默认是12T模式,要想更改为6T模式,需在烧录软件STC-ISP中进行更改。
这个模式具体是什么意思呢?普中科技的A2开发板晶振频率,即系统时钟输出脉冲频率为11.0592MHZ,12T模式就是将此频率除以12后,以此为新的脉冲输出,即计时频率;6T Mode同理。
当然,我们注意到图中有一个T0 Pin,这是T0的外部引脚,它也可以提供脉冲,如果采用这个外部引脚提供脉冲,定时器就相当于一个计数器,而计数单元就用于记录外部输入的脉冲次数。
而到底是通过哪个输出脉冲则取决于图中C/T的取值,取0则SYSClk输出脉冲,为定时器;取1,则由外部输入脉冲,为计数器
1.2.2 计数单元
计数单元是由图中的TL0与TH0组成的。在定时器0的模式1下,计数单元共有16位二进制,低八位存储在TL0中,高八位存储在TH0中。
由此可见,此计数单元的计数极限为65535(2的16次方减去1得到65535),一旦超过这个极限,便会由上图中的TF0中断源(用于发出中断请求的器件为中断源)发出中断请求,中止主程序的执行,而执行相应的中断函数。
1.2.3 中断系统
中断系统是为使CPU具有对外界紧急事件的处理能力而设置的。
中断的过程可以分为三步:
- 中断请求:由中断源发出中断请求
- 中断响应:相应中断请求后,主程序中止,执行相应的中断处理程序
- 中断返回:中断函数执行完毕后,返回原先的主程序
中断请求有优先级之分,对于STC89C52型号的单片机,共有4种优先级(高、较高、较低、低),中断系统总是会先执行高优先级的中断请求,因此就有可能会存在一个低优先级的中断被高优先级的中断打断,这时候便形成了中断嵌套,而含有中断嵌套的中断系统被称为多级中断系统,反之则为单级中断系统。
实际上,同一优先级的中断请求也会因中断源的不同而产生次序之分。
STC89C52型号的单片机提供了八个中断请求源,它们的次序如下:
简而言之,不同优先级的中断请求看优先级,相同优先级的中断请求看中断查询次序号。
低优先级中断可被高优先级中断打断,某一优先级的中断一旦响应便不可被同级中断打断。
下附STC89C52的中断结构图:
1.2 定时器0/1的相关寄存器
1.2.1 TMOD
TMOD寄存器是用来控制定时器1/0的模式的,高四位用于定时器1,低四位用于定时器0,二者的模式设置几乎是完全相同的。
- M1/M0用于定时器模式选择:
0 0代表模式0,0 1代表模式1,1 0代表模式2,1 1代表模式3,特别注意模式1,这几乎是使用最多的。
- C/T用于切换定时器/计数器:
C/T置为0时表示定时器,C/T置为1时表示计数器。
- GATE用于控制定时器的开闭条件:
以定时器0为例,如果GATE置为1,则定时器0想要打开,必须INT0和TR0均置为1;如果GATE置为0,定时器想要打开,则只需TR0置为1即可。
通常情况下,较为简单的定时器功能,我们将GATE置为0即可。
特别注意,由于TMOD寄存器是不可位寻址的,所以配置TMOD寄存器必须八位二进制一起配置,而不能各个二进制位分别配置。
1.2.2 TCON
TCON是定时器0/1的中断控制寄存器,以下介绍TCON寄存器B7~B4位所代表的含义:
- TR1和TF1:
TF1:可以理解成定时器1的中断源,置1时说明计数单元溢出了,就向CPU请求中断;置0则表示计数单元未溢出。(TF1中的F意指flag)
TR1:当GATE置为0时,TR1=1就允许T1开始计数,TR1=0时禁止T1计数。
- TR0和TF0:与定时器1相同,此处不再赘述
特别注意,TCON寄存器是可以位寻址的,即TCON可以一位一位分别进行设置,而不用对TCON整体进行赋值。
1.3 初始化定时器0
以下是初始化定时器0的代码示例:
上述对定时器0的配置,使得定时器0每间隔1ms(存在微小误差,因为晶振的频率不为12MHZ)便会进行一次中断。
基于这个定时器0的配置,我们可以写一个间隔为1s(1ms的一千倍)的定时器0的中断函数模板: