Many people have misunderstandings about the memory of 51 MCU. The most common ones are the following two:
① If 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 by special registers and cannot be used by programs.
Different from PC, 51 MCU does not use linear addressing, special registers and RAM use repeated addresses, but different instructions are used when accessing, so it does 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 default 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, I wrote an example
#define LEN 120
data UCHAR tt1[LEN];
idata UCHAR tt2[127];
void main()
{
FLY 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 result of keil compilation is as follows:
Program Size: data=256.0 xdata=0 code=30
creating hex file from ".DebugTest"...
".DebugTest" - 0 Error(s), 0 Warning(s).
(Test environment is XP + Keil C 7.5)
This code has reached the memory allocation limit. If you define any global variables or increase the size of the array, the compilation 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. Then change the code to
FLY i;
FLY 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 put the defined variables of idata after the data variables.
For this definition
fly c1;
idata uchar c2;
uchar c3;
The variable c2 will definitely be addressed indirectly, but it may fall into the data area, wasting 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, a character array with a length of 119
Because the total length exceeds 120 bytes, it is impossible to define it all in the data area
According to this principle, the definition is as follows:
data FLIGHT tab[119];
data UCAHR c1;
idata UCaR c2;
But it is not absolute. If c1 and c2 need to be accessed very frequently, but tab is accessed less frequently
Then you should use direct addressing for variables with high access volume:
data UCAHR c1;
data UCaR c2;
idata UCHAR tab[119];
This is determined based on specific project requirements.
② Improve memory reuse
That is to use local variables as much as possible. Another advantage of local variables is that they are accessed faster.
As can be seen from the previous example, local variables i and j do not occupy memory separately.
Variables that use a small amount of memory in a subroutine should be defined as local variables as much as possible.
③For the definition of pointer array, specify the storage type as much as possible
Try to use unsigned type variables
Generally, pointers require an extra byte to specify the storage type.
The 8051 series does not support signed numbers, and requires an external library to handle signed numbers. This greatly reduces program efficiency and requires additional memory.
④Avoid memory holes
You can view it by looking at the compiler output symbol table file (.M51)
For the previous code, the memory section in the M51 file is as follows:
* * * * * * * D A T A M E M O R Y * * * * * * *
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 bank 0 starts at 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 IDATA area variables start from 0080H and occupy 007F bytes
The fourth line shows that the stack starts at 00FFH and occupies 0001H bytes.
Since the variable definition in the previous code is 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 consecutive bytes from 0010H to 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:Very simple 8×8LED dot matrix c51 source code
Next article:Drivers for 93C46/93C06/93C46/93C56/93C66/93C86 (C51)
Recommended ReadingLatest update time:2024-11-16 17:53
- Popular Resources
- Popular amplifiers
- 西门子S7-12001500 PLC SCL语言编程从入门到精通 (北岛李工)
- Siemens Motion Control Technology and Engineering Applications (Tongxue, edited by Wu Xiaojun)
- Virtualization Technology Practice Guide - High-efficiency and low-cost solutions for small and medium-sized enterprises (Wang Chunhai)
- How to read electrical control circuit diagrams (Classic best-selling books on electronics and electrical engineering) (Zheng Fengyi)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- The calculation problem of frequency count value
- 13.56MHz ultra-low power contactless card reader chip Si522_Provide technical support
- EEWORLD University Hall----Sharing the application solution of sensorless FOC portable refrigerator based on Lingdong MM32SPIN series MCU
- I was fired for refusing to bring my computer home during the holidays, but the result was comfortable!
- DIY crystal radio that does not require power
- 【Smart Network Desk Lamp】3. ESP32-S2 + lvgl usage
- Is there any replacement for ATSAME51J20A?
- 【Renesas CPK-RA2L1 Development Board】Review - 0: Starting from IDE
- Low-side current sensing for high-performance, cost-sensitive applications
- Analog Characteristics of Digital Circuits