“I have read a lot of relevant information on the question “Why does AVR use writing 1 as a means of clearing the interrupt flag to 0”. The AVR manual does not give an explanation of why, but only emphasizes “write 1 to clear the interrupt flag bit”. At the same time, I also see that many new chips, such as DSP, also use writing 1 to clear the flag bit. But I haven’t found a more professional or root-based explanation. If that person has knowledge or information in this area, in-depth discussions are welcome.
“
I have read a lot of relevant information on the question “Why does AVR use writing 1 as a means of clearing the interrupt flag to 0”. The AVR manual does not give an explanation of why, but only emphasizes “write 1 to clear the interrupt flag bit”. At the same time, I also see that many new chips, such as DSP, also use writing 1 to clear the flag bit. But I haven’t found a more professional or root-based explanation. If that person has knowledge or information in this area, in-depth discussions are welcome.
Below is my personal analysis and explanation for reference.
1. First of all, from the consideration of hardware, the usual read and write processing unit is based on 8BIT bytes, because the data bus is generally a multiple of 8 bits. In this way, the operation of the bit is inconvenient. You cannot directly write 1 bit (it 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 the RAM operation, the direct write method is generally adopted, so there is basically no direct bit operation instruction for the RAM. For registers, bit operations can be performed directly, but if bit operations can be implemented for all registers, the hardware structure is very complicated and huge, so a compromise processing method must be adopted.
3. The current trend is to use C language to write system programs. In standard C, there is no concept of bit variables, and the smallest unit is also a byte. Therefore, the design of hardware should also consider the advantages of C language.
The above is the reason for my analysis. May be incomplete or biased because it is beyond the direction of my research (I focus on applications). Now back to the AVR itself.
We can notice:
1. AVR has no “bit” space, that is to say, there is no separate “bit” address, all bit addressing is based on 8-bit registers, so the basic addressing mode is based on registers.
2. Therefore, AVR does not have special bit addressing instructions, and its own bit manipulation instructions are few, all of which operate on a certain bit of the register on the basis of register addressing.
3. In addition to the direct operation instructions for the bits in the status register SREG (SREG is too special, there must be a dedicated bit operation instruction), there are only 2 instructions that can operate on the bits of other registers.
a) BST, BLD. The cycle of this instruction is 1CK, which is an instruction to exchange data between the T flag bit in SREG and the bits of the 32 general-purpose registers. If you want to set 1 bit of 32 registers (for example, set 1), you must first use the 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. 2 CK times are required.
b) SBI, CBI. These 2 instructions are instructions that set the bits of the registers in the first 32 (note: only the first 32 I/O spaces!) I/O space registers. The execution time of these 2 instructions is 2 CKs. Most of the AVR’s instructions for register operations are 1 CK, and why do these 2 instructions need 2 CKs? The reason is that it is still written with 8 bits when writing, so to change 1 bit, you need to read first, modify 1 bit, and then write back. This ensures that the other bits remain unchanged, but the time requires 2 CKs.
4. It is precisely because of point 3 (b) that the registers of I/O ports such as PA, PB, PC, and PD are in the first 32 I/O spaces, thus realizing a convenient separate bit-wise control I/O port .
5. Different C compilers, bit handling is different. ICC and IAR basically do not have extended bit processing, and they are processed according to standard C, because they consider more portability. And CVAVR expands the bit variable (in 32 working registers) and bit operation (only for the first 32 registers in the I/O space), so it is more convenient for users to use. However, it should be noted that CVAVR cannot implement bit operations for the last 32 registers in the I/O space.
Finally, look at the processing of the interrupt flag bit. The processing of the interrupt flag in the AVR adopts different processing methods according to different situations, and the explanation has been given in the above English description. Some are cleared by hardware when entering the execution interrupt, and some are cleared by hardware after reading a certain register. And software clear is usually to write “1”, why?
Looking at the M16 manual, I found that the external interrupt flag register GIFR (0X3A) and the T/C interrupt flag register TIFR (0X38) are all in the last 32 addresses of the I/O space, and all are interrupt flag registers. Therefore, whether it is ICC, IAR, or CVAVR, SBI and CBI instructions must not be used to perform bitwise operations, and only 8 bits of one register can be written at the same time.
So, how do you usually change the 1 bit to 1 in C? Usually, the correct statement is: XXXX |= 0B00000001; its function is to read XXXX first, and then OR with 0B00000001, so that the lowest bit is 1, and the other bits remain unchanged. Actually need 3 assembly instructions. Change 1 position 0: XXXX &= 0B11111110; also requires 3 assembly instructions.
AVR uses writing “1” to clear the “0” interrupt flag (writing “0” does not affect the flag), then the statement can directly use TIFR = 0B00000001, only 2 pieces of assembly are required. Clear the lowest flag bit to “0”, while ensuring that other flag bits remain unchanged. (!!! Note that it is wrong to use TIFR |= 0B00000001 instead!!! Because, if the other bits themselves are 1, this will be cleared instead)
In addition, if writing “0” to clear the “0” interrupt flag, how should it be defined when writing “1” to the interrupt flag? The interrupt flag bit should be set to 1 by hardware. If software can set it to 1, it will bring more trouble.
In fact, the above English explanation is still incomplete, and it is easy to cause some misunderstandings.
a) The statement TIFR = 0B00000001 can only be used for TIFR and GIFR, because only these two registers are all interrupt flag bits.
b) For some other interrupt flag bits, if there are some non-interrupt flag bits in the register where it is located, the writing method of XXXX |= 0B00000001 must be used.
c) For the setting of the non-interrupt flag bit, the form of XXXX |= 0B00000001 must be used.