51单片机:定时/计数器

STC89C52RC 的定时/计数器是单片机内部非常重要的可编程资源。它的核心是一个 16位加1计数器,通过选择不同的计数脉冲来源,可以分别实现"定时"和"计数"两种看似相反、但原理相通的功能。

1.TMOD

TMOD 是工作方式寄存器,地址为 89H,不可位寻址,需要整体赋值。TMOD 的高 4 位控制 T1,低 4 位控制 T0。其中 TMOD.7 和 TMOD.3 是 GATE 门控位:当 GATE=0 时,软件置 TRx=1 即可启动定时/计数器;当 GATE=1 时,除了 TRx=1 外,还需要 INTx 引脚为高电平才能启动,常用于测量脉宽。TMOD.6 和 TMOD.2 是 C/T 位:C/T=0 为定时模式,C/T=1 为计数模式。

TMOD.5 和 TMOD.4 以及 TMOD.1 和 TMOD.0 分别是 T1 和 T0 的 M1、M0 位,用来选择工作方式 0 到 3。

定时器和计数器共用同一套硬件,区别仅在于计数脉冲的来源:

2.TCON

TCON 是控制寄存器,地址为 88H,可位寻址,与定时器直接相关的有 4 位。TCON.7 和 TCON.5 分别是 TF1 和 TF0,即溢出标志位;计满溢出时硬件自动置 1,**进入中断后硬件自动清零,也可以由软件清零。**TCON.6 和 TCON.4 分别是 TR1 和 TR0,即运行控制位;软件置 TRx=1 启动计数,清 0 停止计数。

3.案例实现

STC89C52RC 的定时器有两种计数速率,在烧录程序时通过 STC-ISP 软件选择。12T 模式是默认模式,每 12 个时钟周期计数一次,与传统 8051 一致;6T 模式每 6 个时钟周期计数一次,计数速度是 12T 模式的两倍。以常见的 11.0592 MHz 晶振、12T 模式为例,机器周期等于 12 除以 11 059 200,约为 1.085 微秒,即每经过约 1.085 微秒,定时器加 1。

方式 1 的初值计算公式为:初值等于 65536 减去目标时间秒数乘以晶振频率再除以 12。例如,11.0592 MHz 晶振、12T 模式、定时 20 毫秒时,计数值等于 0.02 乘以 11 059 200 再除以 12,结果为 18432;初值等于 65536 减去 18432,得到 47104,即十六进制 0xB800,所以 TH0 写 0xB8,TL0 写 0x00。标准配置流程是:先写 TMOD,设定工作方式、定时或计数、门控;再写 THx 和 TLx,装入初值;然后置位 TRx,启动计数;最后处理溢出,可以查询 TFx 或使能中断。

下面给出一个完整示例:定时器 0 方式 1 查询方式在 P1.0 上产生 40 毫秒周期的方波,每 20 毫秒翻转一次电平。

cs 复制代码
#include <reg52.h>

void main(void)
{
    TMOD = 0x01;          // T0 方式1,定时模式,GATE=0
    TH0  = 0xB8;          // 20 ms 初值 @11.0592MHz, 12T
    TL0  = 0x00;

    TR0 = 1;              // 启动 T0

    while (1) 
    {
        if (TF0) // 查询溢出标志
        {        
            TF0 = 0;      // 软件清零
            TH0 = 0xB8;   // 方式1必须软件重装初值
            TL0 = 0x00;
            P1_0 = ~P1_0; // 翻转 P1.0,形成方波
        }
    }
}

如果改用中断方式,则需要在初始化中使能 ET0=1 和 EA=1,溢出后硬件自动清零 TF0,在中断服务函数中重装初值并执行翻转操作。

cs 复制代码
#include <reg52.h>

void Timer0_ISR(void) interrupt 1  // 1 对应定时器0
{
    // 清除标志位(定时器0硬件通常自动清除,此处为逻辑严谨可手动处理)
    TH0 = 0xB8;   // 方式1必须软件重装初值
    TL0 = 0x00;
    P1^0 = ~P1^0; // 翻转 P1.0,形成方波
}

void main()
{
    EA = 1;    // 打开总中断(关键步骤)
    ET0 = 1;   // 打开定时器0中断
    // ... 初始化定时器0(TMOD, TH0, TL0)并启动(TR0=1)
    TMOD = 0x01;          // T0 方式1,定时模式,GATE=0
    TH0  = 0xB8;          // 20 ms 初值 @11.0592MHz, 12T
    TL0  = 0x00;

    TR0 = 1;              // 启动 T0

    while (1);
  
}
相关推荐
杯子不吃紫菜3 小时前
LangGraph 体系实战(下):中断恢复、流式、子图与设计模式
单片机·嵌入式硬件·设计模式
Risehuxyc3 小时前
STM32程序逻辑---入口函数逻辑和NVIC嵌套向量中断控制器初始化
stm32·单片机·嵌入式硬件
【 STM32开发 】4 小时前
CubeMX+STM32】SD卡U盘实现__USB+FATFS (F103 篇)
stm32·单片机·嵌入式硬件
jianqiang.xue4 小时前
3倍向量算力:Arm给最小MCU装上本地AI
arm开发·人工智能·单片机
无敌最俊朗-18 小时前
【电感专题2:电感的感抗、电路的阻抗、电流的滞后】
单片机·嵌入式硬件·元器件·电感
wuyk5551 天前
嵌入式故障诊断-Bug002-局部大数组压栈高温必死机
stm32·单片机·嵌入式硬件·mcu·物联网·51单片机·嵌入式实时数据库
Zwawa1 天前
嵌入式OLED表驱动菜单:用一张表、一个栈和一个窗口重写表驱动菜单
c语言·单片机·嵌入式
Dev_XH1 天前
【成品设计】基于沁恒单片机的电动汽车充电站智慧调度系统
stm32·单片机·嵌入式硬件·物联网
minglie11 天前
esp32c3+atshell测试ov7670
单片机·嵌入式硬件