I don’t know if you have such a feeling, that is, you feel that you can play with a microcontroller and each functional module can be driven. But if you are asked to write a complete set of code, but there is no logic and framework at all, just start writing! Copying from east to west shows that programming is still at a relatively low level. So, how can you improve your programming skills?
Learning a good programming framework or a programming idea may be useful for life! For example, modular programming, framework programming, state machine programming, etc. are all good frameworks.
What we are talking about today is state machine programming. Since it is quite long, please take your time to enjoy it. So, what kind of thing is a state machine?
A state machine has five elements, namely state, transition, event, action, and guard.
What is a state machine?
A state machine is something like this: a state machine has five elements, namely state, transition, event, action, and guard.
State: The stable working condition of a system at a certain moment. The system may have multiple states throughout the entire work cycle. For example, a motor has three states: forward rotation, reverse rotation, and stalled rotation.
A state machine needs to select a state from the state set as the initial state.
Migration: The process of a system moving from one state to another is called migration. Migration does not happen automatically and requires external influence on the system. A stalled motor will not start on its own, so it must be powered on.
Event: Something meaningful to the system occurs at a certain moment. The reason why the state machine undergoes state transition is because of the occurrence of events. For motors, adding positive voltage, adding negative voltage, and cutting off power are events.
Action: During the migration process of the state machine, the state machine performs some other behaviors. These behaviors are actions. Actions are the state machine's response to events. Applying positive voltage to the stalled motor will cause the motor to move from the stalled state to the forward rotating state, and at the same time it will start the motor. This starting process can be regarded as an action, that is, a response to the power-on event.
Conditions: The state machine is not responsive to events. With events, the state machine must meet certain conditions before state transition can occur. Let's take the motor in the stalled state as an example. Although it is closed and powered on, if there is a problem with the power supply line, the motor still cannot start.
Just talking about the concept is too empty. The previous small example: one microcontroller, one button, two LED lights (recorded as L1 and L2), and one person is enough!
Rule description:
1. L1L2 state transition sequence OFF/OFF--->ON/OFF--->ON/ON--->OFF/ON--->OFF/OFF
2. Control the state of L1L2 by pressing buttons. Each state transition requires pressing the button 5 times continuously.
3. L1L2 initial state OFF/OFF
figure 1
The following program is code written according to functional requirements.
Program list List1:
void main(void)
{
sys_init();
led_off(LED1);
led_off(LED2);
g_stFSM.u8LedStat = LS_OFFOFF;
g_stFSM.u8KeyCnt = 0;
while(1)
{
if(test_key()==TRUE)
{
fsm_active();
}
else
{
; /*idle code*/
}
}
}
void fsm_active(void)
{
if(g_stFSM.u8KeyCnt > 3) /*Whether the keystrokes have been completed 5 times*/
{
switch(g_stFSM.u8LedStat)
{
case LS_OFFOFF:
led_on(LED1); /*Output action*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_ONOFF; /*Status migration*/
break;
case LS_ONOFF:
led_on(LED2); /*Output action*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_ONON; /*Status migration*/
break;
case LS_ONON:
led_off(LED1); /*Output action*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFON; /*Status migration*/
break;
case LS_OFFON:
led_off(LED2); /*Output action*/
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFOFF; /*Status migration*/
break;
default: /*illegal status*/
led_off(LED1);
led_off(LED2);
g_stFSM.u8KeyCnt = 0;
g_stFSM.u8LedStat = LS_OFFOFF; /*Restore initial state*/
break;
}
}
else
{
g_stFSM.u8KeyCnt++; /*The status does not migrate, only the number of keystrokes is recorded*/
}
}
In fact, in state machine programming, the correct order should be to have the state transition diagram first, then the program. The program should be written based on the designed state diagram. However, considering that some children may think that code is more friendly than conversion diagram, I will put the program first.
This state transition diagram is drawn using the syntax elements of UML (Unified Modeling Language). The syntax is not very standard, but it is enough to explain the problem.
Figure 2 Button control flow lamp state transition diagram
The rounded rectangle represents each state of the state machine, and the name of the state is marked inside.
The straight lines or arcs with arrows represent state transitions, starting from the initial state and ending in the secondary state.
The text content in the picture is a description of the migration, and the format is: event [condition]/action list (the last two items are optional).
The meaning of "event [condition]/action list" is: if an "event" occurs in a certain state, and the state machine satisfies the "[condition]", then the state transition must be executed and an event must be generated. A series of "actions" in response to an event. In this example, I use "KEY" to represent keystroke events.
There is a solid black dot in the figure, which represents an unknown state that the state machine is in before it works. Before running, the state machine must be forcibly migrated from this state to the initial state. This migration can have an action list (as shown in the figure) 1), but no event triggering is required.
There is also a circle containing a solid black dot in the figure, which represents the end of the state machine's life cycle. The state machine in this example is endless, so there is no state pointing to the circle.
I won’t say much about this state transition diagram. I believe you can easily understand it based on the above code. Now let's talk about the program list List1.
Let’s take a look at the fsm_active() function first. g_stFSM.u8KeyCnt = 0; this statement appears 5 times in switch-case. The first 4 times appear as actions for each state migration. From the perspective of code simplification and efficiency improvement, we can completely merge these 5 times into 1 and put it before the switch-case statement. The effect of the two is exactly the same. The reason why the code is so verbose is to clearly indicate All the action details in each state transition are completely consistent with the intention expressed by the state transition diagram in Figure 2.
Take another look at the g_stFSM state machine structure variable. It has two members: u8LedStat and u8KeyCnt. Using this structure to make a state machine seems a bit cumbersome. Can we just use an integer variable like u8LedStat to make the state machine?
sure! We split each of the 4 states in Figure 2 into 5 small states, so that this state machine can also be implemented with 20 states, and only one unsigned char type variable is enough, and each keystroke will trigger Status migration can change the status of the LED light every 5 times. From the outside, the effects of the two methods are exactly the same.
Suppose I change the functional requirements from 5 consecutive keystrokes to change the state of L1L2 to 100 consecutive keystrokes to change the state of L1L2. In this case, the second method requires 4X100=400 states! Moreover, there must be 400 cases in the switch-case statement in the function fsm_active(). Is there any way to write such a program? !
For the same functional change, if you use the g_stFSM structure to implement the state machine, the function fsm_active() only needs to change if(g_stFSM.u8KeyCnt>3) to if(g_stFSM.u8KeyCnt > 98)!
Among the two members of the g_stFSM structure, u8LedStat can be regarded as a qualitative change factor, equivalent to the main variable; u8KeyCnt can be regarded as a quantitative change factor, equivalent to the auxiliary variable. The gradual accumulation of quantitative factors will trigger changes in qualitative factors.
A state machine like g_stFSM is called an Extended State Machine. I don’t know how to use the formal Chinese terminology in the industry, so I had to move the English phrase over.
2. Advantages of state machine programming
Having said so much, everyone probably understands what a state machine is, and how to write a state machine-based program. So what are the benefits of using a state machine method to write a microcontroller program?
(1) Improve CPU usage efficiency
In other words, whenever I see a program full of delay_ms(), I get sick. Software delays of tens of milliseconds and dozens of milliseconds are a huge waste of CPU resources. Precious CPU time is wasted on NOP. on instructions. That kind of program that stays still just waiting for a pin level jump or a serial port data also makes me very entangled. If the event never happens, do you want to wait until the end of the world?
By turning the program into a state machine, this situation will be significantly improved. The program only needs to use global variables to record the working status, and then it can turn around and do other work. Of course, after finishing those tasks, you should check to see if there is any change in your work status. As long as the target event (timing has not arrived, the level has not jumped, and the serial port data has not been completed) has not occurred, the working status will not change, and the program will keep repeating "query-do something else-query-do something else". Loop, so that the CPU will not be idle.
In the program list List3, the content under else in the if{}else{} statement (not added in the code, just a comment indicating /*idle code*/) is the "other work" mentioned above.
Previous article:Selection of microcontroller, a few steps that have to be mentioned
Next article:Doesn’t the microcontroller deserve to be called embedded? What is the relationship between embedded and microcontroller?
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!
- Rambus Launches Industry's First HBM 4 Controller IP: What Are the Technical Details Behind It?
- 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
- Shengbangwei's lithium battery management chip and high current op amp
- Altium Designer 20 released
- FPGA_100 Days Journey_Infrared Remote Control System Design.pdf
- The microchip Harmony interface is different from the tutorial
- FAQ_How to convert Tmall Genie triples to the format used by ST mesh code
- EEWORLD University Hall----What can be easily charged?
- Share the steps of DSP development
- The long-awaited Digi-Key STM32F7508-DK and MAiX Bit unboxing notes
- It is customary to connect a 120Ω resistor between RS485 interface AB and CAN interface H and L. I only have 100Ω in stock. Can it be replaced?
- [NXP Rapid IoT Review] Online IDE Experience