51单片机所有寄存器介绍
51单片机所有寄存器介绍
作者 | 将狼才鲸 |
---|---|
创建日期 | 2025-04-27 |
- 参考资料:Intel官方《MCS-51 Programmer’s Guide and Instruction Set.pdf》
- CSDN阅读地址:51单片机所有寄存器介绍
一、前言
- 51单片机的寄存器和ARM不一样,有自己专有的名称,叫SFR(特殊功能寄存器),地址是8位的0x80-0xFF(该地址与IRAM地址复用,通过不同的汇编操作指令来区分);
- 因为51单片机中的寄存器不是通过指针来读写,而是通过伪指令定义别名后来直接读写,因此这一块的编程也是和ARM不同的地方,寄存器读写相关的代码都不能和32位ARM的代码复用;
- 因为51单片机特殊功能寄存器最多只能有128个,对于当前很多应用场景下的的MCU来说明显不够,那么很多芯片厂商会对寄存器进行扩展,例如选2个寄存器作为二级寄存器地址,选2个寄存器作为二级寄存器数据,那么通过多操作几次寄存器就能扩展16位或32位的寄存器容量;
- 扩展寄存器的代价是牺牲了速度(操作一次16位寄存器要读写好几个SFR寄存器),但当前很多51单片机都做到了1T(一个时钟周期执行一条指令),主频200M+,所以这点花销是可以忽略的;
- 原始的MCS-51核用到的寄存器很少,但这些中也只有大部分是通用的,一些兼容MCS-51指令集的CPU核也会删除或修改里面一些寄存器(特别是有些8052寄存器);
- 一些8051核的IP商会将剩下的一百多个寄存器占用得差不多,而且不同的8051核所用的寄存器含义都不一样;而之后芯片厂商一般会将所有的128个寄存器用完,甚至还扩展出二级寄存器使用;
- 不同厂商51单片机的寄存器会不一样,因此底层硬件相关的代码并不通用,也就是说如果有驱动概念的话,换一款51芯片就得重写一次驱动;
- 标准MSC-51寄存器
- 寄存器地址为0x00-0xFF,其中只有0x80-0xFF特殊功能寄存器SFR与IRAM的地址是复用的,通过不同的汇编指令可以分别操作SFR和IRAM;而0x00-0x7F通用寄存器地址就是IRAM;所以SP堆栈指针不能设置到0x00-0x07,会与R0-R7冲突,但是可以设置到0x80-0xFF,与SFR不冲突;
- 寄存器地址0x00-0x7F是通用寄存器,同时也占用IRAM地址,例如4组R0-R7(ARM中类似的是R0-R31)和16字节位寻址,以及未使用的几十个字节;0x80-0xFF是SFR特殊功能寄存器,类似于ARM中的外设寄存器,不占用IRAM地址;
- 如果程序需要从ROM加载到RAM中执行,那么是加载到0地址的外部RAM,和IRAM无关,操作内外RAM的汇编指令不一样,它们的总线宽度一个只有8位一个16位;
- IRAM一般只有128B、256B;
二、所有寄存器信息的表格
- 0x00-0x7F通用寄存器(占用IRAM地址)
地址 | 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 |
---|---|---|---|---|---|---|---|---|
通用寄存器 | 0组R0 | 0组R1 | 0组R2 | 0组R3 | 0组R4 | 0组R5 | 0组R6 | 0组R7 |
0x08 | 0x09 | 0x0A | 0x0B | 0x0C | 0x0D | 0x0E | 0x0F | |
1组R0 | 1组R1 | 1组R2 | 1组R3 | 1组R4 | 1组R5 | 1组R6 | 1组R7 | |
0x10 | 0x11 | 0x12 | 0x13 | 0x14 | 0x15 | 0x16 | 0x17 | |
2组R0 | 2组R1 | 2组R2 | 2组R3 | 2组R4 | 2组R5 | 2组R6 | 2组R7 | |
0x18 | 0x19 | 0x1A | 0x1B | 0x1C | 0x1D | 0x1E | 0x1F | |
3组R0 | 3组R1 | 3组R2 | 3组R3 | 3组R4 | 3组R5 | 3组R6 | 3组R7 | |
0x20 | 0x21 | 0x22 | 0x23 | 0x24 | 0x25 | 0x26 | 0x27 | |
位寻址 | 位地址00H~07H | 08H~0FH | 10H~17H | 18H~1FH | 20H~27H | 28H~2FH | 30H~37H | 38H~3FH |
0x28 | 0x29 | 0x2A | 0x2B | 0x2C | 0x2D | 0x2E | 0x2F | |
40H~47H | 48H~4FH | 50H~57H | 58H~5FH | 60H~67H | 68H~6FH | 70H~77H | 78H~7FH | |
0x30 | 0x31 | 0x32 | 0x33 | 0x34 | 0x35 | 0x36 | 0x37 | |
剩下都是 | 用户可 | 自行定义 | 与使用 | 的寄存器, | 可以当成 | 全局变量 | 和局部变量 | 来使用, |
0x38 | 0x39 | 0x3A | 0x3B | 0x3C | 0x3D | 0x3E | 0x3F | |
一般会将 | 里面大部分 | 区域配置成 | 堆栈 | …… | …… | …… | …… | |
0x78 | 0x79 | 0x7A | 0x7B | 0x7C | 0x7D | 0x7E | 0x7F | |
…… | …… | …… | …… | …… | …… | …… | …… |
- 0x80-0xFF SFR特殊功能寄存器,加粗为8051的,斜体+下划线是8052专有(不占用IRAM地址)
地址 | 0x80(此列可位寻址,位地址X0~XF) | 0x81 | 0x82 | 0x83 | 0x84 | 0x85 | 0x86 | 0x87 |
---|---|---|---|---|---|---|---|---|
SFR | P0 IO口输入输出 | SP 堆栈指针 | DPL 内存数据地址低8位 | DPH 内存数据地址高8位 | PCON 电源控制 | |||
0x88 | 0x89 | 0x8A | 0x8B | 0x8C | 0x8D | 0x8E | 0x8F | |
TCON 定时器0计数器控制 | TMOD 定时器0计数器模式 | TL0 定时器0值低8位 | TL1 定时器1值低8位 | TH0 定时器0值高8位 | TH1 定时器1值高8位 | |||
0x90 | 0x91 | 0x92 | 0x93 | 0x94 | 0x95 | 0x96 | 0x97 | |
P1 IO口输入输出 | ||||||||
0x98 | 0x99 | 0x9A | 0x9B | 0x9C | 0x9D | 0x9E | 0x9F | |
SCON串口0设置 | SBUF串口0数据 | |||||||
0xA0 | 0xA1 | 0xA2 | 0xA3 | 0xA4 | 0xA5 | 0xA6 | 0xA7 | |
P2 IO口输入输出 | ||||||||
0xA8 | 0xA9 | 0xAA | 0xAB | 0xAC | 0xAD | 0xAE | 0xAF | |
IE 中断使能 | ||||||||
0xB0 | 0xB1 | 0xB2 | 0xB3 | 0xB4 | 0xB5 | 0xB6 | 0xB7 | |
P3 IO口输入输出 | ||||||||
0xB8 | 0xB9 | 0xBA | 0xBB | 0xBC | 0xBD | 0xBE | 0xBF | |
IP 中断优先级 | ||||||||
0xC0 | 0xC1 | 0xC2 | 0xC3 | 0xC4 | 0xC5 | 0xC6 | 0xC7 | |
0xC8 | 0xC9 | 0xCA | 0xCB | 0xCC | 0xCD | 0xCE | 0xCF | |
T2CON 定时器2计数器控制 | RCAP2L 定时器2重装载数低8位 | RCAP2H 定时器2重装载数高8位 | TL2 定时器2值低8位** | TH2 定时器1值高8位 | ||||
0xD0 | 0xD1 | 0xD2 | 0xD3 | 0xD4 | 0xD5 | 0xD6 | 0xD7 | |
PSW 程序状态字 | ||||||||
0xD8 | 0xD9 | 0xDA | 0xDB | 0xDC | 0xDD | 0xDE | 0xDF | |
0xE0 | 0xE1 | 0xE2 | 0xE3 | 0xE4 | 0xE5 | 0xE6 | 0xE7 | |
ACC 累加器 | ||||||||
0xE8 | 0xE9 | 0xEA | 0xEB | 0xEC | 0xED | 0xEE | 0xEF | |
B 寄存器 | ||||||||
0xF8 | 0xF9 | 0xFA | 0xFB | 0xFC | 0xFD | 0xFE | 0xFF | |
-
MCS-51寄存器详细描述
-
汇编编程相关寄存器
寄存器 | bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
---|---|---|---|---|---|---|---|---|
(R0-R7)x4 | 通用 | 寄存器, | 用作 | 函数形参、 | 局部变量 | |||
00-7F位寻址,20-7F通用寄存器 | 自定义 | 寄存器, | 汇编 | 编程时 | 自行使用, | 可定义成 | 全局变量 | 和堆栈区域 |
ACC累加器(A寄存器) | 用作局部变量, | 或存储 | 算数运算 | 的结果 | ||||
B寄存器 | 用作局部变量, | 或乘除操作 | 时使用 | |||||
DPL/DPH/DPTR数据指针 | 使用汇编 | 读写外部RAM | 数据时的 | 当前RAM地址 | ||||
PSW程序状态字 | P: 操作数中奇偶校验,可用于串口数据校验 | 用户自定义 | OV溢出,算术运算时的溢出判断 | RS0 | RS1寄存器组选择(第几组R0~R7),很少使用 | F0用户自定义 | AC半字节进位,高半字节和低半字节间进位,如BCD码计算中能用到,很少使用 | CY进位,int、long等多字节类型加减乘除等算数运算时会用到,一些包含位标志的指令会用到 |
- 系统设置和外设寄存器(串口、GPIO、定时器)
寄存器 | bit0 | bit1 | bit2 | bit3 | bit4 | bit5 | bit6 | bit7 |
---|---|---|---|---|---|---|---|---|
SP堆栈指针(建议主动配置) | 指向内部通用寄存器或IRAM地址, | 上电默认值07H | 一般会主动设置到 | 30H~F0H之间, | 函数调用时 | 压栈弹栈 | 会用到 | |
PCON芯片电源控制(可使用默认值) | IDL芯片进入空闲 | PD芯片下电 | GF0用户自定义 | GF1用户自定义 | 无 | 无 | 无 | SMOD特定条件下的串口双波特率位(由定时器1产生)(当前很多芯片串口波特率由别的寄存器来控制了,更简单) |
IE中断使能(用到外设时需主动打开) | EX0外部中断0 | ET0定时器0中断 | EX1外部中断1 | ET1定时器1中断 | ES串口0中断 | ET2定时器2中断 | 无 | EA失能所有中断 |
IP中断优先级(可使用默认值) | PX0外部中断0优先级 | PT0定时器0优先级 | PX1外部中断1优先级 | PT1定时器1优先级 | PS串口优先级 | PT2定时器2优先级 | 无 | 无 |
SCON串口0配置 | 接收中断,软件清零 | 发送中断,软件清零 | RB8接收的9bit | TB8要发送的9bit | REN接收使能 | SM2 | SM1 | SM0串口模式:波特率与晶振关系,8bit还是9bit(当前很多芯片串口波特率由别的寄存器来控制了,更简单) |
SBUF串口0数据 | 串口0的收发数据 | |||||||
P0、P1、P2、P3 GPIO | 读写IO数据,Px.0 | Px.1 | Px.2 | Px.3 | Px.4 | Px.5 | Px.6 | Px.7 |
TCON定时器和外部中断配置 | IT0外部中断0边缘触发还是电平触发 | IE0外部中断0标志 | 1边缘触发还是电平触发 | IE1收到外部中断1的标志 | TR0定时器0使能失能 | TF0定时器0溢出标志,硬件置位和清零 | TR1定时器1使能失能 | TF1定时器1溢出标志,硬件置位和清零 |
TMOD | M0_0 | M1_0多少位的寄存器,是否自动装载 | C/T0作为计数器还是定时器 | GATE0定时器0的运行关闭由外部中断引脚电平来控制 | M0_1 | M1_1 | C/T1 | GATE1 |
TL0、TL1、TH0、TH1、TL2、TH2、RCAP2L、RCAP2H | 定时器的装载值和计数器的计数值 | |||||||
T2CON | CP/RL2是否自动装载 | C/T2作为定时器2还是计数器2 | TR2定时器2开始和运行 | EXEN2定时器2外部使能 | TCLK串口0发送波特率由串口2来生成 | RCLK串口0接收波特率由定时器2来生成 | EXF2定时器2外部标志 | TF2定时器2溢出标志 |