51单片机定时器应用实战

实验目的

本实验旨在掌握51单片机定时器的配置和使用方法,实现精确的时间控制功能。通过实际案例,深入理解定时器的工作原理和应用技巧。具体目标包括:

定时器基础知识

1. 定时器结构

51单片机内置的定时器主要包含以下部分:

  • 定时器/计数器寄存器(TH、TL)
  • 模式寄存器(TMOD)
  • 控制寄存器(TCON)
  • 中断控制相关寄存器

定时器模式:

  • 模式0:13位定时器/计数器
  • 模式1:16位定时器/计数器
  • 模式2:8位自动重装定时器/计数器
  • 模式3:两个8位定时器/计数器

2. 定时计算

定时器计数值计算公式:

计数初值 = 65536 - (定时时间 × 晶振频率) / 12

例如:12MHz晶振,需要1ms定时:

计数初值 = 65536 - (0.001 × 12000000) / 12
计数初值 = 65536 - 1000 = 64536 (FC18H)

实验案例:精确定时控制LED闪烁

1. 硬件连接

本实验需要的硬件连接非常简单:

  • 将LED正极通过限流电阻连接到P1.0口
  • LED负极接地
  • 12MHz晶振连接到XTAL1和XTAL2

2. 程序实现

#include <reg51.h>

sbit LED = P1^0;    // LED连接到P1.0口
bit flag = 0;       // LED状态标志位

// 定时器0中断服务函数
void Timer0_ISR() interrupt 1 {
    TH0 = 0xFC;    // 重装初值高字节
    TL0 = 0x18;    // 重装初值低字节
    flag = !flag;   // 翻转标志位
    LED = flag;     // 控制LED
}

// 定时器0初始化函数
void Timer0_Init(void) {
    TMOD &= 0xF0;   // 清零T0的控制位
    TMOD |= 0x01;   // 设置T0为模式1(16位定时器)
    
    TH0 = 0xFC;     // 1ms定时值
    TL0 = 0x18;
    
    ET0 = 1;        // 使能T0中断
    EA = 1;         // 使能总中断
    TR0 = 1;        // 启动定时器0
}

void main() {
    Timer0_Init();  // 初始化定时器0
    
    while(1) {
        // 主循环中可以执行其他任务
    }
}

代码说明:

  • 使用定时器0,工作在模式1(16位定时器模式)
  • 通过中断服务程序实现LED状态翻转
  • 定时时间为1ms,使用12MHz晶振
  • 主循环可以执行其他任务,不会被定时器占用

3. 关键点解析

定时器配置步骤:

  1. 配置TMOD寄存器,选择工作模式
  2. 计算并设置定时初值(TH0、TL0)
  3. 配置中断使能
  4. 编写中断服务程序
  5. 启动定时器

注意事项:

  • 中断服务程序要尽量简短
  • 注意重装初值的时机
  • 避免在中断中���行耗时操作

实验扩展

1. 多定时器应用

51单片机有Timer0和Timer1两个定时器,可以同时使用:

// Timer1中断服务函数
void Timer1_ISR() interrupt 3 {
    TH1 = 0xFC;    // 1ms定时
    TL1 = 0x18;
    // 其他任务
}

// 初始化两个定时器
void Timer_Init(void) {
    // Timer0配置(同上)
    TMOD |= 0x10;   // 设置Timer1为模式1
    TH1 = 0xFC;
    TL1 = 0x18;
    ET1 = 1;        // 使能Timer1中断
    TR1 = 1;        // 启动Timer1
}

2. 实用功能示例

  • 数码管动态显示时钟
  • PWM输出控制
  • 按键消抖
  • 串口波特率产生

实验思考

  1. 如何实现更长时间的定时?
  2. 定时器如何配合PWM实现呼吸灯效果?
  3. 如何使用定时器实现精确的串口波特率?
  4. 多个定时器同时使用时需要注意什么?
返回文章列表