跟我学STC15F2K60S2-定时器的使用

  • SingleYork
  • LV5工程师
  • |      2016-04-29 17:17:35
  • 浏览量 3841
  • 回复:13

       由于之前焊好的一块开发板送到社区做展示了,一直又没有时间静下心来重新焊一块板子,所以本开发板的教程暂停更新了一两个月,实在是抱歉啊!昨天抽空又重新焊了一块开发板,接下来,我会继续抽时间跟大家一起学习后面的内容。


         这一节主要跟大家一起学习一下STC15F2K60S2的定时器,本贴我们只以TMER0做讲解。学习之前,我们先来看下本例要用定时器实现的功能吧:


        


       如上图所示,是用定时器控制一个LED亮0.5秒,然后灭0.5秒,再亮0.5秒……如此循环,从而达到闪烁效果。


        


       从官方给的资料上,我们可以看到,STC15F2K60S2单片机有3个定时器/计数器,即:TMER0、TMER1、TMER2三个定时器,是通过C/T这个位来设置的,当C/T=0时,定时器/计数器为定时器,当C/T=1时,定时器/计数器为计数器,当工作在定时器状态时,其中TMER0、TMER1有四种工作模式(TMER2的工作模式固定位16位自动重装模式),即:


       模式0:16位自动重装载模式

       模式1:16位不可重装载模式

       模式2:8位自动重装模式

       模式3:不可屏蔽中断的16位自动重装载模式


       关于以上四种模式的详细说明,官方给的资料上写的很详细,在此我就不多说了,其中模式0是我们比较常用的,而在此前的51单片机的定时器做定时用时,比较常用的是模式1。看到这里估计很多小伙伴又要疑惑了:既然有了16位不可重载模式干嘛还要弄个16位自动重载模式呢?很显然,这样做肯定是有目的的嘛!手动重装的程序运行是需要时间的,这段时间久而久之会造成误差,所谓自动重装载就是在定时器溢出后自动装入设定的初值,这样的好处当然是显而易见的,不需要在中断服务器里手动赋值了,所以可以精确的定时,比如T1和T2做波特率发生器时都需要设置成自动重装载模式就是如此。


       既然我们知道了定时器有四种工作模式,那么要通过什么方式才能让定时器工作在想要的工作模式下呢?

       STC15F2K60S2单片机是通过对寄存器TMOD中的M1(TMOD.1)、M0(TMOD.0)来设置的。


      


       那么让我们来看下M1(TMOD.1)、M0(TMOD.0)在寄存器TMOD中的结构吧:

      

        


       于是,我们便很清楚的知道,要想让定时器0工作的模式零,只需要将TMOD的0和1两位置0即可,当然C/T位肯定也是要置0的;而GATE(TMOD.3)位的功能是用来配置定时器0的启动限制条件:置1时只有在INT0脚为高及TR0控制位置1时才可打开定时器/计数器0,我们一般默认设置为0,即:只需要TR0来控制定时器的启动,TR0=1时,启动定时器0,TR0=0时,关闭定时器0。


       接下来我们再来看下另外一个与定时器0有关的寄存器AUXR-辅助寄存器,这是一个很重要的寄存器,但在此处,我们仅仅学习他对定时器0的影响。


       AUXR格式如下:

      

        


       在这里,我们仅仅只需要关注T0x12这个位就好了,这个位主要是用来控制定时器0的速度的,即:

       T0x12 = 0时,定时器0是传统的8051速度,12分频

       T0x12 = 1时,定时器0的速度是传统8051的12倍,不分频


       其他的位的功能因跟本例无关,在此就不再赘述,感兴趣童鞋可以自行查看手册。

      

       通过上述学习,相信大家都知道怎么配置定时器的工作模式、速度及启停了,接下来我们一起来学习定时器的定时时间,很显然,我们既然用它来定时,肯定需要设置让他定时多长时间嘛,到底是1ms、100ms、10s还是多长时间?别急,马上就知道了!


         在学习设定定时时间之前,再跟大家科普下一些小知识点,也是很重要的一些知识点:

什么是单片机的1T模式跟12T模式。


    1T、6T12T等这个原本叫机械周期,现在更多人称为指令周期;以前标准51单片机,是12T模式的。后来大量单片机厂家的介入,开始对单片机进行提速,于是就出现了 6T1T模式的单片机。

    时钟周期:是指振荡源的周期,如 外部晶振 10MHz(假设有),那么它的时钟周期就是 1/10MHz=0.1us

    机械周期:单片机执行一单位指令所需要的 时钟周期 个数,如 1T,就表示,需要 1个时钟周期;12T 即为 12个时钟周期。这些都只是 一单位指令的时间(如自增、自减等),多单位指令时间进行倍乘(如赋值语句需要2个机械周期,即乘以2倍)。

    指令周期:早期更多的是用来描述 某条指令执行 需要多少个机械周期,(如自增、自减为 1个机械周期,赋值 2个机械周期,判断 4个机械周期)。随着C语言的大量普及,现在,更多的人用它来代替 机械周期 这个名词,而 指令本身的 周期被人们所忽略,不再深讨了。

    有了上面的知识,那么我们可以来计算下定时器0工作在16位自动重载模式下的初值了。

    首先,我们知道了工作在1T模式下的单片机时钟周期为外部晶振频率的倒数,即:Tcy=1/focs,也就是说单片机每执行一单位指令需要1/ focs秒,(当然我们所使用的是内部晶振,那么就是内部晶振频率的倒数了)那么如果我们需要定时t秒,需要单片机执行多少条这样的指令呢?很显然:Nt=t/ Tcy。那么定时器的初值很显然就是:N初值=Nmax- Nt,将前面几个公式代入即得:N初值=65535-focs*t;此例中我们定时的时间是1ms,即1/1000s,那么 N初值=65535-focs/1000;12T模式下的计算就不再在此赘述了,请大家自行完成吧。

   

    


    


    到此相信大家应该都知道怎么设置自己想要的定时时长了,到这里,我想又会有小火伴要感到疑惑了:如果我程序中要设置很多个不同的时长,难道要用很多个定时器?答案肯定是:NO!如果单片机有那么多定时器资源,这么做也是可以的,那如果要设置几十个、甚至几百个不同时长,不可能去找个有这么多定时器的单片机吧?这肯定是不可能的!那么我们究竟该怎么实现呢?其实很简单!

    我们只需要在程序中设置一个基准定时,比如1ms,然后再通过设定不同的变量来达到定时不同时间的目的。比如本例中我们要实现的是0.5秒取反一个指示灯,那么我们可以在基准时间里设置个计数CNT,然后当CNT计数500次后开始让LED取反(即500*0.001s=0.5s),再将CNT清零重新下一次计数。这样就到达了我们想要的每隔0.5秒将LED取反的目的!

   


        最后在此给大家奉上源代码,需要的小伙伴们请自行下载吧:


        




  • 0
  • 收藏
  • 举报
  • 分享
我来回复

登录后可评论,请 登录注册

所有回答 数量:9
瞎折腾 2016-05-01
感谢楼主
0   回复
举报
发布
SingleYork 回复 2016-06-23
欢迎经常来逛哦……
0   回复
举报
2016大圣 2016-04-30
楼主:拜读了,谢谢!
0   回复
举报
发布
SingleYork 回复 2016-06-23
过奖了……;P
0   回复
举报
lilei 回复 2016-12-06
厉害呀 收藏了
0   回复
举报
lilei 回复 2016-12-06
厉害呀 收藏了
0   回复
举报
SingleYork 2016-04-29
月底了,一看,这个月交白卷了,于是只能拼了……
0   回复
举报
发布
SingleYork 2016-04-29
这个可以有,等我有时间弄个试试……
0   回复
举报
发布
s112 2016-04-29
6个6,好斑竹都是月底努力发帖哟
0   回复
举报
发布
灵澈 2016-04-29
节前这么用功
0   回复
举报
发布
HelloWii 2016-04-29
用定时器 模拟个 PWM ,来鼓捣个  呼吸灯 就更棒了。。。。
0   回复
举报
发布
SingleYork 2016-04-29
我去,老大神速啊,我都还没编辑完了,呵呵……
0   回复
举报
发布
gtrjolin1986 2016-04-29
图挂了啊!
0   回复
举报
发布
x
收藏成功!点击 我的收藏 查看收藏的全部帖子