The C51 interrupt function is formatted as: void Funcir (void) interrupt x [using Y]
Here is some analysis of sleepwalking:
The interrupt function is a special function with no parameters and no return value, but it is not allowed to use returns in the program. The answer is yes, but only "return", not "return" (z); ; used in places that need to be quickly returned, the corresponding Assembly will have multiple RET statements, the relative efficiency will be higher.
Using use, using can modify any function, but the personal recommendation is only used to modify the interrupt function; Simply put, the "using" specifies the Working register group, because the interrupt function is generally a more urgent matter, sometimes a statement will be preoccupied, Therefore, using a use-switched register group can save some of the action of the stack, because 51 only two levels of interruption, the sibling interrupt can not be interrupted, so we can be a sibling interrupt set to the same register group, in a sense, there is a set of registers is redundant. At the same time, individuals suggest that the interrupt function should use the using this keyword.
Third, interrupt to call the function, first of all, to discuss the need to call the function in the interrupt function, the day before yesterday in the forum I debated with others on this issue, now I still this view: Some situations interrupt call function is necessary, this time is not the call function, in fact, and the normal function, The first is that this function, if called multiple times, or to take some of the parameters of what is more necessary; the day before yesterday, someone told me that if the function called only once and no return of parameters to write directly, because if the function, at least add call and RET two statements, I do not agree, I was actually debugging found, When your program is more complex, you pull that out into a function, and the code and time will be better.
Four, the function called in the interrupt is best not to be interrupted by other function calls, because there will be a "repeat call" warning, sometimes this call is very fatal, some people say this function can be decorated with reentrant, yes, it can be solved, but the individual does not recommend doing so, Perhaps this will be with you to reduce a lot of stack space, and the whole program optimization is much worse, personal suggestion this situation to write the function two times, divided into two functions are called respectively.
The interruption called the function, there will be some inexplicable problems, some data is not correct (I now encountered this problem) in fact, is generally because the assembly used the absolute register, some say interrupt function use that register group, Which register group is used for the function that is being called (I think a good reference C51.PDF:Functions called from a interrupt procedure must function with the same register bank as The interrupt procedure. When the NOAREGS directive isn't explicitly specified, the compiler may generate absolute register accesses using the Reg The Ister bank selected (by the using attribute or by the Registerbank control) is for that function. Unpredictable results may occur when a function is assumes a register bank other than the one currently selected. Refer to ' Register Bank Access ' on the page 124 for the more information.), I think this is not good:
This increases the extra cost and uses the using to add the statement:
PUSH PSW
MOV PSW, #XX
....
POP PSW
More importantly, a function with a using cannot have a return value (this place has a problem, should be able to have a return value, the following is said to be unable to return the bit type of value), which is fatal (so this is not fatal, you can use using to solve this problem)
There are two ways to personally recommend:
1, the use of "#pragma noaregs" prohibit the use of absolute registers
2. Use "#pragme RB (x)" To specify the working register group for this file
VI, generally speaking, the requirements of the interrupt function as short as possible, but there are special cases, some of the former/backstage system, will put a lot of relatively important things to the timing of the interruption (this time interrupt similar to the real-time operating system clock beat) to do, and the program is very long. I have come up with this to tell you that the interrupt function is also a function, as long as the system is necessary, you can do something seemingly unreasonable, the shot will be shot, like Goto statement.
Transfer from http://www.ednchina.com/blog/hotchip/, please go to his blog to support him, there are good articles. In parentheses it's my understanding
About using:
For example:
Define a function
void func (unsigned char i) {
...
}
Like the next interrupt function
void Int_0 (void) interrupt 0 using 1 {
....
}
In the default state, Func uses Register Group 0 (BANK0), if there is a parameter passing error when the INT_0 is invoked func when the parameter is passed.
If you use registers in the Interrupt service function ISR, you must deal with the usage problem of the using:
1. The Interrupt service function uses using using to specify a register group that differs from the main function (the main function typically uses register bank 0).
2. The ISR with the same interrupt priority can specify the same register group, but the ISR with different priority must use a different register group, and the called function in the ISR uses the same register group as the interrupt function. (This should be the case)
3. If the use designation is not used, at the entrance of the ISR, the C51 defaults to select Register group 0, which is equivalent to the entry of the interrupt service program to first execute the instruction:
MOV PSW #0
This ensures that high priority interrupts are not used as specified by using the. You can break down low-priority interrupts that use different register groups.
4, using the use of keyword to interrupt the specified register group, so that directly switch the Register group without a large number of PUSH and POP operation, can save RAM space, accelerate the MCU execution time. Register group switching, in general, more prone to error, to the memory of the use of a clearer understanding of the correctness of your own to ensure that. Be careful when you have direct address access in your program. As for "When to use register group switching", one scenario is: When you try to get two (or more) jobs running at the same time, and their site needs some isolation, it will be used. Registers are useful in ISR or in the use of real-time operating system RTOS.
Principles used by register groups:
The minimum 32 bytes of 1 and 8051 are divided into 4 groups of 8 registers. Registers R0 to R7 respectively. The register group is selected by a low two-bit PSW. In the ISR, the MCU can switch to a different register group. Access to a register group is not addressable, and the C51 compiler stipulates that a function using or prohibiting interruption (#pragma disable) cannot return a bit type value.
2, the main program (main function) using a group, such as bank 0, the lower interrupt priority of all interrupts are used in the second group, such as bank 1; all interrupts for high school break priority are used in another group, such as Bank 2. Obviously, the same level of interrupts using the same set of registers will not be problematic because interrupt nesting does not occur, while high-priority interrupts use a different set than low-priority interrupts because of the possibility of high priority interrupts occurring in low-priority interrupts. The compiler automatically determines when absolute register access can be used.
3, in the ISR call other functions, must and interrupts use the same register group. When no explicit declaration is made by the Noaregs command, the compiler will use absolute register addressing to access the Register Group of function selection (that is, using or Registerbank specified), which will produce unpredictable results when the function is assumed to be different from the actual selected register group, This may result in parameter passing errors, which may be in the wrong register group.
As an example: if you need to use the same function within interrupts and interrupt calls, it is assumed that the process of the program will not give you a recursive invocation of the function, and this call will not be problematic. If it is determined that no reentrant conditions will occur, there are two scenarios:
1. If the ISR and the main program use the same register group (the main program defaults to bank 0, and if the ISR does not specify a register area with using using, then BANK 0 is the default), no additional settings are required.
2. If the ISR and the main program use a different register group (the main program defaults to using the bank 0,ISR to specify the other bank), the called function must be placed in:
#pragma noaregs
#pragma aregs
In a control parameter pair, specify that the compiler does not use absolute register addressing for the function, or you can select "Don" t use absolute Register accesses in options->c51, so that all code is not using absolute Register addressing (this , execution efficiency will be reduced slightly). In either case, the compiler gives a OVERLAY warning, and you need to change the parameters manually to make a reentrant note.
3, there is another way: if the code of the called function is not very long, or copy the function, with a different function name instead, this situation is suitable for ROM has enough space.
Therefore, using the use of the keyword, if not sure, would rather not, to the compiler to deal with the system itself.
For more information, please refer to the C51.pdf file for detailed use.
Http://blog.sina.com.cn/s/blog_4c5da5d8010009tu.html