In the development and application of single-chip microcomputers, high-level languages have gradually been introduced, and C language is one of them. For those who are used to assembly, they always feel that high-level languages are not as controllable as assembly. However, as long as we have a certain knowledge of C language, some things are still easy to do. The following are several problems encountered by the author in actual work, hoping to help beginners of C51.
1. Compilation of C51 hot start code
For industrial control computers, there is often a watchdog circuit. When the watchdog is activated, the computer is reset, which is a hot start. When hot starting, it is generally not allowed to start from the beginning, which will cause the existing measured or calculated values to be reset, resulting in abnormal system operation. Therefore, when the program must determine whether it is a hot start or a cold start, the commonly used method is: determine a certain memory unit as a flag bit (such as 0x7f bit and 0x7e bit), first read the content of the memory unit when starting, if it is equal to a specific value (for example, both memory units are 0xaa), it is considered a hot start, otherwise it is a cold start, the program executes the initialization part, and assigns 0xaa to the two memory units.
According to the above design ideas, when programming, set a pointer to point to a specific memory unit such as 0x7f, and then judge it in the program. The program is as follows:
void main()
{ char data *HotPoint=(char *)0x7f;
if((*HotPoint==0xaa)&&(*(--HotPoint)==0xaa))
{ /*Hot start processing*/
}
else
{ HotPoint=0x7e; /*Cold start processing
*HotPoint=0xaa;
*(++HotPoint)=0xaa;
}
/*Normal working code*/
}
However, in actual debugging, it is found that no matter it is hot start or cold start, the values of all memory units are reset to 0 after startup, and of course the hot start requirement cannot be achieved. Why is this? It turns out that when programming in C language, the code executed at startup does not start from the first statement of the main() function. Before the first statement of the main() function is executed, a section of "starting code" must be executed first. It is this section of code that performs the clearing work. The C compiler provides the source code of this startup code, named CSTARTUP.A51. Open this file and you can see the following code:
.
IDATALEN EQU 80H ; the length of IDATA memory in bytes.
.
STARTUP1:
IF IDATALEN <> 0
MOV R0,#IDATALEN - 1
CLR A
IDATALOOP: MOV @R0,A
DJNZ R0,IDATALOOP
ENDIF
.
It can be seen that before executing the code to determine whether to hot start, the startup code has cleared all memory units. How to solve this problem? Fortunately, the startup code can be changed. The method is: modify the startup.a51 source file, then use the a51.exe program attached to the compiler to compile startup.a51 to get the startup.obj file, and then use this code to replace the original startup code. The specific steps are (assuming that the C source program is named HOTSTART.C):
modify the startup.a51 source file (this file is in the C51LIB directory).
Execute the following command:
A51 startup.a51 to get the startup.obj file. Copy this file to the directory where HOTSTART.C is located.
Compile the compiled C source program with C51.EXE to get the target file HOTSTART.OBJ.
Use the L51 HOTSTART, STARTUP.OBJ command to connect and get the absolute target file HOTSTART.
Use OHS51 HOTSTART to get the HOTSTART.HEX file.
Modify startup.a51 according to your own needs. For example, change 80H in IDATALEN EQU 80H to 70H, so that the 16-byte memory from 6F to 7F will not be cleared.
2. Directly call the program that has been fixed in EPROM
The emulator used by the author is displayed by a 6-digit digital tube. The display subroutine is placed at DE00H in the memory. As long as the number to be displayed is placed in the display buffer, and then this subroutine is called, it can be used. The assembly instruction is:
LCALL 0DEOOH
[page]
type identifier (* pointer variable name) ();
After defining the pointer, you can assign a value to the pointer variable to point to the starting address of a function, and then use
(* pointer variable name) () to call this function. As shown in the following example:
void main (void)
{
void (*DispBuffer) (); /* define pointer to function */
DispBuffer = 0xde00; /* assign value */
for (;;)
{ Key ();
DispBuffer ();
}
}
3. Convert floating point numbers to character arrays
When compiling an application, the author has such a requirement: store the result of the operation (floating point number) in EEPROM. We know that floating point numbers are stored in IEEE format in C language. A floating point number occupies four bytes. For example, the floating point number 34.526 is stored as (160, 26, 10, 66). To store a floating point number in EEPROM, you actually need to store these four numbers. So how do you get the components of a floating point number in a program?
When floating point numbers are stored, they are stored in consecutive bytes. As long as you try to find the storage location, you can get these numbers. You can define a void pointer, point this pointer to the floating point number you need to store, and then force this pointer to be converted to a char type. In this way, you can use the pointer to get the values of the bytes that make up the floating point number. The specific program is as follows:
#define uchar unsigned char#define uint unsigned intvoid FtoC(void)
{ float a;
uchar i,*px
uchar x[4]; /*Define a character array to prepare to store four bytes of floating point numbers*,
void *pf;
px=x; /*px pointer points to array x*/
pf=&a; /*void pointer points to the first address of the floating point number*/
a=34.526;
for(i=0;i<4;i++)
{ *(px+i)=*((char *)pf+i); /*Force the void type pointer to be converted to char type, because*/
} /*void type pointer cannot be calculated*/
}
If the number has been stored in EEPROM and you want to take it out and merge it, the method is the same. You can refer to the program below.
#define uchar unsigned char#define uint unsigned int
void CtoF(void)
{ float a;
uchar i,*px
uchar x[4]={56,180,150,73};
void *pf;
px=x;
pf=&a;
for(i=0;i<4;i++)
{ *((char *)pf+i)=*(px+i);
}
}
The C language used above is F RANKLIN C51 VER 3.2.
Previous article:Method of cracking the internal password of single chip microcomputer
Next article:Programming Skills of EH78 Series MCU
Recommended ReadingLatest update time:2024-11-17 00:38
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
- Pressure sensor temperature compensation
- PID regulation problem
- E2lite emulator connection failed
- Miniaturized millimeter wave sensors enabled by CMOS technology
- Award Ceremony: Follow cruelfox and check in to learn FreeRTOS. Winners and their learning sharing
- Altera series FPGA chip IP core detailed explanation.pdf
- After more than 20 years, why are domestic CPUs still not good enough? Source: Coder’s Turn
- Happy Queen's Day
- Help 200VDC-DC to 5V power management chip
- The kernel of the free version of rt-thread is really too bad...