# 1.中断简介


51单片机里面有5个中断源：

- 两个外部中断
- 两个定时器中断
- 一个串口中断



## 中断类型

| 中断源名称    | 类型号 | 默认优先级 |
| ------------- | ------ | ---------- |
| 外部中断0     | 0      | 最高       |
| 定时/计数器T0 | 1      | 第2        |
| 外部中断1     | 2      | 第3        |
| 定时/计数器T1 | 3      | 第4        |
| 串口中断      | 4      | 第5        |

## IE寄存器

中断控制寄存器

| 位序 | D7   | D6   | D5   | D4   | D3   | D2   | D1   | D0   |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 位名 | EA   | --   | --   | ES   | ET1  | EX1  | ET0  | EX0  |

- EA位：全局中断允许控制位，EA = 0时，禁止所有中断
- ES位：串口接收中断使能
- EX位：外部中断允许位，EX = 0时，禁止外部中断
- ET位：定时/计数允许位，ET = 0时，禁止定时/计数器中断

## IP寄存器

中断优先级寄存器

## TCON寄存器

主要用于控制定时/计数器、中断的启动与停止、标示定时器的溢出和中断的情况。

| 位序 | D7   | D6   | D5   | D4   | D3   | D2   | D1   | D0   |
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
| 位名 | TF1  | TR1  | TF0  | TR0  | IE1  | IT1  | IE0  | IT0  |

### TF位

定时/计数器溢出中断位，这个位一般不需要人为操作。当定时/计数器溢出时，硬件自动将这个位置1，并向CPU发出中断指令，CPU进入中断服务程序的时候，自动清除该位。

### TR位

定时/计数器使能位。

- 0：停止计数
- 1：启动计数

### IE位

外部中断请求标志位，这个位一般不需要人为操作。当外部中断无中断请求时，IE=0；当外部中断有中断请求时，IE=1.在CPU响应该中断后，由硬件自动将IE清零

### IT位

外部中断的触发方式。
0：低电平触发
1：下降沿触发

# 定时/计数器

51单片机中有两个定时/计数器T1和T0，有以下相关寄存器：

- TH：高8位定时/计数器。有TH1和TH0两个
- TL：低8位定时/计数器。有TL1和TL0两个
- TMOD：工作方式选择寄存器
- TCON：控制寄存器

## TMOD寄存器

用于配置定时器的工作模式，作用如下：

1. 设置定时器是软件启动还是硬件启动
2. 设置T0、T1的工作方式
3. 设置T0或T1是用做计数器还是定时器
    位定义如下(高4位为T1，低4位为T0)：

| 位序 | D7   | D6               | D5   | D4   | D3   | D2               | D1   | D0   |
| ---- | ---- | ---------------- | ---- | ---- | ---- | ---------------- | ---- | ---- |
| 位名 | GATE | $C/ \overline T$ | M1   | M0   | GATE | $C/ \overline T$ | M1   | M0   |

> 注意
> 如果只使用T1，建议TMOD低4位都置0

### GATE

门控位。用于选择定时/计数器的启动方式。
定时/计数器的启动方式有两种，位设置如下:

- 0：软启动，通过配置TCON寄存器中的TR位直接启动
- 1：硬启动，通过外部中断启动。
    注意：
- 硬启动之前，也需要配置TCON寄存器中的TR位。
- 外部中断引脚为INT0(P3.2)和INT1(P3.3)
- 外部中断启动条件为置“1”

### $C/ \overline T$ {#c-overline-t}

功能选择位。用于选择定时/计数器的脉冲源。
脉冲源有两种，位设置如下：

- 0：内部脉冲，单片机内部提供一个12分频的时钟脉冲
- 1：外部脉冲

### M1、M0

定时/计数器工作方式选择位，含义如下表：

| M1   | M0   | 工作方式 | 功能说明                  |
| ---- | ---- | -------- | ------------------------- |
| 0    | 0    | 方式0    | 13位                      |
| 0    | 1    | 方式1    | 16位                      |
| 1    | 0    | 方式2    | 8位自动重载               |
| 1    | 1    | 方式3    | T0分为两个8位；T1停止计数 |

## 工作方式

TMOD寄存器可以设置定时/计数器的工作方式。工作方式有4种：

- 方式0：13位
- 方式1：16位
- 方式2：8位自动重载
- 方式3：T0分为两个8位；T1停止计数

### 方式0

定时/计数器为13位定时/计数方式，它由TL的低5位和TH的全部8位构成13位的计数器，此时TL的高3位为无效位：

<div>
<table border="1">
  <tr>
    <th colspan="8">TH</th>
    <th colspan="8">TL</th>
  </tr>
  <tr>
    <td>D12</td>
    <td>D11</td>
    <td>D10</td>
    <td>D9</td>
    <td>D8</td>
    <td>D7</td>
    <td>D6</td>
    <td>D5</td>
    <td> *</td>
    <td> *</td>
    <td> *</td>
    <td>D4</td>
    <td>D3</td>
    <td>D3</td>
    <td>D1</td>
    <td>D0</td>
  </tr>
</table>

</div>

当定时/计数器开始工作时，每经过一个机器周期就往TL里加1，当TL溢出的时候TH加1，直到TH溢出引发中断，然后停止定时或者计数。
如果想要重新定时或者计数，需要手动重置TH和TL寄存器。
13位最大计数次数为8192次，下表是晶振与计数时间的关系：

| 晶振    | 单个周期时间 | 总时间      |
| ------- | ------------ | ----------- |
| 12MHz   | 1μs          | 8192μs      |
| 11.0592 | 约1.085μs    | 约8888.89μs |

假设需要定时的时间长度为t(μs),晶振频率为f(MHz)，定时器初始值count计算公式如下：

$$
count=2^{13}- \frac {tf}{12}
$$

由于TL寄存器高三位未被使用，所以要将count拆开低五位到TL，剩下的位放到TH：



$$
\begin{cases}TH=count >> 5 \\ TL=count \& 0x1F \end{cases}
$$






### 方式1

定时/计数器为16位定时/计数方式，原理和工作方式一致：

<body>

<table border="1">
  <tr>
    <th colspan="8">TH</th>
    <th colspan="8">TL</th>
  </tr>
  <tr>
    <td>D15</td>
    <td>D14</td>
    <td>D13</td>
    <td>D12</td>
    <td>D11</td>
    <td>D10</td>
    <td>D9</td>
    <td>D8</td>
    <td>D7</td>
    <td>D6</td>
    <td>D5</td>
    <td>D4</td>
    <td>D3</td>
    <td>D3</td>
    <td>D1</td>
    <td>D0</td>
  </tr>
</table>

</body>

当定时/计数器开始工作时，每经过一个机器周期就往TL里加1，当TL溢出的时候TH加1，直到TH溢出引发中断，然后停止定时或者计数。
如果想要重新定时或者计数，需要手动重置TH和TL寄存器。
16位最大计数次数为65536次，下表是晶振与计数时间的关系：

| 晶振    | 单个周期时间 | 总时间       |
| ------- | ------------ | ------------ |
| 12MHz   | 1μs          | 65536μs      |
| 11.0592 | 约1.085μs    | 约60397.98μs |

假设需要定时的时间长度为t(μs),晶振频率为f(MHz)，定时器初始值count计算公式如下：

$$
count=2^{16}- \frac {tf}{12}
$$

由于TL寄存器高三位未被使用，所以要将count拆开低五位到TL，剩下的位放到TH：



$$
\begin{cases}TH=count >> 8 \\ TL=count\&0xFF\end{cases}
$$



