单片机定时器_蓝桥杯单片机竞赛备赛之定时器

289b1671e7d72da057ca44b1d9c91b1c.png

文 | 阿飞

写于2020-1-25

今天我们开始讲解定时/计数器的基础知识。

从名称上就可以看出来,这部分内容有两个主要功能模式:定时模式和计数模式。

工作在定时模式时,每经过一个机械周期,内部的16位计数寄存器数值就会加1,寄存器装满时就会溢出,对应的标志位就会被置高,计时会从我们存放的初值开始计时,一直到16位的寄存器存满时产生溢出,因此在最大计时范围内,我们只要计算出需要存放的初值,就可以准确的产生任意时间的定时。

工作在计数模式时,对应的计数器输入引脚每产生一个脉冲,计数寄存器就会加1。

使用定时/计数器步骤主要分为以下几步:

  • 启动定时/计数器(通过TCON寄存器控制)

  • 设置定时/计数器工作模式(通过TMOD寄存器控制)

  • 查询定时/计数器是否溢出(查看TCON中TF标志位)

这节课我们主要讲解一下定时器的基础知识:

659c3a405f31d972d12c9dde95ca01e4.png

我们先来看TCON寄存器高四位的使用:以定时器0为例,图中可以看到,TR0是定时器0的运行控制位,在TOMD.3 = 0的情况下(这也是我们常用的):当TR0 = 1时,定时器0会开始计时,TR0 = 0时,定时器0会禁止计时,因此,在启用定时器时,需要将TR0置高,“TR0 = 1”。TF0是定时器0的溢出标志,图中也可以看到,定时器0计满时,此标志位会被置高,在打开了定时器0中断的情况下,标志位会在响应中断后被硬件清0,也可以在程序的循环扫描中通过程序查询标志位并清0。(定时器1也是类似的)

再来看一下TMOD寄存器的使用:

3dd7f68ad57ba8cddc1d6a9283b33f88.png

从图中可以看到,TMOD寄存器是不可位寻址的,因此在使用时只能对此寄存器进行整体赋值(例:TMOD = 0x01;)图中的高四位(4~7)是定时器1的控制位,低四位(0~3)是定时器0的控制位,以下介绍仍然以定时器0为例(定时器1也是类似的):

cdb1d06037c31f40fd56e3cd3d17b9e5.png

GATE(TMOD.3)控制定时器0的打开方式(前边讲过的,这里我们一般配置为0,不做太多讲解)

33b44e8c631765bf8c71eb02b036bd92.png

C/T(TMOD.2)用来控制定时/计数器是工作在定时模式还是计数模式(当TMOD.2 = 1时工作在计数模式,TMOD.2 = 0时工作在定时模式)

0b5d4068c0e34c1eb1d349f037dc8745.png

M1(TMOD.1)与M0(TMOD.0)共同控制定时器0的定时模式,共有4种工作模式(0、1、2、3),这里我们常用的是模式1(M1 = 0、M0 = 1时),此时定时器的高8位与低8位全用,溢出值为65535,因此,当使用定时器0时,TMOD寄存器应配置为:“TMOD = 0x01; ”。(其它三个模式如果用到了会再讲,大家也可以去问一下百度)

现在就只剩下了最后一步:存放定时器初值,因为51单片机定时器默认为12分频的,因此,单片机的机械频率 = 晶振频率 / 12,机械周期 = 12 / 晶振频率,外接的晶振是11.0592MHz的频率,因此可计算出机械周期 = 12 / 11.0592 = 1.085(us)。也就是说,每隔1.085us,计数值会加1,我们只要用目标时间除以1.085us就是需要计数多少次,再用溢出值(65535)减去计数次数就得到了我们的需要存放的初值,我举个栗子:假设计时5ms, 5ms / 1.085us = 4608 ;65535 - 4608 = 60927;这个60927就是我们需要存放的初值,把高8位存放到TH0中,低8位存放到TL0中就可以啦,因此:TH0 = 0xed; TL0 = 0x14; 每次计时结束后进行下次计时时,初值会被清零,因此我们需要在查询TF标志位时重装初值。

好的,现在用程序来实现以下以上讲到的内容(led间隔500ms闪烁,假设LED直接由P1端口控制):

1a3594af5602d4855153e66c985403b3.png

接下来我们把定时器与中断配合起来使用(依然以定时器0为例):

ee60fa0a6a9c0424b148e4e011ab4109.png

a6829f0967e460c47b545b7069a644af.png

结合这两张图与上次讲的内容我们知道,打开定时器0中断时需要配置:“ EA = 1;  ET0 = 1; ”

配置好以后,每次定时器计满溢出时,程序会响应对应的中断,前边讲的,当打开了定时器对应的中断时,每次定时满响应了溢出中断以后,溢出标志位TF会被硬件清零,因此,我们就不需要在程序中编写 “扫描TF状态” 与 “清零TF标志” 的操作。

16f01bcee771bf2ff72b700ca524dad4.png

编写中断服务函数时需要在函数名后边加上中断编号:interrupt 1(定时器0),别忘了在中断服务函数中重放初值哦

在这里要强调一点:在中断服务函数里边不要放延时函数和死循环,也很好理解的,假如说我定时2ms,定时时间到了以后会执行中断服务函数,同时定时器会重新计时,当这里有延时函数与死循环时很容易造成这次中断服务函数还没有执行完,下一次又该开始了,程序很容易会跑飞的,因此,加了松手检测与按键消抖的按键扫描函数一定不能放里边

好的,接下来我们用程序来实现一下(与上一程序功能相同的):

dd8db3a63989951f986c8f977c2df0e8.png

小练习

(1)使用定时器控制数码管任意一位显示数值0~9(每隔1秒数值加1)。

(2)把我们将机械按键时写的那个用延时函数实现的秒表程序改为定时器计时。

▼ 更多蓝桥杯文章 ▼ 蓝桥杯·单片机竞赛备赛之外部中断 蓝桥杯·单片机竞赛备赛之机械按键 10d54ab8915d32db11d03d9f78e1c74a.png d2491d9c7aab189cb4f1ff0bb22a046a.png 扫码入群 扫码添加管理员微信

加入“电子产品世界”粉丝交流群

↓↓↓↓点击,查看更多新闻

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值