定时计数器

定时/计数器

  1. 51 单片机中有两个 16 位的定时计数器。
  2. 每个 16 位的定时计数器最大计算能力位:65536(2^16)
  3. 分类
    • 加计数器:计数初值 = 最大计数值 - 计数值。
    • 减计数器:计数初值 = 计数值。
  4. 工作模式
    • 定时模式
    • 计数模式
  5. 工作方式:方式 0 ~ 方式 3
    • 方式 0:13 位
    • 方式 1:16 位
    • 方式 2:8 位,自动载入初值
    • 方式 3:8 位

操作步骤

设置工作模式

  1. TMOD 寄存器结构图

    • GATE:门控信号。0-软件开启 1-硬件开启
    • C/~T:0-定时模式 1-计数模式
    • M1:M0:00、01、10、11 设置 4 种工作方式。
    • TMOD 不支持位寻址。
  2. TMOD 寄存器设置 T0 为软件开启,工作在计时模式,工作方式是方式1。

写入计数初值

  1. 计数初值较大,需要用两个 8 位寄存器存储。

  2. 借助 TH0、TL0、TH1、TL1 寄存器完成初值的存储。

开启

  1. 通过 TCON 寄存器的高 4 位完成软开启工作。

  2. TCON 寄存器结构图

    • TR0:T0 的软开关。0-关闭 1-开启
    • TF0:T0 的溢出标识位。0-正常 1-计数结束。
    • TR1/TF1 同上。

查询法

  1. 设计并开启一个软开启的计数器 T0,工作方式为方式1,计数值为 3000。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include <STC12C5A60S2.H>

    void init(void) {
    TMOD = 0x05;
    TH0 = (65536 - 3000) / 256;
    TL0 = (65536 - 3000) % 256;
    TR0 = 1;
    }

    void main(void) {
    init();
    }
  2. 设计并开启一个软开启的计数器 T0,工作方式为方式1,计数值为 3。用计数器控制 LED 的亮灭。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #include <STC12C5A60S2.H>
    sbit LED = P1 ^ 0;

    void init(void) {
    LED = 1;
    TMOD = 0x05;
    TH0 = (65536 - 3) / 256;
    TL0 = (65536 - 3) % 256;
    TR0 = 1;
    }

    void main(void) {
    init();
    while (1) {
    if (TF0) {
    TR0 = TF0 = 0;
    TH0 = (65536 - 3) / 256;
    TL0 = (65536 - 3) % 256;
    LED = ~LED;
    TR0 = 1;
    }
    }
    }

定时计数器中断

  1. 触发条件:当定时计数器完成工作后回出发定时计数器中断。

  2. 中断处理子函数执行完后,CPU 自动将 TF0/TF1 自动清零。

  3. 开启中断 —— IE 寄存器

    • EA:中断总开关
    • ES:串型中断
    • ET1:定时计数器 1 中断开关
    • EX1:外部中断 1 开关
    • ET0:定时计数器 0 中断开关
    • EX0:外部中断 0 开关
  4. 中断处理子函数:文档

    1
    2
    3
    void timer0(void) interrupt 1 {
    ……
    }
  5. 例:通过定时计数器中断控制 LED 的亮灭。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    #include <STC12C5A60S2.H>
    typedef unsigned int UI;
    typedef unsigned char UC;

    sbit LED = P1 ^ 0;

    void storageInitValue() {
    TR0 = 0;
    TH0 = (65536 - 50000) / 256;
    TL0 = (65536 - 50000) % 256;
    TR0 = 1;
    }

    // 初始化
    void init() {
    LED = 1;
    EA = 1;
    ET0 = 1;
    TMOD = 0x01;
    storageInitValue();
    }

    void main() {
    init();
    while(1);
    }

    // 定时计数器 0 中断处理子函数
    void testTime0() interrupt 1 {
    static UC count = 0;
    count = ++count % 10;
    if (count) storageInitValue();
    else LED = ~LED;
    }

时基

  1. 时基:时间基础。
  2. 时基值取决于时钟晶振的频率。
  3. 一个时基大小就是一个机器周期

总结

外部中断

  1. 开中断。IE 寄存器
  2. 设置中断请求信号类型。TCON 寄存器
  3. 中断处理子函数。关键字:interrupt

定时/计数器

  1. 设置工作模式。TMOD 寄存器
  2. 写入计数初值。TH0、TL0、TH1、TL1
  3. 启动。TCON 寄存器的高 4 位

定时/计数器中断

  1. 开中断。IE 寄存器
  2. 中断处理子函数。