Abstract:
This paper introduces a simple method to implement multitasking mechanism in MCS51 single-chip microcomputer program, and gives source code and an application example. Real-time task switching through interruption has the advantages of simple and clear structure, small amount of code, and no need to use assembly. This method can also be applied to other single-chip microcomputer systems.
Keywords
: multitasking system single-chip microcomputer C51 interrupt security system
Introduction
Traditional single-chip microcomputer programs generally use a single-task mechanism. Single-task systems have the advantages of being simple, intuitive, and easy to control. However, since programs can only be executed sequentially, they lack flexibility and can only use interrupt functions to process some shorter tasks in real time, which is extremely inconvenient to use in more complex applications. The emergence of embedded multi-task operating systems solves this problem. In a multi-task system, multiple parallel tasks can be executed simultaneously, and tasks can jump to each other. However, while providing powerful functions, embedded operating systems also bring problems such as large code volume, complex structure, high hardware requirements, high development difficulty and high cost. In many cases, it is only necessary to implement simple multi-task operations to meet actual needs. This simple multi-task mechanism designed in this article can achieve multi-task operations without using assembly and making major changes to the original program, while only adding a very small amount of C language code.
The core of the real-time operating system RTOS is interrupts, which are used to switch tasks. In most RTOS, such as μC/OS-II, each task has its own stack to save some information about the task, and tasks transmit information through semaphores, mailboxes, message queues, etc. In many cases, these functions are not needed. All you need to do is switch the microcontroller to a different working state after receiving a control signal. That is, you only need to switch tasks, and there is no need to save task-related information. Abandoning these complex functions can make the program structure simple and easy to use.
Comparison of two mechanisms in application examples
Below is an application example to illustrate the idea of this design. To design an intelligent security system, its functions include: executing alarm work when someone invades; users can set functions through the keyboard board; the mainboard can communicate with the management center, and when disasters such as fire and earthquake occur, the management center can notify users. Its structure is shown in Figure 1. Under normal conditions, the CPU of the mainboard continuously scans the status of each sensor. When an abnormal signal from the sensor is detected (someone breaks in), the CPU enters the intrusion alarm state and executes tasks such as ringing the alarm, calling the owner's phone, and notifying the management center. When a fire or earthquake occurs, the management center sends a serial port code to the mainboard CPU, causing the CPU to enter the disaster alarm state and execute operations such as ringing the alarm and voice alarm. When the user needs to set functions, he can use the keyboard board to make the mainboard CPU enter the function setting state. Therefore, the mainboard CPU has 4 different working states.
Figure 1 Schematic diagram of the intelligent security system structure
If a single-task mechanism is adopted, the program flow of the main board is shown in Figure 2. In the main function, the sensor status is detected cyclically. If there is an abnormality, the alarm function is called. The disaster alarm and function setting are completed in the serial port interrupt. This single-task structure has two disadvantages. First, in various non-normal states, the program needs to constantly detect whether the removal signal is received. This requirement is difficult to achieve when the program code is large and the execution work is large. Secondly, it is very difficult to switch between states. In order to modularize, programs written in C language generally have a large number of functions and a large number of nested layers of function calls. It is very difficult to jump out of a deeper nest to the main function immediately. The general solution is to use the C51 library functions setjmp() and longjmp() to achieve long jumps, but these two functions are powerless inside the interrupt function; or embed assembly instructions in the C function. Although assembly instructions can be used to achieve long-distance jumps of programs, the debugging process of this method is very cumbersome, and the portability of the program is poor. For designers who are accustomed to programming in C51 and do not want to use assembly, this part of the program is a problem.
Figure 2 Single-task mechanism program flow
Program structure for implementing multi-tasking mechanism
This article provides a method to implement a highly portable multi-tasking program without using assembly instructions. The program flow is shown in Figure 3.
Figure 3 Multi-tasking structure program flow
The complete source code to implement this multi-tasking mechanism is as follows:
word idata PC_Value, SP_Value;
file://
Global variables that store interrupt return point and SP initial value
byte idata Ctrl_Code;
file://
Global variables that control task switching, which are assigned in the interrupt function
void main()
{
Initial();
file://Initialization
function, which has nothing to do with the program structure
SP_Value=SP;
file://Get
the initial value of SP
PC_Value=Get_Next_PC();
file://Get
the address of the next instruction
EA=1;
file://Get
the initial value of PC and SP before opening the interrupt to ensure stability
if(Ctrl_Code!=0)
SP=SP_Value;
file://Reset
the stack pointer to prevent stack overflow
switch(Ctrl_Code)
file://
Task entry address, that is, the return point of the interrupt
{
case 1: goto TASK1;
case 2: goto TASK2;
case 3: goto TASK3;
default: break;
}
TASK1: for( ; ; )
{
file://task
code 1 }
TASK2: for( ; ; )
{
file://task
code 2 }
TASK3: for( ; ; )
{
file://task
code 2 }
}
word Get_Next_PC(void)
file://get
the address of the next instruction
{
word address;
address=*((unsigned char *)SP);
file://PC
high byte
address <<= 8;
address+=*((unsigned char *)(SP-1));
file://PC
low byte
return address+4;
file://check
disassembly code, calculate
}
void Chuan_Kou_Interrupt(void) interrupt 4 using 0
{
byte a1,a2;
a1=a1*a2;
*((unsigned char *)(SP-5))=PC_Value>>8;
*((unsigned char *)(SP-6))=PC_Value & 0x00ff;
{
file://Receive
Serial port code and modify the value of Ctrl_Code according to the code
file://Other
Operations
}
}
Task Scheduling Principle and Implementation
The overall idea of the program is to place several infinite loops in the main function as the task framework, that is, each task is an infinite loop, and use interrupts to switch tasks. Taking the security system mentioned above as an example, since the motherboard, keyboard, and management center communicate through the serial port, the serial port is an ideal interrupt source for triggering task switching. The program sets a general entrance for all tasks and puts it in the main function. Every time the serial port interrupt returns, it must first pass through this general entrance. At the general entrance, the value of the task control variable (global variable) is checked. The task control variable has been assigned in the serial port interrupt, and its value determines which task to switch to.
In the design, the normal state, intrusion alarm state, crisis alarm state, and function setting state can be used as task 1, task 2, task 3, and task 4 respectively. The motherboard CPU usually works in the normal state, that is, task 1; when the serial port receives the crisis code from the management center, Ctrl_Code = 3 is set in the serial port interrupt function, and the interrupt will switch to task 3 after returning; similarly, after receiving the keyboard function setting code, it will switch to task 4; because the motherboard CPU is responsible for intrusion detection, if it detects an intrusion and needs to switch to the intrusion alarm state, it can generate a serial port interrupt through the keyboard, that is, send a serial port data to the keyboard and ask the keyboard to send it back. In this way, the switching of various states is realized.
To realize task scheduling, three key problems need to be solved:
① Get the program address of the task entry point. Since the value of the program counter PC cannot be directly obtained and modified using C language, the PC value will be pushed into the stack when calling a function. Using this feature, the Get_Next_PC function can be called before the task entry to obtain the entry address from the stack. In Get_Next_PC, SP is the stack pointer, and the PC value obtained must be added by 4 to obtain the task entry address, because looking at the disassembly window, it can be seen that two 2-byte mov instructions are required to pass the function return value to the global variable PC_Value.
② Modify the interrupt return address. The operation of modifying the interrupt return address is similar to obtaining the PC value, and is implemented by modifying the contents in the stack. However, due to the characteristics of the compiler itself, when entering the interrupt, in addition to pushing the return address into the stack, the compiler will also calculate the changes to registers ACC, B, DPH, DPL, PSW, R0 ~ R7 by itself and the functions it calls, and also push the registers it thinks have been changed into the stack for protection. If the stack structure changes with the content of the interrupt function, there is no way to calculate the position in the interrupt return address stack. The solution is to add the keyword using 0 when defining the interrupt function to tell the compiler that the interrupt function and the functions it calls will use register group 0, so that the working registers R0 ~ R7 will not be saved. ACC, PSW, DPH, and DPL have been used in the operation of PC_Value. At the beginning of the interrupt function, define two variables a1 and b1 and multiply them so that register B is also pushed into the stack, so that the stack structure is fixed.
③Prevent stack overflow. Since the compiler will push the current address into the stack when calling a function and pop it when returning, when task switching or interruption occurs multiple times during the function call, the stack will eventually overflow because it can only be entered but not exited. This is not allowed. Therefore, the SP value should be saved immediately after initialization at the beginning of the main function, and then SP should be restored to its initial value after each task switch, which can effectively prevent stack overflow.
Conclusion
According to the above comparison and analysis, it can be seen that this method of implementing a multi-tasking mechanism has the following advantages: compared with programs that use a single-tasking mechanism, its structure is simple and clear, and it is easy to control; it uses interrupts and stacks to implement long jumps when switching tasks, and does not require the use of assembly language at all, and has strong portability; the amount of additional code is extremely small, the real-time performance is good, and program development time is saved.
The above-mentioned method has been tested and applied to several actual projects, including smart community security systems, automotive CAN bus control systems, etc., and has achieved good results. As long as it is slightly modified according to the specific hardware and compilation environment, it can also be applied to other single-chip microcomputer systems.
References
1. Zhang Peiren. Principles and Applications of MCS-51 Microcontrollers Based on C Language Programming. Beijing: Tsinghua University Press, 2003.1.
2. Hu Dake et al. Embedded Development Guide Based on Single-Chip Microcomputer 8051. Beijing: Publishing House of Electronics Industry, 2003.1
Previous article:Design of automatic line patrol wheel robot control system based on single chip microcomputer
Next article:Design of digital frequency meter based on MSP430F449
- Popular Resources
- Popular amplifiers
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
- [Flower carving hands-on] Interesting and fun music visualization series of small projects (19) - full-body fiber optic lamp
- Detailed explanation of the principle of lora spread spectrum technology
- Questions about oscilloscope and USB flash drive
- Show the certificate of Microchip Security Solutions Seminar
- STM32 output 4-20MA or 0-10V circuit sharing
- EEWORLD University ---- Digital Circuit Design
- Allwinner heterogeneous multi-core AI intelligent vision V853 development board evaluation + ubuntu20 installation LiveSuit nanny-level tutorial
- Disassembled a solar lamp
- 【NUCLEO-L552ZE Review】+ Various lighting patterns
- Summary: About 2.4G NRF24L01 wireless module