1 定时/计数器介绍
定时/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器THX和TLX组成。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1(产生一个溢出标志),向CPU发出中断请求(定时/计数器中断运行时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。
(1)CPU时序的有关知识
①时钟周期/振荡周期:时钟周期又叫做振荡周期、节拍周期,定义为时钟晶振频率的倒数。时钟周期是计算机中最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。例如晶振为12M,则时钟周期为1/12us。又可以被定义为节拍。
②指令周期:指令周期是指取出并完成一条指令所需的时间,一般由若干个机器周期组成,分为单周期指令,双周期指令和多周期指令。对于一些简单的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。
③机器周期:在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。比如,取值周期,取数周期。在80C51内部,机器周期一般包括于6个状态周期,12个时钟周期。例如24M的晶振,机器周期为12/24M秒。
例如:外接晶振为51 单片机相关周期的具体值为: 振荡周期=1/12us; 状态周期=1/6us; 机器周期=1us; 指令周期=1~4us;
(2)学习定时器需要明白的几点:
①普通51单片机有两组定时/计数器,因为即可以定时,又可以计数,故称之为定时/计数器;
②定时/计数器和单片机的CPU是相互对立的,定时/计数器工作的过程是自动完成的,不需要CPU的参与。
③51单片机中的定时/计数器是根据机器内部的时钟或者是外部的脉冲信号对寄存器的数据加1。
有了定时/计数器之后,可以增加单片机的效率,一些简单地重复加1的工作交给定时/计数器处理。CPU转而处理一些复杂的事情,同时可以实现精确定时作用。
(3)定时/计数器内部结构框图
定时/计数器T0和T1分别是由两个8位的专用寄存器组成,即定时/计数器T0由TH0和TL0组成,T1由TH1和TL1组成。此外,其内部还有2个8位的特殊功能寄存器TMOD和TCON,TMOD负责控制和确定T0和T1的功能和工作模式,TCON用来控制T0和T1启动或停止计数,同时包含定时/计数器的状态。
TF0:定时器0溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除,或用软件清除。
TF1:定时器1溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除,或用软件清除。
从上面的图中红线可以看出由TMOD选择由那个定时器工作,工作于什么方式;
从上面的图中蓝线可以看出由TCON决定定时器是否启动;
从上面的图中黄线可以看出外部技术输入由TH和TL进行累计;
从上面的图中紫线可以看出当TH和TL计数溢出时会向TCON进行申请报告;
从上面的图中绿线可以看出所有的定时中断都由TCON向CPU进行中断申请;
从上面的图中黑线可以看出外部中断直接向CPU进行中断申请;
(4)定时/计数器相关寄存器配置
1)定时器控制寄存器TCON
①-④TCON[3:0]:外部中断控制位;
⑤TR0(TCON[4]) :定时/计数器T0运行控制位,TR0=1时,T0开始工作,否则停止工作。TR0由软件置1或清0。所以,用软件可控制定时/计数器的启动与停止。
⑥TF0(TCON[5]) :定时/计数器T0溢出中断请求标志位。T0计数溢出时由硬件自动置TF0为1。CPU响应中断后TF0由硬件自动清0。
⑦TR1(TCON[6]) :定时/计数器T1运行控制位,其功能与TR0类同。
⑧TF1(TCON[7]) :定时/计数器T1溢出中断请求标志位,其功能与TF0类同。
2)定时器模式寄存器TMOD
①-② M1M0(TMOD[1:0]):定时器T0工作方式设置位,共有四种工作方式。
③ C/T(TMOD[2]):定时器T0定时/计数模式选择位,当C/T=0时为定时模式;当C/T=1为计数模式;
④ GATE(TMOD[3]):定时器T0门控位,用于控制定时器的启动是否受外部中断源信号的影响。当GATE=0时,只要用软件使TCON中TR0或TR1为1,就可以启动定时器工作;当GATE=1时,不仅要用软件使TCON中TR0或TR1为1,同时外部中断引脚INT0/INT1也为高电平时,才能启动定时器工作。
④~⑦(TMOD[7:4]):定时器T1工作模式设置位,与定时器T0类同。
2 功能要求:通过定时器 0 中断控制 D1 指示灯间隔 1 秒闪烁,定时器1中断控制D2指示灯间隔1秒闪烁。
3 硬件设计(略)
4 软件设计
1 #include "reg52.h" //头文件
2
3 typedef unsigned int u16;
4 typedef unsigned char u8;
5
6 //定义输出管脚
7 sbit LED1 = P2^0; //LED1管脚
8 sbit LED2 = P2^1; //LED2管脚
9
10 //定时器T0初始化,顺序可以调整
11 void timer0_init(void)
12 {
13 TMOD = TMOD | 0X01; //设置定时器的工作方式,即TMOD=0000_0001
14 /*选择定时器T0,工作方式1*/
15 TH0 = 0XFC; //给定时器TH赋初值,定时1ms
16 TL0 = 0X18; //给定时器TL赋初值,定时1ms
17 ET0 = 1; //打开定时器中断允许位
18 EA = 1; //打开总中断允许位
19 TR0 = 1; //打开定时器
20 }
21
22 //定时器T1初始化,顺序可以调整
23 void timer1_init(void)
24 {
25 TMOD = TMOD | 0X10; //设置定时器的工作方式,即TMOD=0001_0000
26 /*选择定时器T1,工作方式1*/
27 TH1 = 0XFC; //给定时器TH赋初值,定时1ms
28 TL1 = 0X18; //给定时器TL赋初值,定时1ms
29 ET1 = 1; //打开定时器中断允许位
30 EA = 1; //打开总中断允许位
31 TR1 = 1; //打开定时器
32 }
33
34
35 //主函数
36 void main()
37 {
38 timer0_init(); //对定时器T0进行初始化
39 timer1_init(); //对定时器T1进行初始化
40
41 while(1)
42 {
43 /*进入循环,但没有任何执行功能程序,但当定时时间到达1MS,
44 即会进入定时中断函数*/
45 }
46 }
47
48 //定时中断,定时1ms
49 void time0() interrupt 1
50 {
51 static u16 i; //静态变量i,可以保持原来的值
52 TH0 = 0XFC; //定时器溢出后,需要手动加载初值
53 TL0 = 0X18;
54 i++; //i=i+1,
55 if(i==1000) //当i=1000时,表示定时时间达1秒
56 {
57 i = 0; //清零变量i,代表1秒时间完成
58 LED1 = !LED1; //控制LED状态翻转
59 }
60 }
61
62 //定时中断,定时1ms
63 void time1() interrupt 3
64 {
65 static u16 i; //静态变量i,可以保持原来的值
66 TH1 = 0XFC; //定时器溢出后,需要手动加载初值
67 TL1 = 0X18;
68 i++; //i=i+1,
69 if(i==1000) //当i=1000时,表示定时时间达1秒
70 {
71 i = 0; //清零变量i,代表1秒时间完成
72 LED2 = !LED2; //控制LED状态翻转
73 }
74 }
timer_led
5 仿真与实验结果
实验现象:指示灯D1和D2间隔1s闪烁。
参考文献
(1)单片机时钟周期、机器周期、指令周期的区别-百度经验 (baidu.com);