定时器计数器也可以简称定时器,是单片机内与CPU独立的一个硬件,是单片机的重点内容之一
CPU时序
振荡周期:为单片机提供实时信号震荡源的周期(晶振周期或外加震荡周期);
- 状态周期:两个振荡周期;
机器周期:六个机器周期;
指令周期:完成一条指令的全部时间,以机器周期为单位。
当外接晶振频率为12M时:
振荡周期:1/12M=1/12微秒
状态周期:1/6us
机器周期:1us
指令周期:1~4us
51单片机定时器结构
定时器计数器实质是加1计数器(16位),由高八位和低8位两个寄存器组成,工作时先向低8位累加,加满后再向高8位累加,高8位溢出后发出中断信号。TMOD是工作方式寄存器,确定工作方式与功能,TCON是控制寄存器,前面已经讲过。
TMOD寄存器
TMOD是定时器计数器的工作方式寄存器,低四位控制定时器T0,高四位控制定时器T1。
- GATE:门控位,GATE=0,定时器计数器的启动与停止仅受TCON寄存器中的TR0/TR1,GATE=1时,受TR0/TR1与外部中断引脚(INT0/INT1)上的电平共同控制‘’
- C/T:定时器模式和计数模式选择位,C/T=1为计数器模式,C/T=0为定时器模式;
- M1M0:工作方式选择位,每个定时器都有四种工作方式,如下表:
M1M0 | 工作方式 |
---|---|
00 | 方式0,为13位定时器计数器 |
01 | 方式1,16位定时器计数器 |
10 | 方式2,8位初值自动重装的8位定时器计数器 |
11 | 方式3,仅适用于T0,分成两个8位计数器,T1停止计数 |
定时器计数器工作方式
在这里我们以方式1为例。
定时器0方式1的逻辑结构如图:
当GATE=0,TR0=1,低8位TL0在机器周期的作用下开始加1计数,当TL0计满后,向TH0进位,直到TH0也满,此事计数器溢出,TF0置1,向CPU请求中断。
那么如何让定时器定时自己想要的时间呢?
定时器每执行一次+1需要一个机器周期,即12个振荡周期,在时钟频率为12MHz的单片机中,1个机器周期为1us,那么计满计数器需要2^16个机器周期,大约65.5ms。如果我们要定时50ms,就要给TL0TH0装一个初值,在这个初值上加50000个数后,定时器计数器溢出,就是50ms中断一次。当需要1s中断一次时,我们只需要编写程序,使定时器产生20个50ms的中断后执行中断程序。
如何计算初值呢?
当我们要定时50ms,那初值应该是2^16-50000=15536。15536/256=60装入高8位,15536%256=176装入低8位。
定时器程序编写
使用定时器前需对寄存器进行初始化:
- 对TMOD赋值,确定T0/T1工作方式
- 计算初值,填入TH0/TL0;
- 对IE0赋值,开放中断;
- 使TR0/TR1置位,启动计数。
接着我们编写程序,目的是使第一个发光二极管以2s为周期闪烁。
1 | #include<reg52.h> |