如电路图
定时器分为四个模块
- 时钟源模块
- 计数器模块
- 控制逻辑模块
- 中断模块 (notify)
如果要使用定时器, 需要对模块对应的寄存器做初始化
本次选择定时器0
, 工作模式1
配合芯片手册
初始化TCON和TMOD两个地址
所以
- 时钟源模块
- 使用默认的系统时钟源即可, 即
C/T=0
- 使用默认的系统时钟源即可, 即
- 控制模块
GATE=0
TR0=1
- 中断模块
TF0=0
IE0=1
ET0=1
EA=1
总闸启用IT0=0
低电平触发方式即可
M1/M0
两位共同选择模式, 赋值01
代表模式1
- 计数器模块
- 时钟源会每隔一段时间发送一次信号, 计数器接受到信号, 就将计数加一
- 定时器的本质原理,
每经过一个机器周期
,与定时器相关的某个寄存器加一
什么是机器周期
: 机器周期也称为CPU周期。在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段(如取指、译码、执行等),每一阶段完成一个基本操作。完成一个基本操作所需要的时间称为 机器周期。- 一个机器周期又是若干个时钟周期,一般来说一个机器周期是6个时钟周期或者12个时钟周期,我们
STC89C52RC
兼容51系列, 默认是12T模式 什么是时钟周期
: 时钟周期也称为振荡周期,定义为时钟频率的倒数
。时钟周期是计算机中最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。时钟周期是一个时间的量。时钟周期表示了SDRAM所能运行的最高频率。更小的时钟周期就意味着更高的工作频率。什么是晶振
: 晶振(晶体震荡器),又称数字电路的“心脏”,是各种电子产品里面必不可少的频率元器件。数字电路的所有工作都离不开时钟,晶振的好坏、晶振电路设计的好坏,会影响到整个系统的稳定性。在我们要使用定时器进行计数时,一定要了解以上的这些东西。我们要怎样准确的来时间,这就需要晶振派上用场了。每个单片机上面都会有晶振,每个晶振的频率也大不相同。例如,我手上这块51单片机的频率是11.0592MHz
。如上文所说,一个时钟周期是时钟频率的倒数,那么我手上这块51单片机的时钟周期是1/11.0592MHz
.机器周期 = n * 时钟周期 (此处n=12)
时钟周期 = 1 / 时钟频率
- 计数器是两个字节共同存储的, 当两个字节溢出后, 产生一次中断信号
- 计算出
一个机器周期对应的时间
, 设置好计数器的起始值
, 也就能让计数器指定间隔多少时间输出一次中断信号了 STC89C52RC
时钟频率是11.0592MHz
,11.0592MHz
的时钟源每隔约90.4224537037纳秒(即1 / 11.0592MHz)产生一个时钟脉冲信号。12T模式
下, 一个机器周期耗时也就是12*90.4224537037=1085.0694444444纳秒
, 我们需要让定时器间隔1毫秒输出一次信号
, 也就是1毫秒=1000000 纳秒 / 1085.0694444444 纳秒 ≈921.6
≈922
, 即922个机器周期约为1毫秒
- 即两个字节最大为
65535 - 922 + 1 = 64614 = 0xFC66
. (注意当计数器计数922次后到达65535时没有发生溢出, 需要再计数一次才发生溢出, 所以+1) 即TH0=0xFC
TL0=0x66
综上
TMOD
TMOD为不可位寻址 所以进行整体赋值
0000 0001
即
TMOD = 0x01
TCON
TCON可位寻址, 所以可以一个一个赋值
TF0=0
TR0=1
IE0=1
IT0=0
计数器
TH0=0xFC
TL0=0x66
附代码
#include "reg52.h"
#include "lcd1602.h"
typedef unsigned int u16;
typedef unsigned char u8;
sbit LED1 = P2^0;
void time0_init(void) {
//选择为定时器0模式, 工作方式1
TMOD = 0x01;
// 给定时器赋初值, 定时1ms
TH0 = 0xFC;
TL0 = 0x66;
// 打开定时器0中断允许
ET0 = 1;
// 打开总中断
EA = 1;
// 复位
TF0 = 0;
// 最后一步打开定时器
TR0 = 1;
}
void main() {
LCD_Init();
time0_init();
while(1) {
}
}
u16 a = 0;
u16 i = 0;
// 定时器0中断函数
void time0() interrupt 1 {
// 定时器重新赋初值, 定时1ms
TH0 = 0xFC;
TL0 = 0x66;
i++;
if (i == 1000) {
i = 0;
LED1 = !LED1;
a++;
LCD_ShowNum(1, 1, a, 3);
}
}
烧录好程序, 即可看到LCD每隔1s (存在误差)自增, LED也进行亮灭
注意: 本文归作者所有, 未经作者允许, 不得转载. 若有谬误, 欢迎指出