80C51 has four storage spaces in its physical structure: on-chip program memory, off-chip program memory, on-chip data memory, and off-chip data memory. But logically, from the user's point of view, 80C51 has three storage spaces: 64KB of program memory address space (using 16-bit address) with unified addressing inside and outside the chip, 256B of on-chip data memory address space (using 8-bit address, of which only 21 bytes of the 128B dedicated register address space are meaningful) and 64KB of off-chip memory address space.
1. Program memory
The program memory is used to store compiled programs and table constants. The 80C51 has a 4KB ROM inside the chip, and the 16-bit address line outside the chip can expand up to 64KB ROM, and the two are uniformly addressed. If the EA terminal is kept at a high level, the program counter PC of the 80C51 is in the range of 0000H-0FFFH (that is, the first 4KB address) to execute the program of the on-chip ROM. When the addressing range is 1000H-FFFFH, instructions are fetched from the off-chip memory. When the EA terminal is kept at a low level, all instruction fetching operations of the 80C51 are performed in the off-chip program memory, and the off-chip memory can be addressed starting from 0000H.
In the program memory, the following 6 units have special functions.
0000H: After 80C51 is reset, PC=0000H, that is, the program starts executing instructions from 0000H.
0003H: External interrupt 0 entry.
000BH: Timer 0 overflow interrupt entry.
0013H: External interrupt 1 entry.
001BH: Timer 1 overflow interrupt entry.
0023H: Serial port interrupt entry.
2. Data storage
The data memory is used to store intermediate operation results, data temporary storage and buffering, flags, etc. The 80C51 chip has 256B RAM, and up to 64KB RAM can be expanded outside the chip, forming two address spaces.
The on-chip data memory has an 8-bit address and can address up to 256 units. The lower 128B (00H~7FH) address area is the on-chip RAM, which can be accessed by direct addressing and indirect addressing. The higher 128B address area (80H~FFH) is a dedicated register area and can only be accessed by direct addressing.
In the lower 128B RAM area, the addresses 00H~1FH are the general working register area, which is divided into 4 groups, each group consists of 8 working registers (R0~R7), occupying a total of 32 units. The following table is the address table of the working registers. Each group of registers can be selected as the current working register of the CPU. The setting of RS1 and RS0 in the program status word PSW determines which group the CPU is currently using. If the program does not need 4 groups, the rest can be used as general data buffers. After the CPU is reset, the 0th group of working registers is selected.
Group | RS1 | RS0 | R0 | R1 | R2 | R3 | R4 | R5 | R6 | R7 |
0 | 0 | 0 | 00H | 01H | 02H | 03H | 04H | 05H | 06H | 07H |
1 | 0 | 1 | 08H | 09H | 0AH | 0BH | 0CH | 0D | 0E | 0FH |
2 | 1 | 0 | 10H | 11H | 12H | 13H | 14H | 15H | 16H | 17H |
3 | 1 | 1 | 18H | 19H | 1AH | 1BH | 1CH | 1DH | 1EH | 1FH |
The 16B after the working register area (i.e. 20H~2FH) can be accessed by bit addressing. The bit addresses of these 128 bits (bit address refers to the address of a binary bit) are 00H~7FH. They can be used as software flags or for 1-bit (Boolean) processing.
3. Special register SFR
80C51 has 21 special registers SFR, also known as special function registers. They are discretely distributed in the high 128 B addresses 80H~FFH of the on-chip data memory. Access to these special registers is only allowed by direct addressing. Special registers do not occupy the entire address space of 80H~FFH. Operations on idle addresses are meaningless. If an idle address is accessed, random numbers are read out.
Among the 21 special registers, 11 special registers have bit addressing capability and their byte addresses are exactly divisible by 8.
Note: Since SFRs are discretely distributed in the high 128 B addresses 80H~FFH of the on-chip data memory, when the defined data length is greater than 128 B bytes, it may conflict with the addresses of some SFRs, leading to unexpected results. Therefore, the data should be controlled within 128 B as much as possible, especially for arrays. If the data volume is large, xdata can be used to define it in external RAM.
like:
unsigned char xdata gTagId[2500*11] _at_ 0x0000; //Define the array gTagId. This data is stored in the external RAM and its starting address is specified as 0x0000.
unsigned short xdata gTagIdNum; //define data gTagIdNum.
Note the difference between the following definitions:
unsigned char * xdata pWriteTagId; //Define a pointer, which is stored in external RAM. The data type pointed to by this pointer is unsigned char.
unsigned char xdata *pWriteTagId; //Define a pointer, which is stored in the internal RAM. The data pointed to by this pointer is stored in the external RAM and its type is unsigned char.
unsigned char xdata * xdata pWriteTagId; //Define a pointer, which is stored in the external RAM. The data pointed to by this pointer is also stored in the external RAM, and its type is unsigned char.
For the use of external RAM, as long as the hardware connects the corresponding pins, the software does not need to make any settings and can directly use xdata to access it.
Understanding of 51 MCU memory
Many people have misunderstandings about the memory of 51 MCU. The most common ones are the following two:
① When the number of variables exceeds 128, the compact mode must be used for compilation.
The actual situation is that as long as the memory usage does not exceed 256.0, you can compile in small mode.
② Some addresses above 128 are used as special registers and cannot be used by programs.
Unlike PCs, 51 microcontrollers do not use linear addressing. Special registers and RAM use repeated addresses, but different instructions are used when accessing them, so they do not occupy RAM space.
Since the memory is relatively small, memory optimization is generally required to maximize memory usage efficiency.
Taking Keil C compiler as an example, in small mode, variables without storage type specified are defaulted to data type, that is, direct addressing, and can only access the lower 128 bytes. However, these 128 bytes are not all used by our program. Registers R0-R7 must be mapped to low RAM, which takes up 8 bytes. If register group switching is used, it will take up more.
Therefore, the maximum size of the data area that can be used is 120 bytes. If it exceeds 120 bytes, idata must be used to explicitly specify indirect addressing. In addition, the stack must occupy at least one byte, so the variables that can be defined can occupy 247 bytes in the extreme case. Of course, a one-byte stack is definitely not enough in actual applications, but if the number of nested call levels is not deep, more than a dozen bytes are enough.
In order to verify the above point of view, an example was written (the test environment is XP + Keil C 7.5).
#define LEN 120
data unsigned char tt1[LEN];
idata unsigned char tt2[127];
void main()
{
unsigned char i, j;
for(i = 0; i < LEN; ++i )
{
j = i;
tt1[j] = 0x55;
}
}
We can calculate R0-7(8) + tt1(120) + tt2(127) + SP(1) for a total of 256 bytes
The results of keil compilation are as follows:
Program Size: data=256.0 xdata=0 code=30
creating hex file from "./Debug/Test"...
"./Debug/Test" - 0 Error(s), 0 Warning(s).
This code has reached the memory allocation limit. If any global variables are defined or the array is increased, the compiler will report error 107. This raises a question: Why are variables i and j not included? This is because i and j are local variables, and the compiler will try to optimize them to register Rx or the stack. This is the problem. If there are too many local variables or local arrays are defined, the compiler cannot optimize them and must use RAM space. Although the allocation of global variables has been carefully calculated and does not exceed the usage range, memory overflow errors will still occur! Whether the compiler can successfully optimize the variables depends on the code.
In the above code, the loop is bloated and the variable j is completely unnecessary, so change the code to
unsigned char i;
unsigned char j;
for(i = 0; i < LEN; ++i )
{
tt1[i] = 0x55;
}
Compile again and see if there is an error! Because the compiler does not know how to use j, it cannot optimize. j must occupy RAM space, and RAM overflows. (A smarter compiler will automatically remove this useless variable, but this is not discussed here).
In addition, it is best to place the defined variables of idata after the data variables.
For this definition:
unsigned char c1;
idata unsigned char c2;
unsigned char c3;
The variable c2 will definitely be addressed indirectly, but it may fall in the data area, which wastes a directly addressable space.
There are a few things to note when optimizing variables:
① Let as many variables as possible use direct addressing to improve speed.
If there are two single-byte variables and a character array with a length of 119, it is impossible to define them all in the data area because the total length exceeds 120 bytes.
According to this principle, the definition method is as follows:
data unsigned char tab[119];
data unsigned char c1;
idata unsigned char c2;
But this is not absolute. If c1 and c2 need to be accessed very frequently, and tab access is not so frequent,
the variables with high access volume should use direct addressing:
data unsigned char c1;
data unsigned char c2;
idata UCHAR tab[119];
This should be determined according to the specific project requirements
② To improve the reuse rate of memory
is to use local variables as much as possible. Another advantage of local variables is that the access speed is relatively fast. From the previous example, it can be seen that local variables i and j do not occupy memory separately. Variables that do not use a large amount of memory in subroutines should be defined as local variables as much as possible.
③ For the definition of pointer array, specify the storage type as much as possible and try to use unsigned type variables. Generally, pointers require an extra byte to indicate the storage type. The 8051 series itself does not support signed numbers and requires an external library to process signed numbers. This greatly reduces the program running efficiency and requires additional memory.
④Avoid memory holes
You can view the previous code by looking at the compiler output symbol table file (.M51). The section about memory in the M51 file is as follows:
* * * * * * * DATA MEMORY * * * * * * *
REG 0000H 0008H ABSOLUTE "REG BANK 0"
DATA 0008H 0078H UNIT ?DT?TEST
IDATA 0080H 007FH UNIT ?ID?TEST
IDATA 00FFH 0001H UNIT ?STACK
The first line shows that register group 0 starts from address 0000H and occupies 0008H bytes.
The second line shows that the variables in the DATA area start from 0008H and occupy 0078H bytes.
The third line shows that the variables in the IDATA area start from 0080H and occupy 007F bytes.
The fourth line shows that the stack starts from 00FFH and occupies 0001H bytes.
Since the variable definitions in the previous code are relatively simple and all the space is used up continuously, the display here is relatively simple. When there are many variable definitions, there will be many lines here. If the allocation of global variables and local variables is unreasonable, lines like the following may appear:
0010H 0012H *** GAP ***
This line indicates that the bytes starting from 0010H for 0012H are not fully utilized or not used at all. The most common reasons for this situation are too many local variables, the number of local variables in multiple subroutines is too different, and register switching is used but not fully utilized.
Previous article:Microcontroller Learning Notes (IV) - Interrupts
Next article:How to adjust the baud rate in 51 single chip microcomputer serial port experiment
Recommended ReadingLatest update time:2024-11-15 07:23
- Popular Resources
- Popular amplifiers
- MCU C language programming and Proteus simulation technology (Xu Aijun)
- 100 Examples of Microcontroller C Language Applications (with CD-ROM, 3rd Edition) (Wang Huiliang, Wang Dongfeng, Dong Guanqiang)
- Fundamentals and Applications of Single Chip Microcomputers (Edited by Zhang Liguang and Chen Zhongxiao)
- Single chip microcomputer control technology (Li Shuping, Wang Yan, Zhu Yu, Zhang Xiaoyun)
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Studying the road to electric motor drive
- Help with op amp output sine wave signal analysis
- How to use Klipper99se?
- Q: What determines the amplifier power supply voltage range? What are the mainstream power supply ranges?
- GigaDevice GD Series System Solution Evaluation
- Learn about IO-Link and its five advantages
- 【RT-Thread Reading Notes】Reflections on RT-Thread Chapters 9-12
- 【NXP Rapid IoT Review】+ Familiar with the hardware
- 【Qinheng RISC-V core CH582】BLE lighting
- EEWORLD University ---- Altium Designer 4-layer smart car complete PCB design video tutorial