寄存器
在单片机中,具有很多用来储存数据的单元,当我们的代码下载进单片机时,就是将代码转化成二进制的机械码并储存在这种单元中,在这些单元中,有一部分特殊的单元,对里面储存不同的值会导致单片机工作的方式不同,这部分具有特殊功能的单元我们称为寄存器(由多个寄存器组成的一个功能整体我们称之为外设)。(例如 P0 , P0 这个寄存器的作用就是改变 IO 的输出状态。)
不同的芯片内部具有的寄存器是不完全相同的,所以当我们使用不熟悉的芯片时,需要根据芯片数据手册来编写代码。
接下来我们介绍关于 STC12C5A60S2 这个系列的芯片上常用的寄存器。
定时器
在大多数通信或者实际项目中,对于信息处理的时间是有严格要求的,但是由于不同的芯片在功能等方面的差异,我们不能精准的知道运行一行代码的时间长短,所以大多数芯片都会具有定时器这个外设,来满足我们项目需求中的时间需求。
时钟
已经知道芯片中有定时器了,但是定时器是由什么作为参考来计时呢?
在大多数电路中,芯片附近可以找到晶振存在,晶振的作用就是提供一个固定的时钟信号。
像上图这样的我们就称之为时钟信号,晶振所发出的时钟信号的频率时固定且精准的,我们就可以通过读取这个时钟信号的周期次数来计时。
定时器寄存器
我们打开芯片手册
目录中可以直接找到定时器,计数器。
里面对于定时器的介绍有这一段话,通过记录时钟周期的次数来决定计时脉冲的时间,每一次的时钟周期的时间一定,我们改变一次计时脉冲所需要的时钟周期次数,就可以改变一次计时脉冲的时间,我们使用的芯片的定时器支持一个时钟周期就等同于一个计数脉冲,也支持十二个时钟周期等同于一个计数脉冲,默认情况下,是十二个时钟周期等同于一个计数脉冲。
接下来我们可以看到定时器外设所含有的寄存器,我们先讲解 TH 和 TL 寄存器(先不管 0 和 1 的区别,后面会讲到)
记录计数脉冲的次数就是使用的这两个寄存器,两个寄存器都是只有 8 位宽,没过一次计数脉冲, TL 的值就会增加 1 ,随着时间增加, TL 加到 255 时再次加 1 就会溢出,此时 TH 的值会加 1 , TL 的值会清零,随后 TH 的值加到 255 后再次加 1 也会溢出,此时 TH 也会清零。所以定时器不能无限记录时间的长短,是有范围的,在使用定时器时我们就要去考虑定时器的计时范围。
在 STC12C5A60S2 中,一共有两个定时器,分别是 T0 和 T1,所以我们可以看到 TH 和 TL 也被分为了 0 和 1 。
我们再来介绍 TMOD 寄存器的作用,我们可以看到这个寄存器也是八位,被分成了两个四位分别给 T0 和 T1 两个定时器使用。、
每单独的四位里前两位我们不用去深究,有兴趣可以看一下,我们只需要去配置后两位 M0, M1 ,作用时配置定时器的工作方式。
我们可以看到,后两位可以组成四种不同的工作方式。
这儿介绍常用的工作方式。
01
这个工作方式下,TH 和 TL 两个八位的寄存器全部使用,组成一个十六位的寄存器,计数溢出后计数清零。
10
在这个工作方式下,计数器只用了 TL 的八位,计数 256 次后溢出,但是溢出后的值会把 TH 的值存入 TL ,TL 就不被清零。
我们可以看到,在 TCON 这个寄存器中,每一位都被给予了新的名字,其中 TR 的作用时允许定时器开始计时,我们可以把它当作一个开关的功能,当每次计数溢出后, TF 会被置 1,当产生中断(后面会讲)时,这个位才会被清零。
我们需要配置的寄存器也就这些了,其他的默认就行。
代码例程
//所以,我们要开启定时器计时,就对这些寄存器配置就行
void Init(void) {
TCOM = 0x01; //把定时器1配置成01的模式
TR0 = 1; //允许定时器1计数
//定时器计数的初始化就完成了,我们可以通过读取TH和TL的值来判断代码运行时间
}
定时器中断
中断
当我们正在做一件事情的时候,突然被另一件重要的事情打断,所以我们选择优先完成重要的事情,再回来接着完成之前没做完的事情,这个过程我们就称之为发生了中断,重要的事我们称之为中断事件。
定时器中断
由定时器的计数寄存器溢出,从而产生的中断,我们又称之为定时器中断。
上面我们讲到 T