8051 微控制器 · 硬件手册 51单片机零基础训练营
4316A–8051–01/04 · 中文

ATMEL · 8-BIT MICROCONTROLLER · HARDWARE MANUAL · 中文翻译版

8051 硬件手册

Atmel 8051 微控制器硬件特性全面说明:C51 指令集、特殊功能寄存器、振荡器与 CPU 时序、端口结构、外部存储器访问、定时器 0/1/2、串行接口与中断系统。

原文:Atmel 8051 Microcontrollers Hardware Manual · 文档编号 4316A–8051–01/04
覆盖:指令集 / SFR / 端口 / 定时器 / UART / 中断

8位CPU 数据宽度
4个双向 I/O 端口
3×16定时器 / 计数器
4模式串行口工作方式
6源中断向量 · 两级优先级
12Tcy标准机器周期

1.1程序状态字(PSW)

8051 指令集面向 8 位控制应用优化,提供多种快速寻址方式访问内部 RAM,便于对小型数据结构做字节操作;同时把位变量作为独立数据类型提供完整支持,可在需要布尔处理的控制与逻辑系统中直接对位进行操作。

程序状态字(PSW)位于 SFR 空间,包含若干反映 CPU 当前状态的标志位:进位位、辅助进位位(用于 BCD 运算)、两个寄存器组选择位、溢出标志、奇偶标志,以及两个用户自定义状态标志。

进位位除了在算术运算中承担进位功能外,还作为若干布尔运算的“累加器”使用。RS0、RS1 用于从下面四组寄存器中选择一组;多条指令把这些 RAM 单元记作 R0~R7,执行时依据 RS0/RS1 决定引用哪一组。

奇偶标志反映累加器中 1 的个数:累加器含奇数个 1 时 P = 1,含偶数个 1 时 P = 0,因此累加器中 1 的个数加上 P 恒为偶数。PSW 中有两位未分配,可作为通用状态标志使用。

表 1-1PSW:程序状态字寄存器(MSB → LSB)

CY7
AC6
F05
RS14
RS03
OV2
—1
P0

地址 = D0H · 复位值 = 0000 0000B · 可位寻址

符号位位置名称与含义
CYPSW.7进位标志。
ACPSW.6辅助进位标志(用于 BCD 运算)。
F0PSW.5标志 0,可供用户作通用用途。
RS1PSW.4寄存器组选择控制位 1、0,由软件置位 / 清零以确定工作寄存器组(见下注)。
RS0PSW.3
OVPSW.2溢出标志。
—PSW.1保留位。
PPSW.0奇偶标志。每个指令周期由硬件置位 / 清零,指示累加器中“1”位的奇偶性(偶校验)。

注:(RS1, RS0) 选择工作寄存器组如下——(0,0) 组 0(00H–07H);(0,1) 组 1(08H–0FH);(1,0) 组 2(10H–17H);(1,1) 组 3(18H–1FH)。

1.2寻址方式

8051 指令集提供以下六种寻址方式。

直接寻址

直接寻址中,操作数由指令中的 8 位地址字段指定。只有内部数据 RAM 的最低 128 字节和 SFR 可以被直接寻址。

间接寻址

间接寻址中,指令指定一个寄存器,该寄存器中存放操作数的地址。内部 RAM 和外部 RAM 都可以间接寻址。8 位地址的地址寄存器可以是所选寄存器组中的 R0 或 R1,也可以是堆栈指针;16 位地址的地址寄存器只能是 16 位数据指针 DPTR。

寄存器指令

包含 R0~R7 的寄存器组可由某些指令访问,这些指令在操作码中携带 3 位寄存器编号。这种方式省去一个地址字节,代码效率高;执行时访问所选组中的八个寄存器之一,具体哪一组由 PSW 中的两个组选择位在执行时选定。

寄存器专用指令

有些指令专用于某个寄存器。例如部分指令始终对累加器或数据指针操作,因此无需地址字节指向它,操作码本身完成指定。把累加器记作 A 的指令汇编为累加器专用操作码。

立即数

常量值可以跟在程序存储器中的操作码之后。例如 MOV A, #100 把十进制数 100 装入累加器;同一数也可用十六进制写为 64H。

变址寻址

变址寻址只能访问程序存储器,且只能读不能写,用于读取程序存储器中的查表数据。16 位基址寄存器(DPTR 或程序计数器 PC)指向表首,累加器置为表项编号,程序存储器中的表项地址由累加器数据与基址相加形成。另一种变址寻址用于“散转”指令:跳转目的地址由基址指针与累加器数据相加得到。

1.3算术指令

算术指令清单见表 1-2,表中标出了每条指令访问 <byte> 操作数可用的寻址方式。例如 ADD A, <byte> 可写成:

ADD A,7FH ; 直接寻址 ADD A,@R0 ; 间接寻址 ADD A,R7 ; 寄存器寻址 ADD A,#127 ; 立即数

表 1-2Atmel 8051 算术指令(执行时间按 12 MHz 时钟、X1 模式计)

助记符操作寻址方式(DIR/IND/REG/IMM)执行时间 (µs)
ADD A, <byte>A = A + <byte>直接 / 间接 / 寄存器 / 立即1
ADDC A, <byte>A = A + <byte> + C直接 / 间接 / 寄存器 / 立即1
SUBB A, <byte>A = A − <byte> − C直接 / 间接 / 寄存器 / 立即1
INC AA = A + 1仅累加器1
INC <byte><byte> = <byte> + 1直接 / 间接 / 寄存器1
INC DPTRDPTR = DPTR + 1仅数据指针2
DEC AA = A − 1仅累加器1
DEC <byte><byte> = <byte> − 1直接 / 间接 / 寄存器1
MUL ABB:A = B × A仅 ACC 与 B4
DIV ABA = ⌊A/B⌋,B = A 除以 B 的余数仅 ACC 与 B4
DA A十进制调整仅累加器1

表中执行时间按 12 MHz 时钟、X1 模式估算:除 INC DPTR 为 2 µs、乘法与除法为 4 µs 外,其余算术指令均为 1 µs。内部数据存储器空间中的任意字节都可以不经过累加器直接增 1 或减 1。

有一条 INC 指令作用于 16 位数据指针。DPTR 用于为外部存储器产生 16 位地址,因此能在一次 16 位操作中递增它是很实用的特性。

MUL AB 将累加器与 B 寄存器中的数据相乘,16 位乘积放入拼接的 B 与累加器寄存器。DIV AB 用累加器除以 B 寄存器数据,8 位商留在累加器,8 位余数留在 B 寄存器。DIV AB 在算术“除法”例程中的使用反而少于进制转换与可编程移位操作:除以 2ⁿ 等价于右移 n 位,用 DIV AB 完成移位只需 4 µs,且被移出的位保留在 B 寄存器中。

DA A 用于 BCD 算术。BCD 运算中的 ADD、ADDC 之后都应紧跟一次 DA A,以保证结果仍为 BCD。注意 DA A 不会把二进制数转换成 BCD,它只有作为两个 BCD 字节相加的第二步时才有意义。

1.4逻辑指令

对字节执行布尔运算(与、或、异或、取反)的指令按位操作。例如累加器为 00110101B、<byte> 为 01010011B 时,ANL A,<byte> 使累加器得到 00010001B。

表 1-3Atmel 8051 逻辑指令(执行时间按 12 MHz、X1 模式计)

助记符操作寻址方式执行时间 (µs)
ANL A, <byte>A = A AND <byte>直接 / 间接 / 寄存器 / 立即1
ANL <byte>, A<byte> = <byte> AND A直接1
ANL <byte>, #data<byte> = <byte> AND #data直接2
ORL A, <byte>A = A OR <byte>直接 / 间接 / 寄存器 / 立即1
ORL <byte>, A<byte> = <byte> OR A直接1
ORL <byte>, #data<byte> = <byte> OR #data直接2
XRL A, <byte>A = A XOR <byte>直接 / 间接 / 寄存器 / 立即1
XRL <byte>, A<byte> = <byte> XOR A直接1
XRL <byte>, #data<byte> = <byte> XOR #data直接2
CLR AA = 00H仅累加器1
CPL AA = NOT A仅累加器1
RL AACC 左环移 1 位仅累加器1
RLC A带进位左环移仅累加器1
RR AACC 右环移 1 位仅累加器1
RRC A带进位右环移仅累加器1
SWAP A交换 A 内高低 nibble仅累加器1

不经过累加器,也可以对内部数据存储器空间中的任意字节执行布尔运算。例如 XRL P1, #0FFH 是翻转端口各位的快捷写法。若操作由中断触发,不使用累加器还能省去在服务例程中把它压栈的时间。

移位指令(RL A、RLC A 等)把累加器左移或右移 1 位:左环移时最高位滚入最低位位置,右环移时最低位滚入最高位位置。SWAP A 交换累加器内高低 nibble,在 BCD 处理中很有用。例如累加器中有一个已知小于 100 的二进制数,可用下面代码快速转成 BCD:

MOV B, #10 DIV AB SWAP A ADD A, B

除以 10 后,十位数字在累加器低 nibble,个位数字在 B 寄存器;SWAP 与 ADD 把十位移到累加器高 nibble、个位留在低 nibble。

1.5数据传送(内部 RAM)

表 1-4 列出可在内部存储器空间内搬移数据的指令及其可用寻址方式。12 MHz 时钟、X1 模式下,这些指令执行时间为 1 或 2 µs。

MOV <dest>, <src> 可在任意两个内部 RAM 或 SFR 单元之间传送数据,不必经过累加器。注意:数据 RAM 高 128 字节只能间接寻址,SFR 空间只能直接寻址。所有 8051 器件的堆栈都位于片内 RAM,且向上增长。

PUSH 指令先把堆栈指针(SP)加 1,再把字节压入堆栈。PUSH、POP 只用直接寻址识别要保存 / 恢复的字节,而堆栈本身通过 SP 寄存器间接访问。这意味着如果高 128 字节已实现,堆栈可以进入其中,但不能进入 SFR 空间。

表 1-4访问内部数据存储器空间的数据传送指令

助记符操作寻址方式执行时间 (µs)
MOV A, <src>A = <src>直接 / 间接 / 寄存器 / 立即1
MOV <dest>, A<dest> = A直接 / 间接 / 寄存器1
MOV <dest>, <src><dest> = <src>直接 / 间接 / 寄存器 / 立即2
MOV DPTR, #data16DPTR = 16 位立即数立即2
PUSH <src>SP 加 1;(SP) = <src>直接2
POP <dest><dest> = (SP);SP 减 1直接2
XCH A, <byte>ACC 与 <byte> 交换数据直接 / 间接 / 寄存器1
XCHD A, @RiACC 与 @Ri 交换低 nibble间接1

标准 8051 及其 ROMless 型号未实现高 128 字节;这些器件若 SP 指向高 128,压入的字节会丢失,弹出的字节不确定。

数据传送指令中有一条 16 位 MOV,可用于为程序存储器中的查表初始化 DPTR,或用于 16 位外部数据存储器访问。XCH A, <byte> 使累加器与被寻址字节交换数据;XCHD A, @Ri 类似,但只交换低 nibble。

以把 8 位 BCD 数右移两位为例:用直接 MOV 完成需 14 个代码字节、9 µs(12 MHz、X1 模式);改用 XCH 代码更短,速度接近快一倍。右移奇数位时需先执行一位移位;表 1-6 给出用 XCHD 把 BCD 数右移一位的例程,指针 R1、R0 先指向最后两个 BCD 数字所在的字节,循环结束后被移出的数字传播到 2AH,再移入累加器。

1.6外部 RAM 与查表

访问外部数据存储器的数据传送指令见表 1-7,只能使用间接寻址:可选用单字节地址 @Ri(Ri 为所选组的 R0 或 R1)或双字节地址 @DPTR。若外部 RAM 只有几 KB,用 16 位地址的缺点是 P2 口的全部 8 位都要用作地址总线;8 位地址则不必牺牲整个 P2 口。12 MHz 时钟(X1 模式)下这些指令均为 2 µs。所有外部数据 RAM 访问中,累加器始终是数据的目的或来源。

表 1-7访问外部数据存储器空间的数据传送指令

助记符操作地址宽度执行时间 (µs)
MOVX A, @Ri读外部 RAM @Ri 到 A8 位2
MOVX @Ri, A把 A 写入外部 RAM @Ri8 位2
MOVX A, @DPTR读外部 RAM @DPTR 到 A16 位2
MOVX @DPTR, A把 A 写入外部 RAM @DPTR16 位2

外部 RAM 的读 / 写选通只在执行 MOVX 指令期间有效;其余时间这些信号为非激活状态。若根本不使用它们,对应引脚可作为额外 I/O 线。

查表指令

读取程序存储器查表的两条指令见表 1-8。由于只访问程序存储器,查表只能读、不能更新。助记符 MOVC 意为“传送常量(move constant)”;若表在外部程序存储器,读选通为 PSEN。

第一条 MOVC 可容纳最多 256 项(编号 0~255)的表:把所需项编号装入累加器,DPTR 指向表首,然后 MOVC A, @A+DPTR 把表项复制到累加器。另一条 MOVC 用法相同,但以 PC 作为表基址,通过子程序访问:

MOV A, ENTRY_NUMBER CALL TABLE TABLE: MOVC A, @A+PC RET

表本身紧跟程序存储器中的 RET 指令。这种表最多 255 项(编号 1~255);编号 0 不能用,因为执行 MOVC 时 PC 中是 RET 指令地址,编号 0 对应的就是 RET 操作码本身。

表 1-8查表读取指令

助记符操作执行时间 (µs)
MOVC A, @A+DPTR读程序存储器 (A + DPTR) 处内容2
MOVC A, @A+PC读程序存储器 (A + PC) 处内容2

1.7布尔(位)指令

8051 内含一个完整的布尔(单比特)处理器。内部 RAM 含 128 个可位寻址位,SFR 空间还可支持另外 128 个可位寻址位。所有端口线都可位寻址,每一位都可当作一个独立的单比特端口。访问这些位的不只是条件分支,而是一整套传送、置位、清零、取反、或、与指令;在其他架构上,这类位操作很难用面向字节的软件实现。

表 1-98051 布尔指令(执行时间按 12 MHz 计)

助记符操作执行时间 (µs)
ANL C,bitC = C AND bit2
ANL C,/bitC = C AND (NOT bit)2
ORL C,bitC = C OR bit2
ORL C,/bitC = C OR (NOT bit)2
MOV C,bitC = bit1
MOV bit,Cbit = C2
CLR CC = 01
CLR bitbit = 01
SETB CC = 11
SETB bitbit = 11
CPL CC = NOT C1
CPL bitbit = NOT bit1
JC relC = 1 时跳转2
JNC relC = 0 时跳转2
JB bit,relbit = 1 时跳转2
JNB bit,relbit = 0 时跳转2
JBC bit,relbit = 1 时跳转,并清零 bit2

所有位访问都按直接寻址进行:位地址 00H~7FH 在低 128 字节,80H~FFH 在 SFR 空间。把内部标志搬到端口引脚非常简单:

MOV C, FLAG MOV P1.0, C

其中 FLAG 是低 128 或 SFR 空间中任意可寻址位;I/O 线(本例为 P1.0)根据标志位为 1 或 0 被置位或清零。PSW 中的进位位用作布尔处理器的单比特累加器;把进位位记作 C 的位指令汇编为进位专用指令(如 CLR C)。由于 PSW 可位寻址,进位位也有直接位地址。

布尔指令集包含 ANL、ORL,但没有 XRL(异或)。异或可用软件实现:若要计算 C = bit1 XOR bit2,可先把 bit1 送入进位,若 bit2 = 0 则结果已正确;若 bit2 = 1,则进位是正确结果的反,再 CPL C 即可。JNB 是位测试指令之一:JC / JB / JBC 在被位置位时跳转,JNC / JNB 在被位未置位时跳转。JBC 在跳转的同时清零该位,因此可在一次操作中完成“测试并清零标志”。PSW 各位都可直接寻址,奇偶标志与通用标志同样可供位测试指令使用。

相对偏移量

这些跳转的目的地址以标号或程序存储器中的实际地址提供给汇编器,但汇编后目的地址变成一个相对偏移字节。它是带符号(补码)的偏移量;跳转执行时按补码算术加到 PC 上。因此跳转范围是相对于该指令之后第一个字节的 −128~+127 个程序存储器字节。

1.8跳转指令

无条件跳转清单见表 1-10。

表 1-10Atmel 8051 无条件跳转

助记符操作执行时间 (µs)
JMP addr跳转到 addr2
JMP @A+DPTR跳转到 A + DPTR2
CALL addr调用 addr 处子程序2
RET从子程序返回2
RETI从中断返回2
NOP空操作1

表中只列了一个“JMP addr”,实际有三种——SJMP、LJMP、AJMP,区别在目的地址的编码格式;JMP 是通用助记符,程序员不关心编码方式时可用。

  • SJMP:目的地址编码为相对偏移,指令 2 字节(操作码 + 偏移字节),跳转范围为相对于 SJMP 之后指令的 −128~+127 字节。
  • LJMP:目的地址编码为 16 位常量,指令 3 字节(操作码 + 两个地址字节),目的地址可位于 64K 程序存储器空间任意位置。
  • AJMP:目的地址编码为 11 位常量,指令 2 字节;操作码本身含 11 位地址中的高 3 位,后跟一个字节含目的地址低 8 位。执行时这 11 位替换 PC 的低 11 位,高 5 位保持不变,因此目的地址必须与 AJMP 之后指令处于同一 2K 块内。

无论哪种情况,程序员都以标号或 16 位常量向汇编器指定目的地址,汇编器按指令要求的格式编码;若格式达不到到指定目的地址的距离,列表文件会写出“目的地址越界(Destination out of range)”。

JMP @A+DPTR 支持散转:目的地址在执行时由 16 位 DPTR 与累加器相加得到。典型用法是 DPTR 指向跳转表地址,累加器给表内索引。例如五分支中把 0~4 的整数装入累加器:

MOV DPTR, #JUMP_TABLE MOV A, INDEX_NUMBER RL A JMP @A+DPTR JUMP_TABLE: AJMP CASE_0 AJMP CASE_1 AJMP CASE_2 AJMP CASE_3 AJMP CASE_4

RL A 把索引(0~4)换算成 0~8 范围内的偶数,因为跳转表每项占 2 字节。

表中“CALL addr”实际有 LCALL 与 ACALL 两条,区别在子程序地址提供给 CPU 的格式;CALL 为通用助记符。LCALL 用 16 位地址格式,子程序可在 64K 空间任意位置;ACALL 用 11 位格式,子程序必须与 ACALL 之后指令处于同一 2K 块内。子程序应以 RET 结束,返回执行 CALL 之后的位置。RETI 用于从中断服务例程返回;它与 RET 的唯一区别是 RETI 通知中断控制系统:正在进行的中断已结束。若执行 RETI 时没有正在进行的中断,则 RETI 功能上与 RET 相同。

条件跳转

条件跳转清单见表 1-11,全部按相对偏移方式指定目的地址,跳转距离限制为条件跳转之后指令的 −128~+127 字节。用户同样以标号或 16 位常量向汇编器指定实际目的地址。

表 1-11Atmel 8051 条件跳转

助记符操作寻址方式执行时间 (µs)
JZ relA = 0 时跳转仅累加器2
JNZ relA ≠ 0 时跳转仅累加器2
DJNZ <byte>,rel减 1,非零则跳转直接 / 寄存器2
CJNE A,<byte>,relA = <byte> 时不跳转(不等则跳)直接 / 立即2
CJNE <byte>,#data,rel<byte> = #data 时不跳转(不等则跳)直接 / 立即2

PSW 中没有零标志位,JZ、JNZ 直接测试累加器数据是否满足条件。DJNZ(减 1 非零跳转)用于循环控制:要把循环执行 N 次,给计数器字节装入 N,用 DJNZ 跳回循环开头结束循环,例如 N = 10:

MOV COUNTER, #10 LOOP: ; begin loop * * * ; end loop DJNZ COUNTER, LOOP ; continue

CJNE(比较不等跳转)也可用于循环控制。指令操作数字段指定两个字节,仅当两字节不等时才跳转。另一用途是“大于、小于”比较:操作数字段的两个字节按无符号整数处理,第一个小于第二个则置进位位(C = 1),第一个大于等于第二个则清零进位位。

1.9指令操作码表

表 1-12 给出每条指令的十六进制操作码,并标注:字节长度、机器周期数、指令修改的标志位。表中每格通常写作“指令 操作数 · 字节数-周期数”,括号内为受影响标志(如 C, OV, AC)。

下表按原手册版式整表保留:纵列为操作码高半字节(x0~xF),横列为低半字节(0x~Fx)。指令表为旋转排版,放大后可逐格核对操作码与周期。

表 1-12(一)8051 指令表,操作码高半字节 x8~xF(R0~R7 寄存器寻址列)
表 1-12(二)8051 指令表(续),操作码高半字节 x0~x7(立即 / 直接 / 间接 / 位寻址列)

2.1概述与 SFR 映射

本章全面说明 Atmel 8051 微控制器的片上硬件特性,包括:端口驱动器及其作为端口、以及在总线操作中(端口 0、2)的工作方式;定时器 / 计数器;串行接口;中断系统;复位;低功耗模式。

图 2-18051 功能框图(带 * 标注的寄存器仅在含定时器 2 的型号上存在)

特殊功能寄存器(SFR)

片上存储器中称为 SFR(特殊功能寄存器)空间的映射见图 2-1。括号标注的 SFR 仅存在于带定时器 2 特性的微控制器中。注意并非所有地址都被占用,对这些未用地址做读访问通常返回随机数据。

表 2-1SFR 映射(左列为可位寻址字节,右列为不可位寻址字节)

地址0/81/92/A3/B4/C
F8H–FFH—(保留)
F0H–F7HB————
E8H–EFH—(保留)
E0H–E7HACC————
D8H–DFH—(保留)
D0H–D7HPSW————
C8H–CFH(T2CON)(RCAP2L)(RCAP2H)(TL2)(TH2)
C0H–C7H—(保留)
B8H–BFHIP————
B0H–B7HP3————
A8H–AFHIE————
A0H–A7HP2————
98H–9FHSCONSBUF———
90H–97HP1————
88H–8FHTCONTMODTL0TL1TH0 / TH1 / AUXR / CKCON
80H–87HP0SPDPLDPHPCON

注:保留位置用户软件不应写入,Atmel 8051 衍生产品可能在这些位置启用新功能。括号内寄存器仅定时器 2 型号具备。

累加器(ACC)

ACC 即累加器寄存器;累加器专用指令的助记符中直接把累加器记作 A。

B 寄存器

B 寄存器用于乘法与除法运算;在其他指令中可当作另一个暂存寄存器使用。

程序状态字(PSW)

PSW 寄存器包含程序状态信息,位定义见第 1.1 节表 1-1。

堆栈指针(SP)

堆栈指针为 8 位宽。执行 PUSH 与 CALL 时,先把 SP 加 1 再存入数据。堆栈可位于片内 RAM 任意位置;复位后 SP 初始化为 07H,因此堆栈从 08H 单元开始。

数据指针(DPTR)

DPTR 由高字节 DPH 与低字节 DPL 组成,用于保存 16 位地址;既可作为 16 位寄存器操作,也可作为两个独立的 8 位寄存器操作。

端口 0~3

P0、P1、P2、P3 分别是端口 0、1、2、3 的 SFR 锁存器。

串行数据缓冲(SBUF)

串行数据缓冲实际是两个独立寄存器:发送缓冲与接收缓冲。数据写入 SBUF 时进入发送缓冲,等待串行发送(向 SBUF 写入一个字节即启动发送);从 SBUF 读出的数据来自接收缓冲。

定时器寄存器

寄存器对 (TH0, TL0)、(TH1, TL1)、(TH2, TL2) 分别是定时器 / 计数器 0、1、2 的 16 位计数寄存器。

捕获寄存器

寄存器对 (RCAP2H, RCAP2L) 是定时器 2“捕获模式”的捕获寄存器;该模式下响应 T2EX 引脚的跳变,把 TH2、TL2 复制到 RCAP2H、RCAP2L。定时器 2 另有 16 位自动重装模式,RCAP2H、RCAP2L 保存该模式的重装值。

控制寄存器

SFR IP、IE、TMOD、TCON、T2CON、SCON、PCON 包含中断系统、定时器 / 计数器与串行口的控制和状态位,将在后续各节说明。

2.2振荡器与 CPU 时序

XTAL1 与 XTAL2 是片上单级反相器的输入端与输出端,可外接元件配置成皮尔斯(Pierce)振荡器,如图 2-2。

图 2-2晶体 / 陶瓷谐振器振荡器

振荡器驱动内部时钟发生器,时钟发生器向芯片提供内部时钟信号。内部时钟信号频率为振荡器频率的一半,并定义内部的相位、状态与机器周期,见下节。

X1 模式(标准模式)

一个机器周期由 6 个状态(12 个振荡器周期)组成。每个状态分为相位 1 半周(相位 1 时钟有效)与相位 2 半周(相位 2 时钟有效)。因此一个机器周期含 12 个振荡器周期,编号从 S1P1(状态 1、相位 1)到 S6P2(状态 6、相位 2);每个相位持续一个振荡器周期,每个状态持续两个振荡器周期。通常算术与逻辑运算在相位 1 进行,内部寄存器到寄存器传送在相位 2 进行。

图 2-3 给出以内部状态和相位为基准的取指 / 执行时序。由于这些内部时钟信号用户不可见,图中以 XTAL2 振荡器信号和 ALE(地址锁存使能)信号作为外部参考。ALE 在每个机器周期通常激活两次:一次在 S1P2 与 S2P1,另一次在 S4P2 与 S5P1。

单周期指令的执行从 S1P2 开始,此时操作码锁存进指令寄存器。若为双字节指令,第二字节在同一机器周期的 S4 期间读出;若为单字节指令,S4 仍会发生一次取指,但读出的字节(下一条操作码)被忽略,程序计数器不递增。无论哪种情况,执行都在 S6P2 结束。

多数 80C51 指令在一个周期内执行;乘法 MUL 与除法 DIV 是仅有的超过两个周期的指令,需要四个周期。除 MOVX 外,每个机器周期都从程序存储器取两个代码字节。MOVX 是访问外部数据存储器的单字节双周期指令:在 MOVX 期间,对外存寻址和选通时跳过两次取指。

图 2-380C51 取指 / 执行时序序列(含单字节单周期、双字节单周期、普通双周期与 MOVX 时序)

2.3端口结构与操作

80C51 的四个端口都是双向口。每个端口由一个锁存器(SFR P0~P3)、一个输出驱动器和一个输入缓冲器组成。端口 0、2 的输出驱动器以及端口 0 的输入缓冲器用于访问外部存储器:端口 0 输出外部存储器地址低字节,与写入 / 读出的字节分时复用;端口 2 在地址为 16 位宽时输出地址高字节,否则端口 2 引脚继续输出 P2 SFR 的内容。

所有端口 3 引脚以及(定时器 2 型号上的)两个端口 1 引脚是多功能引脚,除端口功能外还承担下列特殊功能:

表 2-2端口引脚复用功能

端口引脚复用功能
P1.0 注 1T2(定时器 / 计数器 2 外部输入)
P1.1 注 1T2EX(定时器 / 计数器 2 捕获 / 重装触发)
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2INT0(外部中断 0)
P3.3INT1(外部中断 1)
P3.4T0(定时器 / 计数器 0 外部输入)
P3.5T1(定时器 / 计数器 1 外部输入)
P3.6WR(外部数据存储器写选通)
P3.7RD(外部数据存储器读选通)

注 1:P1.0、P1.1 仅在含定时器 2 的微控制器上承担这些复用功能。只有端口 SFR 中对应位锁存器为 1 时,复用功能才能被激活;否则该端口引脚被钳在 0。

I/O 配置

图 2-4 给出四个端口中典型位锁存器与 I/O 缓冲器的功能框图。位锁存器(端口 SFR 中的一位)表示为 D 型触发器:响应 CPU 的“写锁存器”信号从内部总线打入数值;触发器 Q 端响应 CPU 的“读锁存器”信号送上内部总线;引脚本身电平则响应 CPU 的“读引脚”信号送上内部总线。读端口的指令中,有的激活“读锁存器”,有的激活“读引脚”。

图 2-480C51 端口位锁存器与 I/O 缓冲器

如图 2-4,端口 0、2 的输出驱动器可由内部 CONTROL 信号切换到内部 ADDR 与 ADDR/DATA 总线,供外部存储器访问使用。外部存储器访问期间,P2 SFR 保持不变,但 P0 SFR 会被写入全 1。此外,若 P3 某位锁存器为 1,则输出电平由标注“复用输出功能”的信号控制;实际 P3.X 引脚电平始终可供该引脚的复用输入功能使用(如果有的话)。

端口 1、2、3 有内部上拉,端口 0 为开漏输出。每条 I/O 线可独立用作输入或输出(端口 0、2 用作 ADDR/DATA 总线时不能作通用 I/O)。用作输入时,端口位锁存器必须为 1,以关断输出驱动 FET;此时端口 1、2、3 的引脚由内部上拉拉高,但可被外部源拉低。

端口 0 没有内部上拉。P0 输出驱动器中的上拉 FET(见图 2-4A)只在端口于外部存储器访问期间输出 1 时使用,其余时间上拉 FET 关断。因此用作输出的 P0 线是开漏;向位锁存器写 1 会使两个输出 FET 都关断,引脚浮空,此时可作高阻输入。

由于端口 1、2、3 有固定内部上拉,有时被称为“准双向”端口:配置为输入时被拉高,外部拉低时会流出电流(IIL,见数据手册)。端口 0 则被认为是“真”双向口,因为配置为输入时它浮空。复位功能会向所有端口锁存器写入全 1;若之后向端口锁存器写入了 0,可通过再写 1 重新配置为输入。

向端口写入

在执行改变端口锁存器数值的指令时,新值在指令最后一个周期的 S6P2 到达锁存器。但端口锁存器实际上只在每个时钟周期的相位 1 被输出缓冲器采样(相位 2 期间输出缓冲器保持上一个相位 1 看到的值)。因此端口锁存器中的新值要到下一个相位 1 才真正出现在输出引脚上,即下一个机器周期的 S1P1。

若端口 1、2、3 的跳变需要 0→1 翻转,在跳变发生周期的 S1P1 与 S1P2 会额外打开一个上拉管以提高翻转速度;这个额外上拉可提供约普通上拉 100 倍的电流。需注意内部上拉是场效应管,不是线性电阻。上拉结构见图 2-5。

图 2-5端口 1、3 CMOS 内部上拉配置

CMOS 型号的上拉由三个 pFET 组成。注意:n 沟道 FET(nFET)栅极加逻辑 1 时导通、加逻辑 0 时关断;p 沟道 FET(pFET)相反,栅极为 0 时导通、为 1 时关断。图 2-5 中 pFET 1 在端口锁存器发生 0→1 跳变后两个振荡器周期导通;导通期间通过反相器打开 pFET 3(弱上拉),反相器与 pFET 构成锁存保持这个 1。若引脚输出 1 时受到外部负向毛刺,可能关断 pFET 3 使引脚进入浮空;pFET 2 是很弱的上拉,在传统 CMOS 风格下只要 nFET 关断就导通,强度约为 pFET 3 的 1/10,作用是在引脚曾为 1 却被毛刺拉低时把 1 恢复回去。端口 2 与之类似,区别在于它在输出作为地址位的 1 期间保持强上拉导通。

端口负载与接口

端口 1、2、3 的输出缓冲器各自可驱动 3 个 LSTTL 输入。引脚可被集电极开路、漏极开路输出驱动,但注意 0→1 翻转不会很快。CMOS 器件中,输入 0 关断上拉 P3,只剩弱上拉 P2 去驱动晶体管。图 2-6 给出端口由漏极开路晶体管 tN 驱动的例子,寄生电容为 1000 pF。

图 2-6端口接口(漏极开路驱动)

上图描述端口在 0→1 翻转期间的行为:A 区只有上拉 P2 对电容充电,从 0 V 升到 2 V 需 5 µs;B 区由上拉 P2、P3 共同给电容充电,充电时间约缩短为十分之一。可见 0→1 翻转要经过若干机器周期才能达到真正的高电平。

图 2-7端口在 0→1 翻转期间的行为(电压 - 时间)

读-改-写特性

读端口的指令中,有的读锁存器、有的读引脚。读锁存器而非引脚的指令,是那些先读出一个值、可能修改它、再写回锁存器的指令,称为“读-改-写”指令。当目的操作数是端口或端口位时,下列指令读的是锁存器而非引脚:

  • ANL(逻辑与,例:ANL P1,A)
  • ORL(逻辑或,例:ORL P2,A)
  • XRL(逻辑异或,例:XRL P3,A)
  • JBC(位为 1 跳转并清位,例:JBC P1.1, LABEL)
  • CPL(位取反,例:CPL P3.0)
  • INC(加 1,例:INC P2)
  • DEC(减 1,例:DEC P2)
  • DJNZ(减 1 非零跳转,例:DJNZ P3, LABEL)
  • MOV PX.Y,C(把进位位传送到端口 X 的 Y 位)
  • CLR PX.Y(清零端口 X 的 Y 位)、SETB PX.Y(置位端口 X 的 Y 位)

后三条指令表面上不明显,但它们也是读-改-写:先读端口字节的全部 8 位,修改被寻址位,再把新字节写回锁存器。读-改-写指令定向到锁存器而非引脚,是为了避免对引脚电平的误判。例如某端口位用来驱动晶体管基极:向该位写 1 时晶体管导通;若 CPU 此时从引脚而非锁存器读取同一端口位,读到的是晶体管基极电压,会被解释为 0。读锁存器而非引脚则返回正确的 1。

2.4访问外部存储器

外部存储器访问分两类:访问外部程序存储器与访问外部数据存储器。访问外部程序存储器以 PSEN(程序存储使能)作为读选通;访问外部数据存储器用 RD 或 WR(P3.7、P3.6 的复用功能)选通存储器。

从外部程序存储器取指始终使用 16 位地址;访问外部数据存储器可使用 16 位地址(MOVX @DPTR)或 8 位地址(MOVX @Ri)。

使用 16 位地址时,地址高字节从端口 2 输出,并在整个读 / 写周期内保持。注意端口 2 驱动器在输出为 1 的地址位期间全程使用强上拉,这发生在执行 MOVX @DPTR 期间。此时端口 2 锁存器(SFR)不必为 1,端口 2 SFR 内容也不被修改;若下一个周期不紧跟另一个外部存储器周期,未被扰动的端口 2 SFR 内容会在下一周期重新出现。使用 8 位地址(MOVX @Ri)时,端口 2 SFR 内容在整个外部存储器周期内保持在端口 2 引脚上,便于分页。无论哪种情况,地址低字节都在端口 0 上与数据字节分时复用。

ADDR/DATA 信号同时驱动端口 0 输出缓冲器中的两个 FET,因此这种应用下端口 0 引脚不是开漏输出,也不需要外部上拉。应使用 ALE(地址锁存使能)信号把地址字节锁存到外部锁存器:地址字节在 ALE 负跳变时有效。写周期中,待写数据字节在 WR 激活前出现在端口 0,并保持到 WR 撤销之后;读周期中,输入字节在读选通撤销前被端口 0 接收。任何外部存储器访问期间,CPU 都会向端口 0 锁存器写入 0FFH,从而覆盖端口 0 SFR 原先保存的信息。

外部程序存储器在两种条件下被访问:① EA 信号有效时;② 程序计数器(PC)所含数值大于存储器容量时。这要求无 ROM 型号把 EA 接低电平,以便从外部存储器取低地址程序字节。CPU 执行外部程序存储器代码时,端口 2 的全部 8 位都专用于输出功能,不能作通用 I/O;外部程序取指期间它们输出 PC 高字节,端口 2 驱动器用强上拉输出为 1 的 PC 位。

图 2-8外部程序存储器执行

PSEN

外部取指的读选通是 PSEN;内部取指时 PSEN 不激活。CPU 访问外部程序存储器时,PSEN 每个周期激活两次(MOVX 指令期间除外),无论当前指令是否真的需要所取字节。PSEN 激活时序与 RD 不同:完整 RD 周期(含 ALE、RD 的激活与撤销)需 12 个振荡器周期;完整 PSEN 周期(含 ALE、PSEN 的激活与撤销)需 6 个振荡器周期。两类读周期的执行序列见图 2-8 对比。

ALE

ALE 的主要功能是在从外部程序存储器取指时,提供时序恰当的信号,把 P0 上的地址低字节锁存到外部锁存器。为此 ALE 每个机器周期激活两次;即使该周期不涉及外部取指,激活仍然发生。唯一不产生 ALE 脉冲的时机是访问外部数据存储器:MOVX 指令第二个周期的第一个 ALE 缺失。后文“ALE 禁止模式”一节可关闭 ALE 输出。因此在不使用外部数据存储器的系统中,ALE 以振荡器频率 1/6 的恒定速率激活,可用于外部时钟或定时。

程序与数据存储器空间重叠

有些应用希望从同一物理存储器执行程序并存数据。80C51 可把外部程序空间与数据空间合并:将 PSEN 与 RD 做正逻辑与,产生低电平有效的读选通,供合并后的物理存储器使用。由于 PSEN 周期比 RD 周期快,外部存储器需要足够快以适应 PSEN 周期。

ALE 禁止模式

与外部程序 / 数据存储器配合时,ALE 信号用于在端口 0 上分离地址与数据总线;但执行内部代码期间仍会产生 ALE 信号。为降低 EMI,可置位 AO 位禁止 ALE。AO 位位于 AUXR 寄存器第 0 位(见表 2-3)。AO 一旦置位,ALE 不再输出,但在 MOVX、MOVC 指令及外部取指期间仍保持有效;禁止期间 ALE 引脚被弱上拉。

表 2-3AUXR 辅助寄存器(地址 8EH)

—7
—6
—5
—4
—3
—2
EXTRAM1
AO0

复位值 = XXXX XX00B

符号位说明
—7:2保留位,读出值不确定,不要置位。
EXTRAM1外部 RAM 选择:清零把 XRAM 数据映射到内部 XRAM;置位映射到外部 XRAM。
AO0ALE 输出位:清零恢复内部取指期间的 ALE 工作;置位禁止内部取指期间的 ALE 工作。

2.5定时器 / 计数器总论

Atmel 80C51 微控制器实现两个通用 16 位定时器 / 计数器,编号为定时器 0 与定时器 1,可独立配置为定时器或事件计数器,工作于多种模式。作为定时器时,定时器 / 计数器按编程时长运行,然后发出中断请求;作为计数器时,对外部引脚上的负跳变计数,达到预设计数值后发出中断请求。

定时器 / 计数器基本操作

基本操作由级联连接的定时器寄存器 THx、TLx(x = 0、1)构成 16 位定时器。置位 TCON 寄存器中的运行控制位 TRx 后,所选输入允许对 TLx 递增;TLx 溢出时使 THx 递增,THx 溢出时置位 TCON 中的定时器溢出标志 TFx。置位 TRx 不会清零 THx、TLx 定时器寄存器。定时器寄存器可被读取以获取当前计数值,也可写入预设值;随时可读,但要预设其值必须先清零 TRx,否则定时器 / 计数器行为不可预测。

C/Tx# 控制位(TCON 中)通过选择分频后的外设时钟或外部引脚 Tx 作为被计数信号源,来选择定时或计数方式。改变工作方式时必须先清零 TRx,否则行为不可预测。

  • 定时方式(C/Tx# = 0):定时器寄存器对分频后的外设时钟计数,每个外设周期(6 个外设时钟周期)递增一次。定时器时钟速率为 FPER / 6,即标准模式下 FOSC / 12,X2 模式下 FOSC / 6。
  • 计数方式(C/Tx# = 1):定时器寄存器对 Tx 外部输入引脚上的负跳变计数。外部输入每个外设周期采样一次;某周期采样为高、下一周期采样为低时计数器加 1。识别一次负跳变需 2 个周期(12 个外设时钟周期),因此最高计数速率为 FPER / 12,即标准模式 FOSC / 24、X2 模式 FOSC / 12。外部输入信号占空比不受限制,但为保证给定电平在变化前至少被采样一次,应保持至少一个完整外设周期。

除“定时 / 计数”选择外,定时器 0、1 还有四种工作方式,由 TMOD 中的位对 (M1, M0) 选择。方式 0、1、2 对两个定时器相同,方式 3 不同。定时器 2 则有捕获、自动重装、波特率发生器三种方式。

2.6定时器 0 与定时器 1

定时器 0 可在四种工作方式下作为定时器或事件计数器,图 2-9 至图 2-12 给出各方式的逻辑结构。定时器 0 由 TMOD 寄存器低四位与 TCON 寄存器的第 0、1、4、5 位控制:TMOD 选择定时器门控方式(GATE0)、定时 / 计数方式(T/C0#)与工作方式(M10、M00);TCON 提供定时器 0 控制功能:溢出标志(TF0)、运行控制位(TR0)、中断标志(IE0)与中断类型控制位(IT0)。

普通定时方式(GATE0 = 0)下,置位 TR0 即允许所选输入对 TL0 递增;同时置位 GATE0 与 TR0,则允许外部引脚 INT0# 控制定时器运行。定时器 0 溢出(计数从全 1 翻转为全 0)置位 TF0 标志,产生中断请求。改变方式前务必先停止定时器 / 计数器。

方式 0(13 位定时器)

方式 0 把定时器 0 配置为 13 位定时器:8 位定时器(TH0 寄存器)加上由 TL0 低 5 位实现的模 32 预分频器(图 2-9)。TL0 高 3 位不确定,应忽略;预分频器溢出使 TH0 递增。计数从全 1 翻转为全 0 时置位定时器中断标志 TF0。当 TR0 = 1 且(GATE = 0 或 INT0 = 1)时,被计数输入才允许进入定时器。GATE = 1 时允许外部输入 INT0 控制定时器,便于脉宽测量。13 位寄存器由 TH0 全部 8 位与 TL0 低 5 位组成,TL0 高 3 位不确定应忽略;置位运行标志 TR0 不会清零寄存器。方式 0 对定时器 1 相同,把表中 TR0、TF0、INT0 替换为定时器 1 对应信号即可;GATE 位有两个,定时器 1 为 TMOD.7,定时器 0 为 TMOD.3。

图 2-9定时器 / 计数器 x(x = 0 或 1)方式 0

方式 1(16 位定时器)

方式 1 与方式 0 相同,区别在于定时器寄存器使用全部 16 位。方式 1 把定时器 0 配置为 16 位定时器,TH0 与 TL0 级联连接(图 2-10),所选输入对 TL0 递增。

图 2-10定时器 / 计数器 x(x = 0 或 1)方式 1

方式 2(8 位自动重装定时器)

方式 2 把定时器 0 配置为 8 位定时器(TL0 寄存器),自动从 TH0 寄存器重装(图 2-11)。TL0 溢出置位 TCON 中的 TF0 标志,并用软件预设的 TH0 内容重装 TL0。中断请求被服务时硬件清零 TF0;重装不改变 TH0。下一次重装值可随时通过写入 TH0 寄存器修改。方式 2 对定时器 / 计数器 1 相同。

图 2-11定时器 / 计数器 x(x = 0 或 1)方式 2

方式 3(两个 8 位定时器)

方式 3 把定时器 0 配置为:TL0 与 TH0 作为两个独立的 8 位定时器运行(图 2-12),为需要额外 8 位定时器 / 计数器的应用提供。TL0 按常规方式使用 TMOD 中定时器 0 控制位 C/T0#、GATE0 以及 TCON 中的 TR0、TF0;TH0 被锁定为定时器功能(对 FPER/6 计数),并占用定时器 1 的中断(TF1)与运行控制(TR1)位。因此定时器 0 处于方式 3 时,定时器 1 的运行受到限制。

图 2-12定时器 / 计数器 0 方式 3:两个 8 位计数器

定时器 1

定时器 1 与定时器 0 相同,除方式 3 为保持计数方式外。要点如下:

  • 定时器 1 在三种工作方式下作为定时器或事件计数器;图 2-9 至图 2-11 为方式 0、1、2 的逻辑结构,方式 3 为保持计数方式。
  • 定时器 1 由 TMOD 高四位与 TCON 第 2、3、6、7 位控制:TMOD 选择门控(GATE1)、定时 / 计数(C/T1#)与方式(M11、M01);TCON 提供溢出标志(TF1)、运行控制(TR1)、中断标志(IE1)与中断类型控制(IT1)。
  • 定时器 1 可作串行口波特率发生器,方式 2 最适合此用途。
  • 普通定时方式(GATE1 = 0)下,置位 TR1 允许所选输入对 TL1 递增;同时置位 GATE1、TR1,则允许外部引脚 INT1# 控制定时器运行。
  • 定时器 1 溢出置位 TF1,产生中断请求。
  • 定时器 0 处于方式 3 时占用定时器 1 的 TF1 与 TR1;此时定时器 1 只用于不需要中断的场合(如串行口波特率发生器),通过把定时器 1 切入 / 切出自身方式 3 来启停。
  • 改变方式前务必先停止定时器 / 计数器。

方式 0:13 位定时器,TH1 为 8 位定时器、TL1 低 5 位作模 32 预分频器,TL1 高 3 位忽略;方式 1:TH1、TL1 级联的 16 位定时器;方式 2:TL1 为 8 位定时器,溢出时从 TH1 自动重装,重装不改变 TH1;方式 3(停止):把定时器 1 置入方式 3 会使其停止并保持计数,可在 TR1 不可用(即定时器 0 处于方式 3)时用来停止定时器 1。

定时器中断

每个定时器处理一个中断源,即定时器溢出标志 TF0 或 TF1,每次溢出置位;转向定时器中断例程时由硬件清零标志。通过置位 IE 寄存器中的 ETx 位使能中断,前提是已置位 IE 中的 EA 位全局开放中断。

定时器控制寄存器

表 2-4TCON 定时器 / 计数器控制寄存器(地址 88H)

TF17
TR16
TF05
TR04
IE13
IT12
IE01
IT00

复位值 = 0000 0000B

符号位说明
TF17定时器 1 溢出标志:定时器 1 寄存器溢出时硬件置位;处理器转向中断例程时硬件清零。
TR16定时器 1 运行控制位:清零关闭定时器 / 计数器 1,置位开启。
TF05定时器 0 溢出标志:定时器 0 寄存器溢出时硬件置位;转向中断例程时硬件清零。
TR04定时器 0 运行控制位:清零关闭定时器 / 计数器 0,置位开启。
IE13外部中断 1 边沿标志:在 INT1# 引脚检测到外部中断时硬件置位;边沿触发方式下被响应时硬件清零(见 IT1)。
IT12中断 1 类型控制位:清零选择低电平有效(电平触发)外部中断 1;置位选择下降沿有效(边沿触发)。
IE01外部中断 0 边沿标志:在 INT0# 引脚检测到外部中断时硬件置位;边沿触发方式下被响应时硬件清零(见 IT0)。
IT00中断 0 类型控制位:清零选择低电平有效(电平触发)外部中断 0;置位选择下降沿有效(边沿触发)。

表 2-5TMOD 定时器 / 计数器方式控制寄存器(地址 89H)

GATE17
C/T1#6
M115
M014
GATE03
C/T0#2
M101
M000

复位值 = 0000 0000B

符号位说明
GATE17定时器 1 门控控制位:清零时只要 TR1 置位即允许定时器 1;置位时仅当 INT1# 引脚为高且 TR1 置位才允许。
C/T1#6定时器 1 计数 / 定时选择位:清零为定时方式,对分频后系统时钟计数;置位为计数方式,对外部引脚 T1 的负跳变计数。
M11 / M015 / 4定时器 1 方式选择:00 = 方式 0(8 位 TH1 + 5 位预分频 TL1);01 = 方式 1(16 位);10 = 方式 2(8 位自动重装,溢出从 TH1 重装 TL1);11 = 方式 3(定时器 1 停止,保持计数)。
GATE03定时器 0 门控控制位:清零时只要 TR0 置位即允许定时器 0;置位时仅当 INT0# 引脚为高且 TR0 置位才允许。
C/T0#2定时器 0 计数 / 定时选择位:清零为定时方式;置位为计数方式,对外部引脚 T0 的负跳变计数。
M10 / M001 / 0定时器 0 方式选择:00 = 方式 0;01 = 方式 1(16 位);10 = 方式 2(8 位自动重装);11 = 方式 3(TL0 为 8 位定时器 / 计数器,TH0 为占用定时器 1 TR1、TF1 的 8 位定时器)。

定时器 0 处于方式 3 时,定时器 1 可通过切出 / 切入自身方式 3 来启停,也仍可被串行口用作波特率发生器,或用于任何不需要中断的场合。TH0、TL0、TH1、TL1 分别为定时器 0/1 的高、低字节寄存器(地址 8CH、8AH、8DH、8BH),复位值均为 0000 0000B。

2.7定时器 2

定时器 2 是大多数 Atmel 8051 微控制器具备的 16 位定时器 / 计数器,计数由级联连接的两个 8 位寄存器 TH2、TL2 维持。与定时器 0、1 一样,它既可作定时器也可作事件计数器,由 T2CON 寄存器(表 2-11)与 T2MOD 寄存器(表 2-12)控制。C/T2 选择 FOSC/6(定时方式)或外部引脚 T2(计数方式)作为定时器寄存器输入;置位 TR2 允许所选输入对 TL2 递增。

定时器 2 有三种工作方式:捕获、自动重装与波特率发生器,由 T2CON 中的位选择,见表 2-10。

表 2-10定时器 2 工作方式

RCLK + TCLKCP/RL2#TR2方式
00116 位自动重装
01116 位捕获
1X1波特率发生器
XX0(关闭)

捕获方式

捕获方式由 T2CON 中的 EXEN2 位选择两种选项。EXEN2 = 0 时,定时器 2 是一个 16 位定时器或计数器,溢出时置位定时器 2 溢出位 TF2,可用于产生中断。EXEN2 = 1 时,定时器 2 仍完成上述功能,并增加:外部输入 T2EX 上的 1→0 跳变把定时器 2 寄存器 TL2、TH2 的当前值分别捕获到 RCAP2L、RCAP2H。RCAP2L、RCAP2H 是 80C52、83C154 等型号中的新 SFR。此外 T2EX 跳变置位 T2CON 中的 EXF2 位;EXF2 与 TF2 一样可产生中断。

图 2-16定时器 2 捕获方式

自动重装方式

自动重装方式同样由 EXEN2 选择两种选项。EXEN2 = 0 时,定时器 2 翻转不仅置位 TF2,还会用软件预设的 RCAP2L、RCAP2H 中的 16 位值重装定时器 2 寄存器。EXEN2 = 1 时,定时器 2 仍完成上述功能,并增加:外部输入 T2EX 上的 1→0 跳变也触发 16 位重装并置位 EXF2。

自动重装方式(上下计数)

自动重装方式把定时器 2 配置为带自动重装的 16 位定时器或事件计数器,由 T2MOD 中的 DCEN 位控制。置位 DCEN 后定时器 2 可向上或向下计数(图 2-17),此方式下 T2EX 引脚控制计数方向:

  • T2EX 为高:定时器 2 向上计数,计到 FFFFH 溢出,置位 TF2 标志并产生中断请求;溢出同时把 RCAP2H、RCAP2L 中的 16 位值装入 TH2、TL2。
  • T2EX 为低:定时器 2 向下计数,当 TH2、TL2 中的计数值等于 RCAP2H、RCAP2L 中保存的值时发生下溢;下溢置位 TF2 标志,并把 FFFFH 重装入定时器寄存器。

定时器 2 溢出或下溢时,EXF2 位依计数方向翻转;EXF2 不产生中断,该位可用于提供 17 位分辨率。

图 2-17自动重装方式上 / 下计数器

可编程时钟输出

时钟输出方式下,定时器 2 作为占空比 50% 的可编程时钟发生器(图 2-18)。输入时钟以 FOSC/2 频率对 TL2 递增,定时器从装入值反复计数到溢出;溢出时 RCAP2H、RCAP2L 内容装入 TH2、TL2。此方式下定时器 2 溢出不产生中断。时钟输出频率由系统振荡器频率与 RCAP2H、RCAP2L 中的值决定:

时钟输出频率 = ( Fosc × 2X2 ) / [ 4 × ( 65536 − RCAP2H/RCAP2L ) ]

注:X2 位位于 CKCON 寄存器。X2 模式下 FOSC = FXTAL;标准模式下 FOSC = FXTAL/2。以 16 MHz 系统时钟为例,定时器 2 的可编程频率范围为 61 Hz(FOSC/2¹⁶)到 4 MHz(FOSC/4),产生的时钟信号由 T2 引脚(P1.0)输出。

定时器 2 配置为时钟输出方式的步骤:

  1. 置位 T2MOD 寄存器中的 T2OE 位;
  2. 清零 T2CON 寄存器中的 C/T2 位;
  3. 按公式确定 16 位重装值,写入 RCAP2H/RCAP2L;
  4. 向定时器寄存器 TH2/TL2 写入 16 位初值,可与重装值相同或不同,视应用而定;
  5. 置位 T2CON 中的 TR2 运行控制位启动定时器。

定时器 2 可同时用作波特率发生器与时钟发生器;此配置下波特率与时钟频率并不独立,因为两种功能都使用 RCAP2H、RCAP2L 中的值。

图 2-18时钟输出方式

定时器 2 寄存器

表 2-11T2CON 定时器 2 控制寄存器(地址 C8H)

TF27
EXF26
RCLK5
TCLK4
EXEN23
TR22
C/T2#1
CP/RL2#0

复位值 = 0000 0000B · 可位寻址

符号位说明
TF27定时器 2 溢出标志:定时器 2 溢出时硬件置位;RCLK = 1 或 TCLK = 1 时不置位。必须由软件清零。
EXF26定时器 2 外部标志:EXEN2 = 1 时,T2EX 引脚负跳变引起捕获或重装时置位;定时器 2 中断使能时使 CPU 转向定时器 2 中断例程。必须由软件清零。上下计数方式(DCEN = 1)下 EXF2 不产生中断。
RCLK5UART 接收时钟位:清零用定时器 1 溢出作为串行口方式 1/3 的接收时钟;置位用定时器 2 溢出。
TCLK4UART 发送时钟位:清零用定时器 1 溢出作为串行口方式 1/3 的发送时钟;置位用定时器 2 溢出。
EXEN23定时器 2 外部使能位:清零忽略 T2EX 引脚事件;置位(定时器 2 未用于串行口时钟时)在检测到 T2EX 负跳变时引起捕获或重装。
TR22定时器 2 运行控制位:清零关闭定时器 2,置位开启。
C/T2#1定时器 / 计数器 2 选择位:清零为定时方式(输入来自内部时钟系统 FOSC);置位为计数方式(输入来自 T2 引脚,下降沿触发)。时钟输出方式下必须为 0。
CP/RL2#0捕获 / 重装位:RCLK = 1 或 TCLK = 1 时该位被忽略,定时器在溢出时强制自动重装;清零在定时器 2 溢出或(EXEN2 = 1 时)T2EX 负跳变时自动重装;置位在 EXEN2 = 1 时于 T2EX 负跳变处捕获。

表 2-12T2MOD 定时器 2 模式寄存器

—7
—6
—5
—4
—3
—2
T2OE1
DCEN0

复位值 = XXXX XX00B

符号位说明
T2OE1定时器 2 输出使能位:置位把 P1.0/T2 配置为时钟输出。
DCEN0下计数器使能位:清零禁止定时器 2 作上 / 下计数器;置位允许作上 / 下计数器。

TH2、TL2、RCAP2H、RCAP2L 分别为定时器 2 高字节、低字节与重装 / 捕获高字节、低字节寄存器(地址 CBH、CAH 等),复位值均为 0000 0000B,不可位寻址。

2.8串行接口

串行接口同时提供同步与异步通信方式。在方式 1、2、3 三种全双工方式下作为通用异步收发器(UART)工作,异步收发可同时进行,并可使用不同波特率。它还具有接收缓冲能力:在前一个接收字节尚未从接收寄存器读出之前,即可开始接收第二个字节(但若第二字节接收完成时第一字节仍未读出,其中一个字节将丢失)。串行口接收与发送寄存器都通过 SFR SBUF 访问:写入 SBUF 装入发送寄存器,读取 SBUF 访问物理上另一个接收寄存器。

四种工作方式

  • 方式 0:串行数据经 RXD 进入 / 输出,TXD 输出移位时钟。收发 8 位数据(低位在前),波特率固定为振荡器频率的 1/12。
  • 方式 1:经 TXD 发送 / RXD 接收 10 位:1 个起始位(0)、8 个数据位(低位在前)、1 个停止位(1)。接收时停止位进入 SFR SCON 的 RB8。波特率可变。
  • 方式 2:收发 11 位:起始位(0)、8 个数据位(低位在前)、可编程第 9 数据位、停止位(1)。发送时第 9 数据位(SCON 中的 TB8)可赋 0 或 1,例如可把 PSW 中的奇偶位 P 送入 TB8。接收时第 9 数据位进入 SCON 的 RB8,停止位被忽略。波特率可编程为振荡器频率的 1/32 或 1/64。
  • 方式 3:收发 11 位:起始位(0)、8 个数据位(低位在前)、可编程第 9 数据位、停止位(1)。方式 3 与方式 2 除波特率外完全相同,方式 3 波特率可变。

四种方式中,方式 0 在 RI = 0 且 REN = 1 条件下启动发送;方式 0 在 RI = 0 且 REN = 1 条件下启动接收;其余方式在 REN = 1 时由到来的起始位启动接收。串行 I/O 口还包含帧错误检测与自动地址识别两项增强功能。串行口控制与状态寄存器为 SFR SCON(表 2-17),除方式选择位外,还包含收发第 9 数据位(TB8、RB8)与串行口中断位(TI、RI)。

表 2-17SCON 串行控制寄存器(地址 98H)

FE/SM07
SM16
SM25
REN4
TB83
RB82
TI1
RI0

复位值 = 0000 0000B · 可位寻址

符号位说明
FE / SM07帧错误位(SMOD0 = 1 时为 FE):检测到无效停止位时硬件置位;清零复位错误状态,有效停止位不会清除它。SMOD0 必须置位才能访问 FE 位。SMOD0 清零时该位为串行口方式位 SM0。
SM16串行口方式位 1。与 SM0 组合选择方式:00 = 方式 0 移位寄存器(FCPU_PERIPH/6);01 = 方式 1 8 位 UART,波特率可变;10 = 方式 2 9 位 UART,FCPU_PERIPH/32 或 /16;11 = 方式 3 9 位 UART,波特率可变。
SM25方式 2 位 / 多机通信使能位:清零禁止多机通信;置位在方式 2、3(以及方式 1)中使能多机通信。方式 0 下该位应清零。
REN4接收使能位:清零禁止串行接收,置位使能串行接收。
TB83发送第 8 位 / 方式 2、3 发送的第 9 位:清零在第 9 位发送逻辑 0,置位发送逻辑 1。
RB82接收第 8 位 / 方式 2、3 接收的第 9 位:收到第 9 位为逻辑 0 时硬件清零,为逻辑 1 时硬件置位。方式 1 中若 SM2 = 0,RB8 为收到的停止位;方式 0 不使用 RB8。
TI1发送中断标志:方式 0 在第 8 位时间结束、其余方式在停止位开始时硬件置位;清零应答中断。
RI0接收中断标志:方式 0 在第 8 位时间结束、其余方式在停止位时硬件置位(见图 2-26、2-27);清零应答中断。

波特率

方式 0 波特率固定。方式 2 波特率取决于 SFR PCON 中 SMOD 位:SMOD = 0(复位值)时波特率为振荡器频率的 1/64;SMOD = 1 时为 1/32。80C51 中方式 1、3 波特率由定时器 1 溢出率决定;带定时器 2 的型号可由定时器 1 或定时器 2 决定,也可两者分别用于发送与接收。

方式 1、3 的 UART 波特率选择

发送与接收时钟的波特率发生器可通过 T2CON 与 BDRCON 寄存器分别选择,见表 2-18。

表 2-18UART 方式 1、3 波特率时钟源选择

TCLK
(T2CON)
RCLK
(T2CON)
TBCK
(BDRCON)
RBCK
(BDRCON)
UART Tx 时钟源UART Rx 时钟源
0000定时器 1定时器 1
1000定时器 2定时器 1
0100定时器 1定时器 2
1100定时器 2定时器 2
X010内部 BRG定时器 1
X110内部 BRG定时器 2
0X01定时器 1内部 BRG
1X01定时器 2内部 BRG
XX11内部 BRG内部 BRG

内部波特率发生器(BRG)

使用内部波特率发生器时,波特率由 BRG 溢出率决定,取决于 BRL 重装值、BDRCON 中 SPD(速度方式)位与 PCON 中 SMOD1 位:

波特率 = 2SMOD1 × FPER / [ 6(1−SPD) × 32 × ( 256 − BRL ) ] BRL = 256 − 2SMOD1 × FPER / [ 6(1−SPD) × 32 × 波特率 ]
图 2-20内部波特率发生器(自动重装计数器、/2 分频与 SPD、SMOD1、BRL 配置)

用定时器 1 产生波特率

定时器 1 用作波特率发生器时,方式 1、3 波特率由定时器 1 溢出率与 SMOD 值决定。此应用应关闭定时器 1 中断;定时器本身可配置为“定时”或“计数”方式,并用其三种运行方式之一。最典型的应用配置为定时方式、自动重装方式(TMOD 高 nibble = 0010B)。也可保持定时器 1 中断使能、配置为 16 位定时器(TMOD 高 nibble = 0001B),用定时器 1 中断做 16 位软件重装,从而获得很低的波特率。

用定时器 2 产生波特率

在 T2CON 中置位 TCLK 和 / 或 RCLK 即选择定时器 2 作为波特率发生器,此时发送与接收波特率可以同时不同。置位 RCLK 和 / 或 TCLK 把定时器 2 置入波特率发生器方式(图 2-22)。

波特率发生器方式类似自动重装方式:TH2 翻转会把 RCAP2H、RCAP2L 中预设的 16 位值重装入定时器 2 寄存器。方式 1、3 波特率由定时器 2 溢出率决定。定时器可配置为定时或计数方式;典型应用为定时方式(C/T2 = 0)。作为波特率发生器时,“定时”方式与普通定时略有不同:普通定时器每个机器周期(振荡器频率 1/12)递增一次;作为波特率发生器则每个状态时间(振荡器频率 1/2)递增一次。

该图仅在 T2CON 中 RCLK + TCLK = 1 时有效。注意 TH2 翻转不会置位 TF2,也不产生中断,因此定时器 2 处于波特率发生器方式时不必关闭其中断。还需注意:若 EXEN2 置位,T2EX 上 1→0 跳变会置位 EXF2,但不会触发从 (RCAP2H, RCAP2L) 到 (TH2, TL2) 的重装;因此定时器 2 用作波特率发生器时,T2EX 可视需要作为额外外部中断使用。

注意

定时器 2 在波特率发生器方式下运行(TR2 = 1)于“定时”功能时,不要尝试读 / 写 TH2 或 TL2。此时定时器每个状态时间递增,读写结果可能不准确。RCAP 寄存器可读但不应写入,因为写入可能与重装重叠,导致写入和 / 或重装错误。这种情况下应先关闭定时器(清零 TR2)再访问定时器 2 或 RCAP 寄存器。

方式 0 补充说明

串行数据经 RXD 进出,TXD 输出移位时钟,收发 8 位(低位在前),波特率固定为振荡器频率 1/12。图 2-24 为方式 0 串行口简化功能框图及相关时序。

任何以 SBUF 为目的寄存器的指令都启动发送。S6P2 的“写 SBUF”信号同时向发送移位寄存器第 9 位装入 1,并通知 TX 控制块开始发送;内部时序使“写 SBUF”到激活 SEND 之间间隔一个完整机器周期。SEND 把移位寄存器输出送到 P3.0 的复用输出功能线,并把移位时钟送到 P3.1 的复用输出功能线。移位时钟在每个机器周期的 S3、S4、S5 为低,S6、S1、S2 为高;SEND 有效时每个机器周期 S6P2 把发送移位寄存器内容右移一位。数据位右移输出的同时左侧补 0;当数据字节 MSB 到达移位寄存器输出位、最初装入第 9 位的 1 位于 MSB 左侧、其左侧各位全为 0 时,TX 控制块执行最后一次移位,然后撤销 SEND 并置位 TI;这两个动作发生在“写 SBUF”后第 10 个机器周期的 S1P1。

接收在 REN = 1 且 RI = 0 时启动。下一机器周期 S6P2,RX 控制单元向接收移位寄存器写入 11111110,下一相位激活 RECEIVE。RECEIVE 把移位时钟送到 P3.1 复用输出线,移位时钟在每个机器周期 S3P1、S6P1 跳变;RECEIVE 有效时每个周期 S6P2 把接收移位寄存器内容左移一位,右侧移入的值是同一机器周期 S5P2 在 P3.0 引脚采样到的值。数据位从右侧移入的同时 1 从左侧移出;当最初装入最右位的 0 到达移位寄存器最左位时,数据装入 SBUF。在清零 RI 的写 SCON 之后第 10 个机器周期 S1P1,RECEIVE 撤销、RI 置位。

图 2-24串行口方式 0(简化功能框图与收发时序)

方式 1 补充说明

方式 1 经 TXD 发送 / RXD 接收 10 位:起始位(0)、8 个数据位(低位在前)、停止位(1);接收时停止位进入 SCON 的 RB8。80C51 中波特率由定时器 1 溢出率决定;带定时器 2 的型号由定时器 1 或定时器 2 溢出率决定,或两者分别用于收发。

发送由任何以 SBUF 为目的寄存器的指令启动。“写 SBUF”信号同时向发送移位寄存器第 9 位装入 1,并通知 TX 控制单元有发送请求;发送实际在分频 16 计数器下一次翻转后的机器周期 S1P1 开始(位时间同步到分频 16 计数器,而非“写 SBUF”信号)。发送以激活 SEND 开始,把起始位送上 TXD;一个位时间后 DATA 激活,把发送移位寄存器输出位送到 TXD;再一个位时间后产生第一个移位脉冲。数据位右移输出的同时左侧补 0,至 MSB 到达输出位、第 9 位初始装入的 1 位于 MSB 左侧、其左侧全为 0 时,TX 控制单元执行最后一次移位,然后撤销 SEND 并置位 TI,发生在“写 SBUF”后第 10 次分频 16 翻转时。

接收由检测到 RXD 上的 1→0 跳变启动。RXD 以所建立波特率 16 倍的速率采样;检测到跳变时立即复位分频 16 计数器,并向输入移位寄存器写入 1FFH。复位分频 16 计数器使其翻转与到来位时间边界对齐。

波特率实例(定时器 2,RCAP2H-RCAP2L)

表 2-19定时器 2 常用波特率重装值(XX-XX 为 RCAP2H-RCAP2L)

波特率Fosc = 6 MHz11.0592 MHz12 MHz
110F9-57—EE-3F
300FD-8FFB-80FB-1E
600FE-C8FD-C0FD-8F
1200FF-64FE-E0FE-C8
2400FF-B2FF-70FF-64
4800FF-D9FF-B8FF-B2
9600—FF-DCFF-D9
19200—FF-EE—
38400—FF-F7—
56800—FF-FA—

2.9帧错误检测与自动地址识别

帧错误检测

三种异步方式(方式 1、2、3)提供帧错误检测。要使能该特性,置位 PCON 寄存器中的 SMOD0 位。使能后,接收器检查每个到来数据帧的停止位是否有效;无效停止位可能由串行线路噪声或两个 CPU 同时发送造成。若未检测到有效停止位,则置位 SCON 寄存器中的帧错误位 FE。

软件可在每次接收后检查 FE 位以判断数据错误。一旦置位,只有软件或复位能清除 FE;后续收到有效停止位的帧不能清除它。FE 特性使能时,RI 在停止位而非最后一个数据位上升起。

自动地址识别

多机通信

自动地址识别由硬件实现,增强多机通信特性:串行口可检查每个到来命令帧的地址,只有识别到自身地址时,接收器才置位 SCON 中的 RI 位产生中断,从而保证 CPU 不被发往其他设备的命令帧打断。为支持自动地址识别,设备由一个给定地址与一个广播地址标识。

注意

多机通信与自动地址识别特性在方式 0 中不能使能(即在方式 0 下置位 SCON 的 SM2 位无效)。如需要,可在方式 1 中使能自动地址识别:此配置下停止位取代第 9 数据位;只有收到的命令帧地址与设备地址匹配且以有效停止位结束时,才置位 RI。

方式 2、3 为多机通信提供专门机制:这些方式接收 9 个数据位,第 9 位进入 RB8,其后是停止位。端口可编程为:收到停止位时仅当 RB8 = 1 才激活串行口中断。该特性由置位 SCON 中的 SM2 使能。多机系统中典型用法:主处理器要向若干从机之一发送一块数据时,先发一个标识目标从机的地址字节。地址字节与数据字节的区别在于地址字节第 9 位为 1、数据字节为 0。SM2 = 1 时,数据字节不会中断任何从机;地址字节则中断所有从机,以便各从机检查收到的字节是否在呼叫自己。被呼叫的从机清零自身 SM2,准备接收随后到来的数据字节;未被呼叫的从机保持 SM2 置位,忽略随后的数据字节。SM2 在方式 0 无效;方式 1 中可用于检查停止位有效性:方式 1 接收时若 SM2 = 1,只有收到有效停止位才激活接收中断。

给定地址

每个设备有一个由 SADDR 寄存器指定的个体地址;SADEN 寄存器是掩码字节,含无关位(用 0 定义),与 SADDR 共同构成设备给定地址。无关位为同时寻址一个或多个从机提供灵活性。示例:按个体地址寻址某设备时,SADEN 掩码字节必须为 1111 1111B。

SADDR 0101 0110B SADEN 1111 1100B 给定地址 0101 01XXB

用给定地址寻址不同从机的示例:从机 A(SADDR = 1111 0001B,SADEN = 1111 1010B,给定 = 1111 0X0XB);从机 B(SADDR = 1111 0011B,SADEN = 1111 1001B,给定 = 1111 0XX1B);从机 C(SADDR = 1111 0011B,SADEN = 1111 1101B,给定 = 1111 00X1B)。SADEN 字节经过选择,使每个从机可被单独寻址:从机 A 的位 0(LSB)是无关位,从机 B、C 的位 0 为 1;只与从机 A 通信时,主机应发送位 0 清零的地址(如 1111 0000B)。从机 A 的位 1 为 1,从机 B、C 的位 1 为无关位;要与 B、C 而非 A 通信,主机应发送位 0、位 1 都置位的地址(如 1111 0011B)。要与 A、B、C 通信,主机应发送位 0 置位、位 1 清零、位 2 清零的地址(如 1111 0001B)。

广播地址

广播地址由 SADDR 与 SADEN 寄存器逻辑或构成,0 定义为无关位,例如:

SADDR 0101 0110B SADEN 1111 1100B 广播地址 = SADDR OR SADEN = 1111 111XB

无关位为定义广播地址提供灵活性,但多数应用中广播地址为 FFH。示例:从机 A 广播 = 1111 1X11B;从机 B 广播 = 1111 1X11B;从机 C 广播 = 1111 1111B。A、B 的位 2 为无关位,C 的位 2 置位;要与所有从机通信,主机发送地址 FFH;要与 A、B 而非 C 通信,可发送地址 FBH。

复位地址

复位时 SADDR、SADEN 寄存器初始化为 00H,即给定地址与广播地址为 XXXX XXXXB(全无关位)。这保证串行口应答任何地址,从而与不支持自动地址识别的 80C51 微控制器向后兼容。

表 2-20 / 2-21SADEN 从机地址掩码寄存器(B9H)与 SADDR 从机地址寄存器(A9H)

寄存器功能复位值 / 位寻址
SADEN从机地址掩码字节,0 位为无关位。0000 0000B · 不可位寻址
SADDR从机个体地址字节。0000 0000B · 不可位寻址

相关 UART 寄存器

SBUF(99H)为串行缓冲寄存器,复位值 XXXX XXXXB;BRL(9AH)为内部波特率发生器重装寄存器,复位值 0000 0000B。

表 2-28PCON 电源控制寄存器(地址 87H)

SMOD17
SMOD06
—5
POF4
GF13
GF02
PD1
IDL0

复位值 = 00X1 0000B · 不可位寻址

符号位说明
SMOD17UART 串行口方式位 1:置位在方式 1、2、3 选择双倍波特率。
SMOD06UART 串行口方式位 0:清零选择 SCON 中的 SM0 位;置位选择 SCON 中的 FE 位。
—5保留位,读出值不确定,不要置位。
POF4掉电标志:清零以识别下一次复位类型;VCC 从 0 升到标称电压时硬件置位,也可由软件置位。
GF1 / GF03 / 2通用标志位,供用户清零 / 置位作通用用途。
PD1掉电方式位:复位发生时硬件清零;置位进入掉电方式。
IDL0空闲方式位:中断或复位发生时硬件清零;置位进入空闲方式。

掉电标志仅在上电(冷复位)后复位值为 1;热复位不影响该位。

表 2-29BDRCON 波特率控制寄存器(地址 9BH)

—7
—6
—5
BRR4
TBCK3
RBCK2
SPD1
SRC0

复位值 = XXX0 0000B · 不可位寻址

符号位说明
—7:5保留位,读出值不确定,不要置位。
BRR4波特率运行控制位:清零停止内部波特率发生器,置位启动内部波特率发生器。
TBCK3UART 发送波特率发生器选择位:清零选定时器 1 或定时器 2,置位选内部波特率发生器。
RBCK2UART 接收波特率发生器选择位:清零选定时器 1 或定时器 2,置位选内部波特率发生器。
SPD1UART 波特率速度控制位:清零选慢速波特率发生器,置位选快速波特率发生器。
SRC0UART 方式 0 波特率源选择位:清零选 FOSC/12(X2 模式为 FCLK_PERIPH/6)作波特率发生器;置位为方式 0 选内部波特率发生器。

2.10中断系统

若同时收到两个不同优先级的请求,先服务高优先级请求;若同时收到同优先级请求,由内部查询序列决定服务哪一个。因此每个优先级内部还有一个由查询序列决定的二级优先级结构,见表 2-30。

表 2-30中断优先级(同级内查询顺序)

顺序中断源同级内优先级
1IE0最高
2TF0—
3IE1—
4TF1—
5RI + TI—
6TF2 + EXF2最低

“同级内优先级”结构仅用于裁决同时到来的同优先级请求。

中断处理过程

中断标志在每个机器周期 S5P2 采样,采样值在下一机器周期被查询。若前一周期 S5P2 有标志处于置位状态,查询周期将发现它;在不被下列条件封锁时,中断系统生成一条 LCALL 转向相应服务例程:

  1. 已有同级或更高优先级中断正在进行;
  2. 当前(查询)周期不是正在执行指令的最后一个周期;
  3. 正在执行的指令是 RETI,或对 IE、IP 寄存器的任何访问。

查询周期随每个机器周期重复,查询的是上一机器周期 S5P2 时刻的值。注意:若某中断标志因上述条件之一处于激活但未被响应,当封锁条件解除时标志已不再激活,则被拒绝的中断不会再被服务。换言之,“中断标志曾激活但未被服务”这一事实不会被记住,每个查询周期都是新的。

处理器通过执行硬件生成的 LCALL 转向相应服务例程来应答中断请求。某些情况下硬件同时清零产生中断的标志,另一些情况下则不清零:它从不清零串行口或定时器 2 标志,必须由用户软件完成;只有边沿激活的外部中断标志(IE0 或 IE1)会被硬件清零。

硬件生成的 LCALL 把程序计数器内容压入堆栈(但不保存 PSW),并按中断源重新装入 PC,向量地址如下:

表 2-31中断向量地址

中断源向量地址
IE00003H
TF0000BH
IE10013H
TF1001BH
RI + TI0023H
TF2 + EXF2002BH

程序从该位置执行,直到遇到 RETI 指令。RETI 通知处理器该中断例程已不再进行,然后从栈顶弹出两个字节重装程序计数器,被中断的程序从断点继续执行。注意:单纯的 RET 也能返回到被中断程序,但会使中断控制系统误以为仍有中断在进行。

图 2-28中断响应时序图

外部中断

外部中断源可通过置位 / 清零 TCON 寄存器中的 IT1 或 IT0 位,编程为电平激活或跳变激活。ITx = 0 时,外部中断 x 由检测到的 INTx 引脚低电平触发;ITx = 1 时为边沿触发:若连续采样 INTx 引脚,一个周期为高、下一周期为低,则置位 TCON 中的中断请求标志 IEx,由该标志请求中断。

外部中断引脚每个机器周期采样一次,输入高或低电平应至少保持 12 个振荡器周期以确保被采样。若外部中断为跳变激活,外部源必须先把请求引脚保持高至少一个周期,再保持低至少一个周期,以确保跳变被看到、IEx 置位。调用服务例程时 CPU 自动清零 IEx。若外部中断为电平激活,外部源必须保持请求有效直到中断实际产生;随后必须在中断服务例程完成前撤销请求,否则会再次产生中断。

响应时间

INT0、INT1 电平在每个机器周期 S5P2 反相并锁存到 IE0、IE1;电路要到下一机器周期才真正查询这些值。若请求激活且条件允许应答,下一条要执行的指令就是转向请求服务例程的硬件子程序调用,调用本身占两个周期。因此从外部中断请求激活到服务例程开始执行,最少经过三个完整机器周期。

若请求被前述三种条件之一封锁,响应时间会更长:同级或更高优先级中断正在进行时,额外等待时间显然取决于另一中断服务例程的性质;正在执行的指令未到最后周期时,额外等待不超过 3 个周期(最长指令 MUL、DIV 也只有 4 个周期);正在执行 RETI 或访问 IE、IP 时,额外等待不超过 5 个周期(最多再用 1 个周期完成当前指令,若当前指令是 MUL 或 DIV 再加 4 个周期)。因此在单中断系统中,响应时间总是大于 3 个周期、小于 8 个周期。