STC8单片机计数器/定时器原理及实现

概述

共同点与区别

  • 共同点:对脉冲进行计数
  • 区别:如果计数脉冲来自系统时钟,则为定时;如果计数脉冲来自外部引脚,则为计数。

定时器/计数器的工作模式

  • 定时器/计数器T0有4种工作模式
    • 模式0(16位自动重新加载模式)
    • 模式1(16位不可重加载模式)
    • 模式2(8位自动重加载模式)
    • 模式3(不可屏蔽中断的16位自动重加载模式)
  • 定时器/计数器T1有3种工作模式
    • 模式0(16位自动重新加载模式)
    • 模式1(16位不可重加载模式)
    • 模式2(8位自动重加载模式)
  • 定时器/计数器T2有1种工作模式
    • 模式0(16位自动重新加载模式)
  • 定时器/计数器T3有1种工作模式
    • 模式0(16位自动重新加载模式)
  • 定时器/计数器T4有1种工作模式
    • 模式0(16位自动重新加载模式)

定时器/计数器寄存器组

定时器/计数器T0和T1控制寄存器TCON

  • 作用:用于控制定时器/计数器T0和T1,同时锁存T0和T1溢出中断源和外部请求中断源等
  • 寄存器地址:sfr 0x88
  • 复位值:0000 0000B

TCON寄存器
TCON寄存器

定时器/计数器T0和T1工作模式寄存器TMOD

  • 作用:用于工作模式的选择
  • 寄存器地址:sfr 0x89
  • 复位值:0000 0000B

TMOD寄存器
TMOD寄存器

TH1和TL1
  • 作用:用于保存定时器/计数器T1的计数初值
  • 寄存器地址:sfr 0x8D和0x8B
  • 复位值:均为0000 0000B

TH1和TL1寄存器

TH0和TL0
  • 作用:用于保存定时器/计数器T0的计数初值
  • 寄存器地址:sfr 0x8C和0x8A
  • 复位值:均为0000 0000B

TH0和TL0寄存器

辅助寄存器AUXR

  • 作用:用于控制定时器的分频
  • 寄存器地址:sfr 0x8E
  • 复位值:0000 0001B

辅助寄存器AUXR
辅助寄存器AUXR
辅助寄存器AUXR

TH2和TL2
  • 作用:用于保存定时器/计数器T2的计数初值
  • 寄存器地址:sfr 0xD6和0xD7
  • 复位值:均为0000 0000B

TH2和TL2寄存器

T0~T2时钟输出寄存器和外部中断允许INT_CLKO(AUXR2)寄存器

  • 作用:用于控制是否允许定时器中断
  • 寄存器地址:sfr 0x8F
  • 复位值:x000 x000B

AUXR2寄存器
AUXR2寄存器
AUXR2寄存器
AUXR2寄存器

定时器计数器T3和T4控制寄存器T4T3M

  • 作用:用于控制T3和T4的工作模式
  • 寄存器地址:sfr 0xD1
  • 复位值:0000 0000B

T4T3M寄存器
T4T3M寄存器
T4T3M寄存器

TH4和TL4
  • 作用:用于保存定时器/计数器T4的计数初值
  • 寄存器地址:sfr 0xD2和0xD3
  • 复位值:均为0000 0000B

TH4和TL4寄存器

TH3和TL3
  • 作用:用于保存定时器/计数器T3的计数初值
  • 寄存器地址:sfr 0xD4和0xD5
  • 复位值:均为0000 0000B

TH3和TL3寄存器

定时器中断控制寄存器

注: 参见前面中断章节

工作模式原理及实现

定时器/计数器T0工作模式

模式0(16位自动重加载模式)
原理图:

模式0原理图

实验程序:
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
35
36
37
/*
实验使用开发板:松果派
实验目的:定时器/计数器T0自动加载模式生成1Hz的时钟,
使得LED小灯随着这个频率闪烁,观察现象
版权:Www.ByteMoe.Com
*/
#include "reg51.h"

#define TIME0 3036 //定时器/计数器初值
//声明CLKDIV寄存器XSFR地址
#define CLKDIV (*(unsigned char volatile xdata *)0xfe01)
sfr AUXR=0x8E;//声明AUXR寄存器SFR地址
sfr AUXR2=0x8F;//声明AUXR2寄存器SFR地址
sfr P5=0xC8;//声明P5端口的SFR地址
sbit PNP_T=P5^5;//原理图中PNP三极管控制管脚用
sfr P_SW2=0xBA;//声明P_SW2寄存器的SFR地址

void timer_0()interrupt 1
{
P1=~P1;//P1端口的所有位取反(8个LED状态取反)
}
void main()
{
P_SW2=0x80; //将P_SW2寄存器的最高位EAXFR置1,访问XSFR
CLKDIV=0x10; //CLK_DIV=16,将主时钟16分频后作为SYSclk
P_SW2=0x80; //将P_SW2寄存器的最高位EAXFR置0,访问SFR
TL0=TIME0;//TIME0的低8位给定时器计数初值寄存器TL0
TH0=TIME0>>8;//TIME0的高8位给定时器计数初值寄存器TH0
/*按位与有0一定为0,其余保持原样;按位或有1一定为1,其余保持原样*/
AUXR&=0x7F;//AUXR最高位置0,SYSclk/12作定时器时钟
AUXR2|=0x01;//AUXR2最低位置1,P3.5端口输出为16位自动重载
P1=0;//设置P1端口初值为0,灯亮
TR0=1;//启动定时器/计数器T0
ET0=1;//使能定时器/计数器T0
EA=1;//使能CPU全局中断,允许中断请求
while(1);//无限循环
}
源代码附件下载:

注:由于我亲爱的单片机爆炸了,更新被迫暂时中止,此篇未更新完成