C51_定时器 / 计数器

机器周期与时钟周期

  • 时钟周期即晶振的振荡周期
  • 机器周期是指单片机执行一步操作所需的最短时间。在C语言中,执行一行代码所需的时间是不确定的,因此造成了前面所提到的软件延时函数不精确的问题

定时器 / 计数器的工作原理

  • 定时器 / 计数器所有累加操作均通过计数寄存器实现,这些寄存器都属于特殊功能寄存器,单片机通电复位后其初值均为0。
  • 其中,TH0与TL0分别为定时器 / 计数器0计数值的高位和低位
  • 在定时器 / 计数器运行之前,需要为计数寄存器赋计数初值
TH0 = 0xFC;
TH0 = 0x18;
  • 一旦定时器 / 计数器0开始工作,则从设定的计数器初值开始,每接收到1个脉冲后计数值加1
  • 当计数寄存器的高位与低位计满至0xFFFF时,再接收1个脉冲信号后定时器溢出,产生中断请求,并自动清零。清零后,需要再次设置计数初值,使定时器 / 计数器能在下一次记数周期中计算相同的脉冲信号

定时器 / 计数器系统框架

定时 / 计数功能的选择

定时器 / 计数器的控制运行

工作模式与计数初值

  • 工作模式0

    • 设置工作模式 TMOD = 0x00;
    • 将0x1C18取低5位即为TL0取值
    TH0 = 0x1C18 >> 5;
    TL0 = 0x1C18 & 0x1F;
    
    • 最后打开定时器 TR0 = 1;
  • 工作模式1

  • 工作模式2

  • 工作模式3

定时器 / 计数器中断

  • 中断请求标志位
  • 中断允许控制位
  • 中断优先级控制

实例与代码解析

  1. 包含头文件 #include <reg52.h>
  2. 位定义LED1 sbit LED1 = P2 ^ 4; // 定义LED1
  3. 编写中断配置函数
static void InitInterrupt()
{
    ET0 = 1; // 打开定时器 / 计数器0的中断允许
    EA = 1; // 打开总中断允许
}
  1. 编写计数器0配置函数
static void InitTimer0()
{
    TMOD = 0x05; // 设置计数器0为工作模式1(16位计数器)
    TH0 = 0xFF; // 设置计数器0计数初值的高8位
    TL0 = 0xFD; // 设置计数器0计数初值的低8位,记数至3后溢出
    TR0 = 1; // 打开计数器
}
  1. 编写主函数
void main()
{
    InitInterrupt(); // 配置中断
    InitTimer0(); // 配置计数器0
    while (1)
    {
        
    }
}
  1. 编写中断服务函数
void Timer0_Handler() interrupt 1
{
    TH0 = 0xFF; // 重新设置计数器0计数初值的高8位
    TL0 = 0xFD; // 重新设置计数器0计数初值的低8位,记数至3后溢出
    LED1 = ~LED1; // 翻转LED1的亮灭状态
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值