学习单片机这门课的时候我们肯定会学习到中断这节,然后就会了解到什么是外部中断和内部中断还有串行口中断,外部中断包括:外部中断0(INT0),外部中断1(INT1);内部中断包括:定时器/计数器0,定时器/计数器1;我们这里只讲关于定时器T0/T1的知识及使用方法,后面关于其他的知识我们会陆续讲解。

标准的51里边只有定时器0和定时器1这两个定时器,现在很多单片机也有多个定时器的,在这里我们先讲定时器0和1。那么我前边提到过,对于单片机的每一个功能模块, 都是由他的SFR,也就是特殊功能寄存器来控制。而和定时器有关的特殊功能寄存器,有以下几个,大家不需要去记忆这些寄存器的名字和作用,你只要大概知道就行,用的时候,随时可以查手册,找到每个寄存器的名字和每个寄存器所起到的作用。

T0有4种工作方式,T1有3种工作方式,每种工作方式都有定时和计数2种方式,故共有14种组合关系。见下表:

单片机之定时器篇_初值

定时/计数器控制寄存器 TCON (可位寻址)

单片机之定时器篇_单片机_02


关于定时器控制位的描述如下:

单片机之定时器篇_寄存器_03


*TF0/TF1使用中断方式时,作为中断标志位,中断响应后由硬件自动清零;

*TF0/TF1使用查询方式时,作为状态供查询,查询有效后应用软件将该位自动清零。工作方式控制寄存器 TMOD (不可位寻址)

单片机之定时器篇_寄存器_04


关于工作方式寄存器的描述如下:

单片机之定时器篇_寄存器_05


这个地方的意细心的同学会发现,TCON那个地方标注的是“可位寻址”,TMOD这里标注的是“不可位寻址”。这个地方的意思就是比如TCON有一位TR1,我们可以在程序中直接进行TR1 = 1;这样操作。但是(T1)M1 = 1;这样的操作就是错误的。我们要操作就必须一次操作一个字节, 就是必须一次性对TMOD所有位操作,不能对其中某一位单独进行操作。

接下来介绍一下关于定时器工作方式,以及计算公式和计数范围。

工作方式

T1只有3种工作方式(T0的方式3中占用了T1的部分资源)

T0

单片机之定时器篇_编程语言_06


T1

单片机之定时器篇_寄存器_07


计算公式

定时计数初值 a = 2^x- t×fosc/12

(t ≤2^x us, fosc=12MHz时)

各工作方式的计数范围
工作方式0
N=2^13-计数初值
即 计数初值=2^13-N,计数范围即位1~8192
定时时间 t=(2^13-计数初值)(振荡周期12)
假设晶振频率位12MHz,则最大计数个数为8192,最大定时时间则为8.192ms。

由此可知
工作方式1的最大计数个数为65536,最大定时时间为65.536ms。
工作方式2的最大计数个数为256,最大定时时间为0.256ms。

工作方式3
当T0置成工作方式3时,TL0、TH0为两个独立的计数器
(1)TL0的功能和操作与方式0、1完全相同(定时/计数),使用T0的所有控制位。
(2)TH0只能用作定时功能,并占用了T1的控制位TR1和中断标志位TF1,其启动仅受TR1的控制。

利用定时器做一个延时1s的流水灯设计

程序代码如下:

#include"reg52.h"  //头文件
#define LED P1 //端口单片机P1端口名称为LED
unsigned char i; //定义一个无符号字符型变量 i

void Delay_50ms(unsigned char Times) //定义一个50ms的子函数
{
while(Times--)
{
/*这里用的是定时器0,工作方式1,工作方式1的计数最大值是65536us,
1s的话是1000000us,显然想要达到1s的效果,已经超出了工作方式一的
最大计数值,所以我们采用0.05s,让它重复执行20次,依次来达到1s的效果,
0.05s也就是50000us,我们根据根据公式可以计算出它的计数初值为16536,
转换后换成16进制就是3cb0H*/

TH0 = 0x3C; //计数初值的高8位赋值给TH0
TL0 = 0xB0; //计数初值的低8位赋值给TH0
TR0 = 1; //启动定时器0
while(!TF0); //判断T0是否溢出,如果没有则继续计数
TF0 = 0; //溢出后清0
}
}

void main(void) //主函数
{
TMOD = 0x01; //设置TMOD的值,表示用的是定时器0,工作方式1
EA=1; //开中断
ET0=1; //开定时器0中断
while(1) //死循环
{
for(i=0;i<8;i++) //利用for循环,达到8个灯的流水效果
{
LED=~(0x01<<i); //LED向左循环一位
Delay_50ms(20); //延时1s
}
}
}

仿真电路图如下:

单片机之定时器篇_编程语言_08


本次分享就到这里,喜欢的话可以关注我,一起玩转单片机,希望我们都可以在这条路上走得越来越远,路越来越宽❤~