After solving the accuracy problem, let's go back to our motor control program. The two routines given above are not practical programs. Why? Because there are long delays in the program, and nothing else can be done during the delay. Think about the second program, nothing else can be done for 200 seconds, which is absolutely not allowed in the actual control system. So how to modify it? Of course, it is still done with timer interrupts. Since each beat lasts for 2ms, we can directly use the timer to time 2ms to refresh the beat. The modified program is as follows:
#include
unsigned long beats = 0; //Total number of motor rotation beats
void StartMotor(unsigned long angle);
void main(){
EA = 1; // Enable general interrupt
TMOD = 0x01; //Set T0 to mode 1
TH0 = 0xF8; //Assign the initial value 0xF8CD to T0, and set the timing to 2ms
TL0 = 0xCD;
ET0 = 1; // Enable T0 interrupt
TR0 = 1; //Start T0
StartMotor(360*2+180); //Control the motor to rotate 2 and a half circles
while (1);
}
/* Stepper motor start function, angle-the angle to be rotated*/
void StartMotor(unsigned long angle){
// Turn off interrupts before calculation and turn them on after completion to avoid interrupts interrupting the calculation process and causing errors
EA = 0;
beats = (angle * 4076) / 360; //The actual measurement is 4076 beats per rotation
EA = 1;
}
/* T0 interrupt service function, used to drive the stepper motor to rotate*/
void InterruptTimer0() interrupt 1{
unsigned char tmp; //temporary variable
static unsigned char index = 0; //beat output index
unsigned char code BeatCode[8] = { //IO control code corresponding to the stepper motor beat
0xE, 0xC, 0xD, 0x9, 0xB, 0x3, 0x7, 0x6
};
TH0 = 0xF8; //Reload initial value
TL0 = 0xCD;
//If the beat number is not 0, a driving beat is generated
if (beats != 0){
tmp = P1; //Use tmp to temporarily store the current value of port P1
tmp = tmp & 0xF0; // Use & to clear the lower 4 bits
//Use the | operation to write the beat code to the lower 4 bits
tmp = tmp | BeatCode[index];
//Send the lower 4-bit beat code and the upper 4-bit original value back to P1
P1 = tmp;
index++; //beat output index increment
index = index & 0x07; //Use & operation to return to 8
beats--; //Total beats - 1
}else{ //If the number of beats is 0, turn off all phases of the motor
P1 = P1 | 0x0F;
}
}
The program is relatively simple. The motor startup function StartMotor is only responsible for calculating the total number of beats required, and then checking this variable in the interrupt function. If it is not 0, the beat operation is performed and it is reduced by 1 until it is reduced to 0.
Here, we need to explain the two operations on EA in the StartMotor function. We can see that the assignment calculation statement for beats is sandwiched between the two statements EA=0;EA=1;, which means that this line of assignment calculation statement turns off the interrupt before execution, and turns it back on after it is executed. During its execution, the microcontroller will not respond to the interrupt, that is, the interrupt function InterruptTimer0 will not be executed. Even if the timer overflows and an interrupt occurs, it can only get a response after EA is reset to 1, and the interrupt function InterruptTimer0 will be executed.
So why do we do this? Let's think about it: At the beginning of this book, we mentioned that the STC89C52 microcontroller we use is an 8-bit microcontroller. The concept of 8 bits means that the microcontroller operates data in 8 bits, that is, 1 byte. Therefore, to operate multiple bytes (whether reading or writing), it must be done multiple times. The beats variable defined in our program is an unsigned long type, which occupies 4 bytes, so its assignment must be completed at least 4 times. Let's imagine that after completing the assignment of the first byte, an interrupt happens to occur, and the InterruptTimer0 function is executed. In this function, beats may be subtracted by 1. The subtraction may cause a borrow, and the borrow will change other bytes. However, because the other bytes have not been assigned new values at this time, an error will occur, and the result of subtracting 1 is not the expected value! Therefore, to avoid this error, you must temporarily turn off the interrupt and turn it on again after the assignment is completed. If we use char or bit variables, because they are completed in one operation of the CPU, no error will occur even if the interrupt is not disabled. The problem has been analyzed clearly, and how to choose depends on the actual situation. When encountering such problems, please consider them more.
Previous article:Simple Addition Calculator
Next article:Practical Motor Control Program
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
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- 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!
- Thirty-three MCU (microcontroller) input/output interface circuits
- EEWORLD University Hall----Using JTAG with UCD3138
- EEWORLD University Hall----Live Replay: TE explains the design trends of smart antennas and sensor application cases in the Internet of Things
- PDIUSBD12 Send mode command, soft connection does not work
- .DSN file is garbled when opened.
- Security Technology System of Wireless WLAN
- In-depth understanding of C language function parameters as pointers
- EEWORLD University Hall ---- The first stop of the ADI Road theme tour of Shijian: Industrial Automation
- Spring for Beijing mobile users: mobile rates have finally been reduced!
- AD20 Installation Issues