找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 16732|回复: 7
收起左侧

51单片机定时器设置入门 (STC89C52RC)

[复制链接]
ID:101489 发表于 2016-1-3 00:53 | 显示全部楼层 |阅读模式
本帖最后由 hushao 于 2016-1-3 00:54 编辑

51单片机定时器设置入门 (STC89C52RC)

STC单片机定时器的使用可以说非常简单,只要掌握原理,有一点的C语言基础就行了。要点有以下几个:

1. 一定要知道英文缩写的原形,这样寄存器的名字就不用记了。
理解是最好的记忆方法。好的教材一定会给出所有英文缩写的原形。
2. 尽量用形像的方法记忆
比如TCON和TMOD两个寄存器各位上的功能,教程一般有个图表,你就在学习中不断回忆那个图表的形像

TMOD:定时器/计数器模式控制寄存器(TIMER/COUNTER MODE CONTROL REGISTER)
                       
定时器/计数器模式控制寄存器TMOD是一个逐位定义的8位寄存器,但只能使用字节寻址,其字节地址为89H。
其格式为:

其中低四位定义定时器/计数器C/T0,高四位定义定时器/计数器C/T1,各位的说明:

GATE——门控制。
GATE=1时,由外部中断引脚INT0、INT1来启动定时器T0、T1。
当INT0引脚为高电平时TR0置位,启动定时器T0;
当INT1引脚为高电平时TR1置位,启动定时器T1。
GATE=0时,仅由TR0,TR1置位分别启动定时器T0、T1。

C/T——功能选择位
C/T=0时为定时功能,C/T=1时为计数功能。
置位时选择计数功能,清零时选择定时功能。

M0、M1——方式选择功能
由于有2位,因此有4种工作方式:
M1M0 工作方式 计数器模式 TMOD(设置定时器模式)
0 0 方式0 13位计数器 TMOD=0x00
0 1 方式1 16位计数器 TMOD=0x01
1 0 方式2 自动重装8位计数器 TMOD=0x02
1 1 方式3 T0分为2个8位独立计数器,T1为无中断重装8位计数器 TMOD=0x03
单片机定时器0设置为工作方式1为TMOD=0x01                  

这里我们一定要知道,TMOD的T是TIMER/COUNTER的意思,MOD是MODE的意思。至于每位上的功能,你只要记住图表,并知道每个英文缩写的原型就可以了。
在程序中用到TMOD时,先立即回忆图表,并根据缩写的单词原形理出每位的意义,如果意义不是很清楚,就查下手册,几次下来,TMOD的图表就已经在脑子里了。

8位 GATE位,本身是门的意思。
7位 C/T    Counter/Timer
6位 M1         Mode 1
5位 M0         Mode 0

TCON: 定时器/计数器控制寄存器(TIMER/COUNTER CONTROL REGISTER)

TMOD分成2段,TCON控制更加精细,分成四段,在本文中只要用到高四段。

TF0(TF1)——计数溢出标志位,当计数器计数溢出时,该位置1。
TR0(TR1)——定时器运行控制位
当TR0(TR1)=0  停止定时器/计数器工作
当TR0(TR1)=1  启动定时器/计数器工作
IE0(IE1)——外中断请求标志位

当CPU采样到P3.2(P3.3)出现有效中断请求时,此位由硬件置1。在中断响应完成后转向中断服务时,再由硬件自动清0。

IT0(IT1)——外中断请求信号方式控制位
当IT0(IT1)=1 脉冲方式(后沿负跳有效)
当IT0(IT1)=0 电平方式(低电平有效)此位由软件置1或清0。
TF0(TF1)——计数溢出标志位

当计数器产生计数溢出时,此位由硬件置1。当转向中断服务时,再有硬件自动清0。计数溢出的标志位的使用有两种情况:采用中断方式时,作中断请求标志位来使用;采用查询方式时,作查询状态位来使用。

注意记忆方法,理解单词原形,就绝对不会把TF和TR搞混。TF的F也就是溢出Over Flow的F。国外有个著名的IT知识问答社区,网址就stackoverflow点com
TR的R就是运行Run。默认是0不运行,当然要置1才运行。


STC单片机STC89C52RC定时器延时时间的计算

延时时间要根据晶振频率计算,不同板子可能有所不同。

时钟周期:
1/时钟源,在我现在这块板子上,晶振频率是11.0592M,也就是时钟周期是 1/11059200秒

机器周期:
一般51单片机是12个时钟周期,我的板子也就是 12/11059200秒

单次定时最长时间:
如果是16位的计数器,16位最大值是65535,共可计数65536次。基本的常数一定要记住,还要记住8位最大值是255,共可计数256次,还要记住8位上每位代表的数值。
12 * 65536/11059200 = 0.0711 s,也就是,71 ms内的定时可以单次定时就完成。如果定时时间超过71 ms,就要循环了。

一次定时需要几次机器周期:
计算公式:定时秒数/机器周期
比 如我要定时1秒, 1/(12/11059200)= 921600次,16位计数器最大可计数65536次,921600次早就益出了。我们可以每次定时10 ms,循环100次就可以定时1秒了,1 s缩小100百倍就是10 ms, 也就是每次需要计数9216次。

确实计数器初始值:
定时10 ms时,如果计数器从0开始计数,我们就不知道什么时候到了9216次。所以应该计数了9216次,16位计数器最多计数95536次,然后就溢出,一溢出TCON的TF位就会置1,我们只要经常检测TF位就可以知道什么时候完成10ms的定时了。
计算公式:计数器初始值=最大计数次数 - 需要计数次数
如果定时10 ms,计数器的初始值就是 65536 - 9216

计算计数器的高位和低位:
16位的计数器,也就是两个8位组成,8位的最大计数次数是256。所以:
计数器高位 = 初始值/256
计数器低位 = 初始值%256


STC89C52RC单片机定时器示例代码:

#include <reg52.h>

//如果你的单片机没用74hc138扩展IO口,下面代码可略
sbit enableG1 = P1^3;
sbit enableG2 = P1^4;
sbit selectC  = P1^2;
sbit selectB  = P1^1;
sbit selectA  = P1^0;
void hc138()
{
         enableG1 = 1;
         enableG2 = 0;
         selectC  = 1;
         selectB  = 1;
         selectA  = 0;
}


typedef unsigned char uint8;
typedef unsigned int uint16;


/**
    1ms需要的机器周期 = 0.001/(12/11059200) = 921.6   
    要让led灯以7.83hz闪动, 周期是 1000 / 7.83 = 127.713 ms, 也就是每64 ms改变亮灭状态
**/
void main(void)
{   
    uint16 counter;

    hc138();

    TMOD = 0X01;
    TH0  = (65536 - 922) / 256;
    TL0  = (65536 - 922) % 256;
    TR0  =1;

    while(1)
    {
         if(TF0 == 1)
        {
            TF0 = 0;
            TH0  = (65536 - 922) / 256;
            TL0  = (65536 - 922) % 256;
            counter++;
        }

        if(counter == 64)
        {
             counter = 0;
            P0 = ~P0;
        }
    }
}
回复

使用道具 举报

ID:152374 发表于 2016-12-9 23:27 | 显示全部楼层
我来学习学习,巩固巩固知识。
回复

使用道具 举报

ID:126826 发表于 2017-11-22 22:01 | 显示全部楼层
你好,我是初学者,我对这句话很疑惑,为什么一开始要判断TF0==1,难道TF0的初始值就是1吗?
谢谢!
  if(TF0 == 1)
回复

使用道具 举报

ID:201936 发表于 2017-11-23 08:39 | 显示全部楼层
谢谢楼主,这个对我有用
回复

使用道具 举报

ID:262591 发表于 2017-12-17 12:42 | 显示全部楼层
wzg1103 发表于 2017-11-22 22:01
你好,我是初学者,我对这句话很疑惑,为什么一开始要判断TF0==1,难道TF0的初始值就是1吗?
谢谢!
  if( ...

if(TF0 == 1)就是溢出一次,然后再归零循环。循环64次就是64ms,1000次就是1s
回复

使用道具 举报

ID:262477 发表于 2017-12-17 15:08 | 显示全部楼层
不错,受教了,感觉中断和串口是最难的。
回复

使用道具 举报

ID:272625 发表于 2018-1-8 22:30 | 显示全部楼层
很好,谢楼主小白学习了
回复

使用道具 举报

ID:262591 发表于 2018-1-9 10:15 来自手机 | 显示全部楼层
原来51计时精度是可选的,烧录的时候选择6T就是6分频,最小计时单位就是0.5us。如果追求高精度计时可以选6T,然后按照时间寄存器1个单位=6/f推算起始位置,这样就能够做出来高精度的pwm了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表