一、定时器/计数器
1.1 定时器/计数器概述
51单片机有两个内置定时器/计数器。
当记数脉冲来自于外部输入时,为计算器。而来自于系统时钟时,为定时器。
定时器0有四种模式。定时器1支持三种模式,可以被用来产生波特率。
PCON寄存器里的SMOD0位表示每12时钟或者每6时钟产生一次计数脉冲。
1.2 TCON寄存器
bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|
name | TF1 | TR1 | TR0 | TF0 | TR0 | IE1 | IT1 | IE0 |
TF0和TF1为定时器溢出位、TR0和TR1为运行控制位、其他位用于外部中断。
TR0和TR1:
分别控制定时器0和1的运行,该位置1时才允许定时器计数,清0时停止计数。
TF0和TF1
定时器溢出后自动置1,在系统响应定时器中断后清0,也可以由软件手工清0。
1.3 TMOD寄存器
bit | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 |
---|---|---|---|---|---|---|---|---|
name | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
高四位用于控制定时器1,低四位用于控制定时器0
GATE:
该位置1时,定时器的运行有额外的条件,当外部中断输入引脚为为高电平时,才能继续计数。
C/T:
该位置1时,T0和T1做计数器用。置0时,做定时器。
M1、M0:
用于指定定时器工作模式。
M1 = 0;M0 = 0;时,定时器运行模式为0,此模式是为了兼容8048单片机。
M1 = 0;M0 = 1;时,定时器运行模式为1,16位定时器。
M1 = 1;M0 = 0;时,定时器运行模式为1,8位自动重装定时器。
M1 = 1;M0 = 1;时,定时器运行模式为1,双8位定时器,定时器1不支持此模式。
1.4 计算定时时长
假设当前设置为12系统时钟产生一个计数脉冲。
8位定时器从运行到溢出的时间为(系统时钟 X 12)X(256 - 定时器初值)。
16位定时器从运行到溢出的时间为 (系统时钟 X 12) X (65536 - 定时器初值)。
波特率为定时器1的溢出速率/32。
二、编程示例
2.1 定时一秒
#include <8051.h>
#define FOSC 12000000L
#define T50MS (65536-FOSC/12/20000)
volatile unsigned char count = 0;
void timer0_isr __interrupt (1)
{
TL0 = T50MS;
TH0 = T50MS>>8;
if (count-- == 0) {
count == 20;
P1 = ~P1;
}
}
void main()
{
TMOD = 0x01;
TL0 = T50MS;
TH0 = T50MS >> 8;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1);
}
2.2 产生9600波特率
#include <8051.h>
#define FOSC 12000000L
#define BAUD 9600
void uart_init(void)
{
...
TL1 = (65536-(FOSC/384/BAUD));
TH1 = (65536-(FOSC/384/BAUD)) >> 8;
...
}