Use of interrupt and using in C51 interrupts
The basic structure of the 8051 series MCU comprises 32 I/O ports (4 8 bit ports), two 16-bit timing counters, full-duplex serial communication, 6 interrupt sources (2 external interrupts, 2 Timer/counter interrupts, one serial input/output interrupt), two interrupt priority, 128-byte built-in R AM; Independent, 64K-byte addressable data and code area. After the interrupt occurs, the MCU goes to one of the 5 interrupt entrances and then executes the corresponding interrupt service
Handler. The entry address of the interrupt program is placed in the interrupt vector by the compiler, and the interrupt vector is located at the lowest address of the program code snippet, noting that the serial input/output interrupts here share an interrupt vector. The 8051 interrupt vector table is as follows:
Interrupt Source Interrupt Vector
---------------------------
Power-on Reset 0000H
External Interrupt 0 0003H
Timer 0 Overflow 000BH
External Interrupt 1 0013H
Timer 1 Overflow 001BH
Serial Port Interrupt 0023H
Timer 2 Overflow 002BH
Both the interrupt and the using are the C51 keywords. The C51 interrupt process is implemented by using the Interrupt keyword and the interrupt number (0 to 31). The interrupt number indicates the entry address interrupt sequence number for the compiler interrupt program corresponds to the Enable bit in the 8051 interrupt enable register IE, the corresponding relationship is as follows:
IE Register C51 in 8051
The Enable bit interrupt number interrupt source
--------------------------------
ie.0 0 External Interrupt 0
IE.1 1 Timer 0 Overflow
IE.2 2 External Interrupt 1
IE.3 3 Timer 1 Overflow
IE.4 4 Serial Interrupt
IE.5 5 Timer 2 Overflow
With this declaration, the compiler ignores the use of the Register group parameters and protects the accumulator A, status register, register B, data pointers, and default registers. As long as the interrupts are used, the compiler pushes them up and stacks them out at the end of the interrupt program. The C51 supports all 5 8051 standard interrupts from 0 to 4 and up to 8051 interrupt sources in the 27 series (enhanced).
The Using keyword is used to specify the set of registers used by the interrupt service program. Usage is: Using followed by a number from 0 to 3, corresponding to 4 sets of working registers. Once the work register group is specified, the default working register group is not pushed to the stack, which saves 32 processing cycles because both the stack and the stack require 2 processing cycles. The disadvantage of this approach is that all calls to the interrupt process must use the same register group as specified, otherwise the parameter pass error occurs. Therefore, for using, the use of flexible trade-offs.
About using:
You explained in this article that "the disadvantage of this approach is that all invocations of the interrupt process must use the same register group specified" is not the meaning.
For example:
Define a function
void func (unsigned char i) {
...
if (++i==0x12) {
...
}
...
}
Like the next interrupt function
void Int_0 (void) interrupt 0 using 1 {
....
}
By default, Func uses Register Group 0 (BANK0), so when Int_0 invokes Func, there is a parameter passing error when parameters are passed.
Thank you.
If you use a register in the Interrupt service function ISR, you must handle the usage of the using problem:
1. The Interrupt service function uses the using to specify a register group that differs from the main function (the main function generally uses the Register bank 0).
2. The ISR with the same interrupt priority can use the same register group as the using, but the different priority ISR must be different register groups, and the function called in the ISR also uses the same register group as the interrupt function.
3, if the use is not specified, at the entrance of the ISR, C51 default Select register group 0, which is equivalent to the Interrupt Service program's entry first execute the instruction:
MOV PSW #0
This ensures that the high-priority interrupts specified by the using are not used. Low-priority interrupts that use different register groups can be interrupted.
4. Use the Using keyword to assign a register group to the interrupt, so that switching the register group directly without a large number of PUSH and POP operations, you can save RAM space and accelerate the MCU execution time. Register group switching, in general, more error-prone, to the memory of the use of a clearer understanding of the correctness of your own to ensure that. When you have direct address access in your program, be cautious. As for "When to use register group switching", one scenario is when you try to have two (or more) jobs running at the same time, and their site needs some isolation, it will be used. Registers are very useful in an ISR or in a real-time operating system RTOs.
Principle of use of register groups:
A minimum of 32 bytes of 1, 8051 is divided into 4 groups of 8 registers. Registers are R0 to R7, respectively. The register group is selected by the PSW's low two-bit. In the ISR, the MCU can switch to a different register group. Access to the Register group is not addressable, and the C51 compiler stipulates that a function with using or no break (#pragma disable) cannot return a value of type bit.
2. The main program (main function) uses a group, such as bank 0, and all interrupts with low interrupt priority use the second group, such as bank 1; all interrupts in high-school break priority are used in another group, such as Bank 2. Obviously, there is no problem with using the same set of registers for interrupts at the same level, since no interrupt nesting occurs, whereas high-priority interrupts use a different set of low-priority interrupts because of the potential for high-priority outages in low-priority interrupts. The compiler automatically determines when absolute register access can be used.
3. Call other functions in the ISR and must use the same register group as the interrupt. When the Noaregs command is not used to make a clear declaration, the compiler will use absolute register addressing to access the Register group of the function selected (that is, specified with using or Registerbank), which produces unpredictable results when the function is assumed to be different from the actual selected register group. A parameter pass error may occur, and the return value may be in the wrong register group.
For example, when it is necessary to use the same function within and out of the interrupt, assuming that the procedure is controlled by the program, there will be no recursive invocation of the function, so that the call will not be problematic. If it is determined that no re-entry occurs, there are two scenarios:
1. If the ISR and the main program use the same register group (the main program uses bank 0 by default, and if the ISR does not use the using to specify the register area, then the bank 0 is used by default), no additional settings are required.
2, if the ISR and the main program use a different register group (the main program by default using bank 0,ISR using the use specified other bank), the called function must be placed in:
#pragma noaregs
#pragma aregs
Control parameter pair, specifies that the compiler does not use absolute register addressing for the function, or options->c51, select "Do not use absolute register accesses", so that all code is not using absolute register addressing (this way, Execution efficiency will be reduced slightly). Regardless of the above situation, the compiler will give a re-entry warning, you need to manually change the OVERLAY parameter, do the re-entry instructions.
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 the ROM has enough space.
Therefore, the use of keywords using, if not sure, rather than, to the compiler system to deal with their own. Interrupt xx using Y
The XX following the interrupt is worth the interrupt number, which means that the function corresponds to the first interrupt port, typically in 51
0 External Interrupt 0
1 Timer 0
2 External Interrupt 1
3 Timer 1
4 Serial interrupts
Other root lifting corresponding to the microcontroller has its own meaning, in fact, C-load compile time is to take you this function of the entry address to the corresponding interrupt of the jump address
Using y this y means that the set of registers used by this interrupt function is 51 there are generally 4 r0--R7 registers, If your terminal function and other programs do not use the same register group, then the Register group will not be pressed into the stack when it goes into the interrupt. Save code and time generally only using 0,1,2,3
Single chip microcomputer interrupt response can be divided into the following steps: 1, stop the main program to run. Immediately after the execution of the current instruction terminates the operation of the current program. 2, protect the breakpoint. The current value of the program counter PC is pressed onto the stack, and the terminating address (that is, the breakpoint address) is saved so that the program can continue executing when the service program is returned from it, 3, looking for an interrupt entry. Find 5 different entry addresses based on interrupts from 5 different interrupt sources. 4. Execute interrupt handler. This does not speak; 5. Interrupt return. After executing the interrupt handler, return to the main program from the interrupt and proceed to the next step.
The above work is done automatically by the computer, regardless of the programmer, there are 5 entry addresses to store the interrupt processing program (this is where the program was written, if you do not put the interrupt handler there can be wrong, because the interrupt program cannot be executed to). It's a little complicated, isn't it. Never mind, keep looking down.
The natural priority of the five interrupt sources is from high to low in the order of the external interrupt 0→ timer 0→ external interrupt 1→ timer 1→ serial interrupt. If we don't set it up, the microcontroller is constantly looping through the interrupt flags in this order (as we do in our lives), but sometimes we need to manually set high and low priority, which means that the programmer sets which interrupts are high-priority, Which interrupts are low priority (of course, because there are only two levels, so only some interrupts are prioritized, while others are at the same level, the sequence of interrupts at the same level is determined by the natural priority, so be sure to figure it out).
Now that you can set the human priority, how is it set? Actually very simple, we just put the IP register corresponding position "1" on it, look at the following table:
Xxxps PT1 PX1 PT0 PX0
Serial T1 INT1 T0 INT0
At boot time, each interrupt is in a low priority, and we can set the priority with the instruction. For example: now has the following requirements, the T0, INT1 set to high priority, the other is low priority, the IP value.
The first 3 bits of IP are useless, can be arbitrary value, set to 000, the following according to the requirements of writing: 00000110, that is ip=06h, see the table below.
Xxxps PT1 PX1 PT0 PX0
0 0 0 0 0 1 1 0
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.