好久没更新了..
一开学就好忙~
不过我们的校内电子设计竞赛
就快要开始了。
这几天多更新点。。
中断概述
上节的内容是外部中断
这节我们介绍另一种非常重要的中断——
定时器中断
大家可能都忘了中断源有哪些,放上图
什么是定时器中断呢?
其实就是
过一段时间 (定时周期)
就执行 某一段程序 (中断子程序)
打个比方:
宿舍楼的阿姨/大爷
每隔一个月 来 查一次水表
也就是说,我们可以将需要定期执行的程序
利用定时器功能来实现
首先,定时器具有定时的功能
比如我给定时器设定定时时间为 10ms
那么在这之后过了 10ms
定时器将发出一个中断请求
让单片机运行中断子程序中的内容
定时器主要用在:
把比较重要的或者需要每隔一定时间执行一次的程序放在定时器内,确保其能定期被运行。
精确计时,做秒表、时钟等应用。
我们所使用的单片机(STC89C52RC)
是传统MCS-51单片机的升级版
其内部有三个定时器中断源(T0 T1 T2)
其中 T2定时器的某些特性和 T0 T1 不同
我们在这里只讲解 T0 T1 部分
在这之前,我们先了解一下单片机的时钟系统~
单片机时钟系统
我们先了解下面几个概念:
时钟周期:
单片机晶振的震荡周期,频率的倒数。
机器周期:
完成一个基本操作的时间单元叫做机器周期。
一个机器周期由若干个时钟周期构成。
我们所使用的单片机其机器周期由12个时钟周期构成。
即: 机械周期 = 12 × 时钟周期
指令周期:
完成一条指令所需的时间。
简单的指令是单机器周期指令;复杂的为双机器周期指令和多机器周期指令.
由于我们使用C语言编程,编译时会转换成机器语言
由于编译器的不同,相同的语句可能会编译成不同的指令
如赋值语句: i=0;
有可能是一条单机器周期指令
也有可能是一条双机器周期指令
准确的指令周期需要根据汇编程序来确定哦~
我们可以看到开发板上的晶振
画圈的就是我们单片机的晶振
上面写着 11.0592 单位是兆赫兹(MHz)
那么我们单片机的时钟周期是 (1/11.0592M) s
这个晶振是可拔插的,我们可以使用不同频率的晶振
改变单片机的时钟周期,相应的单片机的运行速度也会改变
(有的板子配的是12MHZ的晶振哦)
如果晶振是12M的话,那么时钟周期就是
1/12000000 秒
对应的机械周期就是
1/12000000 × 12 = 1/1000000 = 1 us
机械周期正好是1us
这会方便我们的计算
所以初学者用12MHz 的晶振比较多哦~
(那么为什么会有11.0592MHz 这种频率的晶振呢?其实是为了串口通信时的便利,这个我们以后会说的~)
下面的内容为了方便理解与计算,就假设我们使用的晶振是12MHz。
那么机械周期就是 1 us
而定时器就是以1个机械周期作为最小计时值的。
接下来我们就看看定时器的SFR(特殊功能寄存器)有哪些?
定时器的主要寄存器
定时器主要寄存器如下:
寄存器TMOD我们先放一放
先看一下 ET0 ET1
是不是跟上节的 EX0 EX1 相对应呢?
没错,这就是定时器的使能控制位
也就是说
ET0 = 0 ; //中断未使能 即使定时时间到了也无法进入中断
ET0 = 1 ; //中断使能,能够正常进入中断。
(由于定时器0和定时器1的部分寄存器使用方法完全相同,只讲解定时器0的部分寄存器,定时器1使用方法可自己推导)
ET0 ET1控制定时器0和1的中断是否使能
另一个寄存器 TR0
即定时器0的运行控制位
TR0 = 0 ; //定时器处于关闭状态
TR0 = 1 ; //定时器开始运行
其实相当于定时器开始计时的开关~
下面我们讲一下比较特殊的TMOD寄存器(定时器工作方式寄存器)
可以看到 TMOD寄存器 由8个位组成(D0-D7)
我们将其分为左右两部分
左边(高位)的对应定时器1 ,右边(低位)对应定时器0
我们先讲右边的定时器0部分:
D3 GATE 置1时只有在INT0脚为高电平及TR0置1时才能打开定时器0
D2 C/T 置0则定时器0用作定时器 置1用作计数器
D1 M1 和M0共同设置定时器工作模式
D0 M0 和M1共同设置定时器工作模式
其中
GATE位较不常用,这里不做讲解,默认置0。
C/T位用于配置计数器/定时器模式,我们这里用其定时器功能,将其置0。当用到计数器功能时 应置1
(计数器就是用外部脉冲进行计数,这里不多讲)
前面这两位寄存器我们这里不适用,全部置0。
后面的 M0 M1位 我们需要重点关注
他俩共同决定了定时器的工作模式,如图:
M0 M1共同决定了定时器工作模式
当M0和M1均为0时,为工作方式0,即13位定时器
当M0为1,M1为0时,为工作方式1,即16位定时器
工作方式2会在串口部分讲解,这里不多说
工作方式3不常用,就不说啦。
至于什么是13位定时器、16位定时器呢?
这就跟前面说的 TH0 TL0 寄存器有关了
这两个寄存器都是8位寄存器
能够存储 0-255 之间的二进制数
在单片机中用来存储当前的计时值。
计时/计数规则就是:
定时器运行时,每经过一个机器周期,TL0自加1;
也就是说
当TL0初值为0时,经过255个机器周期后(255us)
TL0加到最大值,这时再加就会溢出,这导致单片机可定时的时间极短(几百us)
时间那么短,我们用起来就会很不方便
所以,厂家想到了一个办法
那就是将TH0和TL0这两个8位寄存器级联
如下图:
13位定时器模式
TH0的高3位舍弃不要
其低5位和TL0的8位组成了一个
13位的存储区域
同样的道理,两个寄存器最多能组成一个16位的定时器:
16位定时器模式
他们工作起来是这样配合的:
TL0累加进位至TH0
就这样,可定时的时间范围变大了,
可以达到2^16=65535us=65.535ms
我们就以16位定时器为例子
(实际应用中16位模式用的比较多~)
当这个16位定时器累加至65535us后
再经过一个机器周期,会导致最后的溢出
产生一个中断请求,进入中断子程序
这样就是一个基本的定时器中断过程
看图更好理解一些~
再此基础上,假设我们每次发产生中断就立即
对TH0和TL0的值进行重装载置0,
那么定时器就会不断的运行,并且每隔一段时间T中断一次
前面我们每次都对TH0 TL0 重装载0值
假设我们装载一个中间值呢?
比如 64535
(二进制: 1111110000010111)
(十六进制: 0xFC17 即TH0=0xFC; TL0=0x17;)
每隔1000us 产生一次定时器中断。
即定时器中断子程序每过 1000us 被执行一次
(以上数据均在12MHz晶振下成立~)
现在我们理一理配置定时器0的思路:
配置 TMOD 寄存器
给TH0 和 TL0 赋初值
打开定时器开关 TR0
打开定时器0中断开关 ET0
打开总中断开关 EA
然后定时器就跑起来了~
当然还有一个中断子程序不要忘了写
至于怎么写..篇幅有限,下次再讲。。。
So...定时器的基本原理就那么多了~
这些内容说一下只用十几分钟
写成文字要好久。。
还要画图- -||
都写了那么多了,看来定时器要分成两节来写了
下一节继续讲定时器的应用~
PS:定时器真的是单片机的精髓啊,可能也是刚开始入门单片机唯一有点难的地方了,但是学好定时器实在是非常重要的~!定时器的应用太多太多了,巧妙地利用好定时器可以做好多复杂的事情了~
一开始接触有可能觉得看不太明白,因为涉及到寄存器这方面的东西算是比较抽象了,所以学习单片机真的要实践啊,光看看文章是没用的啊,写十几个定时器应用的程序,全部都会搞通的!