I have read a lot of relevant information on the question of "Why AVR uses writing 1 as a means to clear the interrupt flag bit". The AVR manual does not explain why, but only emphasizes "writing 1 to clear the interrupt flag bit". At the same time, I have also seen many new chips, such as DSP, which also use writing 1 to clear the flag bit. But I have not found a more professional or fundamental explanation. If anyone has knowledge or information in this area, you are welcome to discuss and learn in depth.
The following is my personal analysis and explanation for reference.
1. First of all, from the hardware perspective, the usual read and write processing unit is based on 8BIT bytes, because the data bus is generally a multiple of 8 bits. This makes it inconvenient to operate on bits. You cannot directly write 1 bit (which will change other bits). You need to read the register first, then change 1 bit, and finally write back, which takes more time.
2. For RAM operations, direct writing is generally used, so there is basically no direct bit operation instruction for RAM. For registers, direct bit operations can be performed, but if bit operations can be implemented for all registers, the hardware structure will be very complex and large, so a compromise must be adopted.
3. The current trend is to use C language to write system programs, but in standard C, there is no concept of bit variables, and the smallest unit is also byte. Therefore, the hardware design should also consider the advantages of C language.
The above is the reason for my analysis. Because it has exceeded the direction of my research (I focus on application), it may not be comprehensive or biased. Let's go back to AVR itself.
We can notice:
1. AVR has no "bit" space, that is, there is no separate "bit" address. All bit addressing is based on 8-bit registers, so the basic addressing method is mainly based on registers.
2. Therefore, AVR does not have special bit addressing instructions. It has very few bit operation instructions. They all operate on a certain bit of the register based on register addressing.
3. In addition to direct operation instructions for the bits in the status register SREG (SREG is too special and must have dedicated bit operation instructions), there are only 2 instructions that can operate on the bits of other registers.
a) BST, BLD. The cycle of this instruction is 1CK. It is an instruction to exchange data between the T flag bit in SREG and the bits of 32 general registers. If you want to set one bit of 32 registers (for example, set it to 1), you must first use an instruction to set T in SREG to 1, and then use the BLD instruction to write the value of T to a certain bit of the register. It takes 2 CKs.
b) SBI, CBI. These two instructions are instructions for setting the bits of the registers in the first 32 (note: only the first 32 I/O spaces!) I/O spaces. The execution time of these two instructions is 2 CKs. Most of the instructions for AVR register operations are 1 CK, so why do these two instructions require 2 CKs? The reason is that when writing, 8 bits are still written together, so to change 1 bit, you need to read it first, modify 1 bit, and then write it back. This ensures that other bits remain unchanged, but it takes 2 CKs.
4. It is precisely because of point 3 (b) that the registers of I/O ports such as PA, PB, PC, PD, etc. are all in the first 32 I/O spaces, so that convenient individual bit-by-bit control of I/O ports is achieved.
5. Different C compilers have different bit processing. ICC and IAR basically have no extended bit processing, and they process it according to standard C because they consider portability more. CVAVR expands bit variables (placed in 32 working registers) and bit operations (only for the first 32 registers in the I/O space), so it is more convenient for users to use. But please note that CVAVR cannot implement bit operations for the last 32 registers in the I/O space.
=======================================================
Finally, let's take a look at the processing of interrupt flag bits. In AVR, the processing of interrupt flag bits adopts different processing methods according to different situations, which has been explained in the English description above. Some are cleared by hardware when entering the execution interrupt, and some are cleared by hardware after reading a certain register. Software clearing usually writes "1", why?
Looking at the manual of M16, we find that the external interrupt flag register GIFR (0X3A) and the interrupt flag register TIFR (0X38) of T/C are all in the last 32 addresses of the I/O space, and all of them are interrupt flag registers. Therefore, whether it is ICC, IAR, or CVAVR, you cannot use SBI and CBI instructions for bit operations, and you can only write 8 bits of a register at the same time.
So, how do you usually change 1 position to 1 in C? Usually everyone thinks that the correct statement is: XXXX |= 0B00000001; its function is to read XXXX first, and then OR it with 0B00000001, so that the lowest bit is 1, and the other bits remain unchanged. Actually, 3 assembly instructions are required. Change 1 position to 0: XXXX &= 0B11111110; also requires 3 assembly instructions.
AVR uses writing "1" to clear "0" interrupt flag (writing "0" does not affect the flag), so the statement can directly use TIFR = 0B00000001, and only two assembly lines are needed. Clear the lowest flag bit to "0" while ensuring that other flag bits remain unchanged. (!!! Note that it is wrong to use TIFR |= 0B00000001!!! Because if other bits are 1, they will be cleared instead)
In addition, if writing "0" clears the "0" interrupt flag bit, then how should it be defined if writing "1" to the interrupt flag bit? The interrupt flag bit should be set to 1 by hardware. If the software can set it to 1, it will bring more trouble.
In fact, the above English explanation is still incomplete and easy to cause some misunderstandings.
a) Only TIFR = 0B00000001 can be used for TIFR and GIFR, because only these two registers are all interrupt flag bits.
b) For some other interrupt flags, if there are some non-interrupt flags in the register where they are located, you must use the writing method of XXXX |= 0B00000001.
c) For the setting of non-interrupt flags, you must still use the form of XXXX |= 0B00000001.
===
...
Previous article:Using the Arduino Minimum System Board as an AVR MCU Programmer
Next article:IARAVR interrupt service routine problem
Recommended ReadingLatest update time:2024-11-15 14:28
- Popular Resources
- Popular amplifiers
- Principles and Applications of Single Chip Microcomputers 3rd Edition (Zhang Yigang)
- Metronom Real-Time Operating System RTOS for AVR microcontrollers
- Learn C language for AVR microcontrollers easily (with video tutorial) (Yan Yu, Li Jia, Qin Wenhai)
- ATmega16 MCU C language programming classic example (Chen Zhongping)
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Brief Analysis of Automotive Ethernet Test Content and Test Methods
- How haptic technology can enhance driving safety
- EEWORLD University Hall ---- Fundamentals of Circuit Theory by Zhao Jinquan, Xi'an Jiaotong University
- Anxinke NB-IoT module review - some speculation about the failure of CH340
- Introducing a newly invented bandwidth amplifier circuit: "Angel"
- Embedded Qt-FFmpeg design an RTSP player
- dsp28335 ADC differential sampling
- Book Festival is coming, let me recommend a wave of must-read books on electromagnetic waves and microwave radio frequency
- [NXP Rapid IoT Review] W2 web development platform trial
- Why Sub-1 GHz RF?
- [Anxinke UWB indoor positioning module NodeMCU-BU01] 02: Module ranging performance actual measurement ranging accuracy test
- The Sound of Silence: Unveiling the Virtual Engine Sound System of Electric Vehicles