#include "reg51.h"
//sbit OE=P2^3;
unsigned int SystemTime;
void timer0(void) interrupt 1 using 3 //Interrupt code, see the explanation below
{
//
}
void main()
{
//According to the barrel metaphor below, if TH0 = 0x00; TL0 = 0x00; it means filling the barrel with water from the bottom.
//TH0 = 0xdb;TL0 = 0xff; This means that there is already some liquid lead in the barrel.
//TH0 and TL0 represent the height of the liquid lead in the barrel, that is, the barrel can only be filled with water from above the height of the liquid lead.
//TH0 = 0xff; TL0 = 0xff; which means the highest position of the bucket.
//The following is an infinite loop. TH0 and TL0 will increase with each step of the program. When TH0 = 0xff; TL0 = 0xff;
//The MCU will exit from the infinite loop and execute the interrupt code, i.e. start running void timer0(void) interrupt 1 using 3{}
//After running the interrupt part of the code, continue to execute the code in the infinite loop.
//Note: When TH0 = 0xff; TL0 = 0xff; runs again, TF0 does not change from 0 to 1. I guess that the interrupt was triggered when TF0=1; and it was reset to zero.
//If ET0 = 1; and EA=1; are commented out, when TH0 = 0xff; TL0 = 0xff; is run again, TF0 will become 1, and the interrupt code will not be executed.
}
Explanation: void Timer0() interrupt 1 using 1
Timer0
interrupt
0External
1Timer
2External
3
4Serial
In fact, when compiling, the entry address of your function is set to the jump address of the corresponding interrupt.
The y in using
Initial value algorithm: The timer generates an interrupt when the total reaches FFFFH! If you want it to count to 10000, should you use FFFF (hexadecimal) minus 10000 (decimal) as the initial value? TH0=-(10000/256); TL0=-(10000%6) is the same as FFFF (hexadecimal) minus 10000 (decimal). Start counting from TH0=-(10000/256); TL0=-(10000%6), and count to 10000. It is the same as using FFFF (hexadecimal) minus 10000 (decimal)!!! It is easier to write, no calculation required!!!
Just look at the original code and the complement code to know. The complement code of a positive number is the corresponding binary number with the sign bit as zero. The complement code of a negative number is the binary number corresponding to its absolute value, inverted bit by bit and then added by one, with the sign bit as one. Unsigned numbers do not consider the sign, so the result is the same as subtracting its absolute value from FFFF.
We have learned how to use commands to delay flashing, but using commands to flash has the disadvantage that the CPU cannot do other work.
In this lesson, we will learn how to use the timer method to make the light blink.
Interrupted understanding.
This involves the application of microcontroller interrupts. In the process of the CPU running according to the instructions step by step (main program), there may be other more urgent things to do (interrupt service program), which requires the CPU to temporarily stop the current program (main program). After completing (interrupt service program), it can continue to run the previous program (main program). It's like you are eating and filling the bucket with water. While eating, the water is full, you have to quickly turn off the faucet or change an empty bucket before coming back to eat.
The timer of the microcontroller is like a bucket. You start it, which means the faucet is turned on; it starts to fill with water; the timer automatically increases by 1 in each machine cycle and finally overflows; the water in the bucket keeps increasing and eventually it is full; when the timer overflows, you have to deal with it; when the bucket is full, you should also deal with it; after processing, the microcontroller can go back to where it just stopped and continue running; the bucket has been processed, and you can continue what you were doing before.
The main program of the microcontroller starts running from 0x0000. Where does the microcontroller service program start running? In 51, there are multiple interrupt service program entries. Entry 0 is external interrupt 0, the address is 0x0003; entry 1 is timer 0, at 0x000B; entry 2 is external interrupt 1, the address is 0x0013, entry 3 is timer 2, the address is 0x001B, and so on. When an interrupt occurs, the program records the current running position, jumps to the corresponding interrupt entry to run the interrupt service program, and after running, jumps back to the original position to continue running.
In C51, you don't need to worry about where the interrupt service routine is placed or how it will jump. You just need to mark a function as an interrupt service function. When the corresponding interrupt occurs, this function will be automatically run.
Please read the relevant 51 hardware books to learn more about the register settings of the timer. You can also learn after the experiment, because the routines have already set them for you.
Please look at the program. The loop in the main program is an infinite loop and does nothing. In actual application, the main program is placed here.
In the timer service function, you need to re-insert the timer value to ensure that each overflow is the time you specify. Here, 0x0006 is inserted, and it takes 0x10000-0x0006 machine cycles to overflow. Converted to decimal, it means an interruption every 65530 machine cycles. The crystal oscillator we simulated is 22118400HZ, and one machine cycle is every 12 clocks. 65530×12/22118400=0.036 seconds. That is, the flashing frequency is about 28HZ.
Because the maximum value of the 51 timer is only 0xffff, it overflows very quickly and cannot produce a longer flashing frequency. In this lesson, we will first observe the frequency of about 28HZ. In the next lesson, we will use the static variable method to make a LED flashing frequency of up to 1 second.
In addition, since the time from the occurrence of an interrupt to the entry of an interrupt is uncertain, it is 3 to 8 machine cycles. We reset the initial value of the timer after entering the interrupt, which will cause a timing error. In other words, it is not precise timing. If you want precise timing, you need to use the timer automatic loading method, that is, when the timer overflows, the hardware logic automatically loads the initial value of the timer, instead of assigning the initial value in the interrupt service program. In this way, precise timing can be achieved, and the error only occurs in the frequency of the crystal oscillator. This is the content of the next one.
Now please study the program carefully, compile it, enter simulation, run it at full speed, and observe the results. We can see that the LED on P10 is flashing quickly.
By the way, please also practice debugging methods such as stop, single step, breakpoint, etc.
A special point is that when using DX516 to run in single-step mode, you may not be able to enter the interrupt service function. This is because the interrupt function may have run past the moment of single-step processing. If you want to debug the interrupt service function in single-step mode, please set a breakpoint in the interrupt service function and then click full speed. After a while, it will stop at the breakpoint and you can continue to run in single-step mode.
Previous article:MSP430 interrupt C function template
Next article:MSP430 MCU ADC Module
Recommended ReadingLatest update time:2024-11-16 16: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
- How does Anlu FPGA output the clock to ordinary IO?
- Stack reuse in GD32VF103 multi-tasking applications
- [ATmega4809 Curiosity Nano Review] Wifi Controlled Lighting (IoT Led Part 2)
- 10UA current drive
- Practice together in 2021 + review my 2020
- What technology is generally used to convert Bluetooth WiFi to 0-10V in smart dimming?
- Busy like a top at the end of the year
- Battery SBS Glossary
- Good book recommendation: "Internet of Vehicles" helps the design of future intelligent driving
- Design based on LM5036: "Intelligent" half-bridge DC/DC power supply design