51单片机的存储结构组成:
分为三部分:
1.程序存储器(ROM):
-
地址范围:
0x0000
到0xFFFF
(64KB)。 -
作用:用于存储程序代码(如指令、常量等)。
-
扩展:如果单片机的内部ROM不够用,可以通过外部扩展ROM来增加程序存储空间。
2.数据存储器(RAM)
-
内部 RAM:
-
地址范围:
0x00
到0xFF
(256字节)。 -
作用:用于存储变量、堆栈、临时数据等。
-
分区:
-
低 128 字节(
0x00
到0x7F
):可以直接寻址包括通用bank寄存器和支持位寻址区,和普通ram区。 -
高 128 字节(
0x80
到0xFF
):只能通过间接寻址访问的普通RAM访问速度较慢与低128字节的。
-
-
-
外部 RAM:
-
地址范围:
0x0000
到0xFFFF
(64KB)。 -
作用:通过外部扩展RAM芯片来增加数据存储空间。
-
3.SFR特殊功能寄存器区
-
地址范围:
0x80
到0xFF
(高128字节)。 -
作用:用于控制和访问单片机的各种外设(如GPIO、定时器、串口等)。
-
访问方式:通过
sfr
关键字定义别名来访问。如sfr P0 = 0x80;支持直接寻址,部分支持位操做。
注意这里需要注意一点:就是这个IDATA区和SFR区所用的地址描述都是80-ff,但是他们对应的物理空间确是不同的,在c语言上通过关键字idata和sfr进行区分,在硬件上sfr采用直接寻址,idata采用间接寻址。
位寻址区
-
地址范围:
0x20
到0x2F
(16字节)。 -
作用:支持位寻址操作,每个字节的每一位都可以单独访问。
-
访问方式:通过
sbit
关键字定义位别名来访问。
分析51单片机的位寻址:
首先我们需要明白位地址空间和字节地址空间的区别,位地址空间其实就是对字节地址空间的每个位的映射,通过关键字sbit区分,51单片机的0x20
到 0x2F
(16字节),支持位寻址,对应位地址空间的0x00到0x7f,可能你们会疑惑为什么有这个位地址空间,它是不是独立的,真实存在的物理地址呢?其实它就是对应于内部ram的0x20
到 0x2F这16个字节地址空间,只不过它支持位操作,通常被用来操作标志位。是一种映射。例如:
unsigned char bdata var3; // 存储在bdata区 sbit flag = var3^0; // 定义var3的第0位为flag flag = 1; // 位操作
对于高128字节ram它其实也支持位操作,不过并不是全部都支持,只要那些需要经常使用到位操作的寄存器才会支持,比如gpio和串口。例如:
sbit P0_0 = 0x80; // 定义P0.0的位地址为0x80 P0_0 = 1; // 将P0.0引脚设为高电平
内部ram的位寻址和sfr寄存器的位寻址的区别:
内部ram的位寻址为什么仅限于 0x20–0x2F
?
-
硬件设计:为了简化硬件实现,51单片机只将内部RAM的
0x20–0x2F
区域设计为支持位操作。 -
资源限制:内部RAM资源有限,16字节的位寻址区已经是一种折中方案。
为什么内部RAM不能全部支持位操作?
地址空间冲突
-
如果内部RAM的低128字节(
0x00–0x7F
)全部支持位操作,会导致地址空间冲突:-
字节地址
0x00
可以表示内部RAM的第0字节,也可以表示位地址0x00
(对应字节地址0x20
的第0位)。 -
硬件无法区分是字节操作还是位操作。
-
硬件解码复杂度
-
内部RAM的位寻址区仅限于
0x20–0x2F
,可以减少硬件解码电路的复杂度。 -
如果整个128字节都支持位操作,硬件需要额外的解码逻辑,增加芯片面积和成本。
性能优化
-
内部RAM的位寻址区(
0x20–0x2F
)主要用于存储软件标志位,访问频率相对较低。 -
SFR的位寻址区(如P0端口)用于控制硬件外设,访问频率较高,因此采用更高效的位寻址方式。
sfr的内部寻址是通过sfr变量和sbit变了区分的,因此它不需要连续,可以达到随机(按需要去设置是否支持位寻址),只需要区分关键字即可。
关键对比分析
特性 | 内部RAM位寻址区 | SFR位寻址区 |
---|---|---|
地址范围 | 位地址 0x00–0x7F | 位地址 0x80–0xFF |
对应物理存储 | 内部RAM的 0x20–0x2F (16字节) | SFR的 0x80–0xFF (部分寄存器支持) |
汇编指令 | SETB 00h (操作位地址0x00) | SETB 80h (操作位地址0x80) |
硬件支持 | 所有51单片机均支持 | 仅部分SFR支持位寻址(如P0-P3) |
用途 | 存储标志位、状态位 | 控制外设引脚或寄存器状态位 |
内存变量关键字的区别:
1. 关键字概述
关键字 | 存储区域 | 地址范围 | 寻址方式 | 访问速度 | 用途 |
---|---|---|---|---|---|
data | 内部RAM低128字节 | 0x00–0x7F | 直接寻址 | 最快 | 存储频繁访问的变量 |
idata | 内部RAM高128字节 | 0x80–0xFF | 间接寻址 | 较快 | 存储较少访问的变量 |
bdata | 内部RAM位寻址区(0x20–0x2F) | 0x00–0x7F(128位) | 位寻址 | 快 | 存储需要位操作的标志位 |
xdata | 外部扩展RAM | 0x0000–0xFFFF(64KB) | DPTR间接寻址 | 较慢 | 存储大量数据 |
pdata | 外部扩展RAM低256字节 | 0x0000–0x00FF(256B) | 分页寻址(MOVX @Ri) | 中等 | 存储中等规模数据 |
code | 程序存储区(ROM) | 0x0000–0xFFFF(64KB) | 直接寻址 | 最快 | 存储常量、程序代码 |
直接寻址和简介寻址的区别
1. 直接寻址
-
定义:
-
直接寻址是指指令中直接给出操作数的内存地址。
-
例如:
MOV A, 30H
表示将地址30H
的内容加载到累加器A
。
-
-
特点:
-
访问速度快,因为地址直接嵌入指令中。
-
只能访问固定的内存地址(如内部RAM的低128字节或SFR区)。
-
适用于访问已知地址的变量或寄存器。
-
-
使用场景:
-
访问内部RAM的低128字节(00H ~ 7FH)。
-
访问特殊功能寄存器(SFR,80H ~ FFH)。
-
1. 直接寻址
-
定义:
-
直接寻址是指指令中直接给出操作数的内存地址。
-
例如:
MOV A, 30H
表示将地址30H
的内容加载到累加器A
。
-
-
特点:
-
访问速度快,因为地址直接嵌入指令中。
-
只能访问固定的内存地址(如内部RAM的低128字节或SFR区)。
-
适用于访问已知地址的变量或寄存器。
-
-
使用场景:
-
访问内部RAM的低128字节(00H ~ 7FH)。
-
访问特殊功能寄存器(SFR,80H ~ FFH)。
-
MOV R0, #30H ; 将地址30H加载到R0
MOV A, @R0 ; 将R0指向的地址的内容加载到累加器A
MOV DPTR, #1000H; 将地址1000H加载到DPTR
MOVX A, @DPTR ; 将DPTR指向的外部RAM内容加载到累加器A
3. 直接寻址和间接寻址的区别
特性 | 直接寻址 | 间接寻址 |
---|---|---|
地址指定方式 | 指令中直接给出地址 | 通过寄存器(如R0、R1、DPTR)指定地址 |
访问速度 | 较快 | 稍慢 |
灵活性 | 固定地址,灵活性低 | 动态地址,灵活性高 |
适用区域 | 内部RAM低128字节、SFR区 | 内部RAM高128字节、外部RAM |
典型指令 | MOV A, 30H | MOV A, @R0 、MOVX A, @DPTR |
1. 51单片机的寄存器
51单片机的寄存器主要包括以下几类:
(1)工作寄存器(R0 ~ R7)
-
数量:8个(R0 ~ R7)。
-
功能:用于通用数据操作。
-
特点:
-
51单片机有4组工作寄存器(Bank 0 ~ Bank 3),每组包含R0 ~ R7。
-
通过PSW(程序状态字)中的RS1和RS0位来选择当前使用的寄存器组。
-
默认使用Bank 0(RS1=0, RS0=0)。
-
(2)特殊功能寄存器(SFR)
-
数量:21个(具体数量取决于单片机型号)。
-
功能:用于控制和配置硬件外设(如P0、P1、定时器、串口等)。
-
常见SFR:
-
ACC
(累加器A):用于算术和逻辑运算。 -
B
:用于乘除法操作。 -
PSW
(程序状态字):包含标志位(如CY、AC、OV等)。 -
SP
(堆栈指针):指向堆栈顶部。 -
DPTR
(数据指针):用于访问外部RAM或代码存储器。 -
P0
、P1
、P2
、P3
:I/O端口寄存器。 -
TCON
、TMOD
:定时器控制寄存器。 -
SCON
、SBUF
:串口控制寄存器。
-
(3)其他寄存器
-
PC(程序计数器):指向下一条要执行的指令地址。
-
DPTR(数据指针):16位寄存器,用于访问外部RAM或代码存储器。
3. 51单片机和32位单片机的寄存器对比
特性 | 51单片机 | 32位单片机(ARM Cortex-M) |
---|---|---|
通用寄存器数量 | 8个(R0 ~ R7) | 13个(R0 ~ R12) |
寄存器位宽 | 8位 | 32位 |
寄存器组 | 4组(Bank 0 ~ Bank 3) | 无分组 |
特殊功能寄存器 | 21个(如ACC、B、PSW、DPTR等) | 多个(如SP、LR、PC、PSR等) |
浮点寄存器 | 不支持 | 可选支持(S0 ~ S31、D0 ~ D15等) |
访问方式 | 直接寻址、间接寻址 | 统一编址,直接访问 |
4. 51单片机的寄存器组切换
51单片机有4组工作寄存器(Bank 0 ~ Bank 3),每组包含R0 ~ R7。通过PSW寄存器中的RS1和RS0位来选择当前使用的寄存器组。
-
RS1和RS0的值:
-
RS1=0, RS0=0
:Bank 0(默认)。 -
RS1=0, RS0=1
:Bank 1。 -
RS1=1, RS0=0
:Bank 2。 -
RS1=1, RS0=1
:Bank 3。
-
bank寄存器的概念
在51单片机中,Bank寄存器是指工作寄存器组(Register Bank),它是51单片机寄存器设计的一个重要特性。51单片机有4组工作寄存器(Bank 0 ~ Bank 3),每组包含8个通用寄存器(R0 ~ R7)。通过切换寄存器组,可以快速保存和恢复上下文,特别适用于中断处理和任务切换。
1. Bank寄存器的结构
-
数量:4组(Bank 0 ~ Bank 3)。
-
每组寄存器:每组包含8个通用寄存器(R0 ~ R7)。
-
总寄存器数量:4组 × 8个 = 32个寄存器(但同一时间只能访问一组)。
2. Bank寄存器的地址
-
Bank 0:地址 00H ~ 07H(R0 ~ R7)。
-
Bank 1:地址 08H ~ 0FH(R0 ~ R7)。
-
Bank 2:地址 10H ~ 17H(R0 ~ R7)。
-
Bank 3:地址 18H ~ 1FH(R0 ~ R7)。
3. Bank寄存器的切换
-
通过**PSW(程序状态字)**中的 RS1 和 RS0 位来选择当前使用的寄存器组。
-
RS1 和 RS0 是PSW的第4位和第3位(PSW.4 和 PSW.3)。
-
RS1 和 RS0 的值:
-
RS1=0, RS0=0
:选择 Bank 0(默认)。 -
RS1=0, RS0=1
:选择 Bank 1。 -
RS1=1, RS0=0
:选择 Bank 2。 -
RS1=1, RS0=1
:选择 Bank 3。
-
-
4. Bank寄存器的用途
-
快速上下文切换:
-
在中断处理或任务切换时,可以通过切换寄存器组来保存和恢复上下文,而不需要将寄存器内容压入堆栈。
-
例如:
-
进入中断时,切换到新的寄存器组(如Bank 1)。
-
退出中断时,切换回原来的寄存器组(如Bank 0)。
-
-
-
提高效率:
-
寄存器组切换比堆栈操作更快,适合实时性要求高的应用。
-
5. 总结
-
Bank寄存器占用低128字节的00H ~ 1FH,但通过寄存器组切换实现地址复用。
-
未激活的Bank地址可作为普通RAM使用,但需避免误操作导致数据覆盖。
-
合理使用Bank切换可以高效管理寄存器和内存资源,尤其适用于中断和任务切换场景。