Академический Документы
Профессиональный Документы
Культура Документы
The table below specifies the interrupt vectors for these 16-bit devices.
The interrupt attribute name and the parameter names may be written with a pair of underscore
characters before and after the name. Thus, interrupt and __interrupt__ are equivalent, as are
save and __save__.
The optional save parameter names a list of one or more variables that are to be saved and
restored on entry to and exit from the ISR. The list of names is written inside parentheses, with the
names separated by commas.
When using the interrupt attribute, please specify either auto_psv or no_auto_psv. If none is
specified a warning will be produced and auto_psv will be assumed.
INTERRUPT OPERATION
The compiler incorporates features allowing interrupts to be fully handled from C code. Interrupt
functions are often called ISRs.
The 16-bit devices allow interrupts to be generated from many interrupt sources. Most sources
have their own dedicated interrupt vector collated in an interrupt vector table (IVT). Each vector
consists of an address at which is found the entry point of the interrupt service routine. Some of
the interrupt table vector locations are for traps, which are non-maskable interrupts which deal
with erroneous operation of the device, such as an address error.
On some devices, an alternate interrupt vector table (AIVT) is provided, which allow independent
interrupt vectors to be specified. This table can be enabled when required, forcing ISR addresses
to be read from the AIVT rather than the IVT. Interrupts have a priority associated with them. This
can be independently adjusted for each interrupt source. When more than interrupt with the
same priority are pending at the same time, the intrinsic priority, or natural order priority, of each
source comes into play. The natural order priority is typically the same as the order of the
interrupt vectors in the IVT.
The compiler provides full support for interrupt processing in C or inline assembly code. Interrupt
code is the name given to any code that executes as a result of an interrupt occurring. Interrupt
code completes at the point where the corresponding return from interrupt instruction is
executed.
This contrasts with main-line code, which, for a freestanding application, is usually the main part
of the program that executes after Reset.
Interrupt vectors are prioritized in terms of their natural priority; this is linked to their position in
the vector table. All other things being equal, lower addresses have a higher natural priority. For
example, the interrupt associated with vector 0 will take priority over interrupts at any other
vector address.
PIC24FJ64GA004 family devices implement non-maskable traps and unique interrupts. These are
summarized in Table 7-1 and Table 7-2.
TABLE
The Alternate Interrupt Vector Table (AIVT) is located after the IVT, as shown in Figure 7-1. Access
to the AIVT is provided by the ALTIVT control bit (INTCON2<15>). If the ALTIVT bit is set, all
interrupt and exception processes will use the alternate vectors instead of the default vectors. The
alternate vectors are organized in the same manner as the default vectors. The AIVT supports
emulation and debugging efforts by providing a means to switch between an application and a
support environment without requiring the interrupt vectors to be reprogrammed. This feature
also enables switching between applications for evaluation of different software algorithms at run
time. If the AIVT is not needed, the AIVT should be programmed with the same addresses used in
the IVT.
Reset Sequence
A device Reset is not a true exception because the interrupt controller is not involved in the Reset
process. The PIC24F devices clear their registers in response to a Reset which forces the PC to
zero. The microcontroller then begins program execution at location 000000h. The user programs
a GOTO instruction at the Reset address, which redirects program execution to the appropriate
start-up routine.
Interrupt Control and Status
Registers
The PIC24FJ64GA004 family of devices implements a total of 28 registers for the interrupt
controller:
• INTCON1
• INTCON2
Global interrupt control functions are controlled from INTCON1 and INTCON2. INTCON1 contains
the Interrupt Nesting Disable (NSTDIS) bit, as well as the control and status flags for the processor
trap sources. The INTCON2 register controls the external interrupt request signal behavior and the
use of the Alternate Interrupt Vector Table. The IFSx registers maintain all of the interrupt request
flags. Each source of interrupt has a status bit which is set by the respective peripherals, or
external signal, and is cleared via software. The IECx registers maintain all of the interrupt enable
bits. These control bits are used to individually enable interrupts from the peripherals or external
signals. The IPCx registers are used to set the interrupt priority level for each source of interrupt.
Each user interrupt source can be assigned to one of eight priority levels. The interrupt sources are
assigned to the IFSx, IECx and IPCx registers in the same sequence that they are listed in Table 7-2.
For example, the INT0 (External Interrupt 0) is shown as having a vector number and a natural
order priority of 0. Thus, the INT0IF status bit is found in IFS0<0>, the INT0IE enable bit in IEC0<0>
and the INT0IP<2:0> priority bits in the first position of IPC0 (IPC0<2:0>). Although they are not
specifically part of the interrupt control hardware, two of the CPU control registers contain bits
that control interrupt functionality. The ALU STATUS register (SR) contains the IPL2:IPL0 bits
(SR<7:5>). These indicate the current CPU interrupt priority level. The user may change the current
CPU priority level by writing to the IPL bits. The CORCON register contains the IPL3 bit, which
together with IPL2:IPL0, also indicates the current CPU priority level. IPL3 is a read-only bit so that
trap events cannot be masked by the user software. All interrupt registers are described in
Register 7-1 through Register 7-29, in the following pages.
INITIALIZATION
1. Set the NSTDIS Control bit (INTCON1<15>) if nested interrupts are not desired.
2. Select the user-assigned priority level for the interrupt source by writing the control bits in the
appropriate IPCx register. The priority level will depend on the specific application and type of
interrupt source. If multiple priority levels are not desired, the IPCx register control bits for all
enabled interrupt sources may be programmed to the same non-zero value.
3. Clear the interrupt flag status bit associated with the peripheral in the associated IFSx register.
4. Enable the interrupt source by setting the interrupt enable control bit associated with the
source in the appropriate IECx register.
Note: At a device Reset, the IPCx registers are initialized, such that all user interrupt sources are
assigned to priority level 4.
The method that is used to declare an ISR and initialize the IVT with the correct vector address will
depend on the programming language (i.e., ‘C’ or assembler) and the language development tool
suite that is used to develop the application. In general, the user must clear the interrupt flag in
the appropriate IFSx register for the source of the interrupt that the ISR handles. Otherwise, the
ISR will be re-entered immediately after exiting the routine. If the ISR is coded in assembly
language, it must be terminated using a RETFIE instruction to unstack the saved PC value, SRL
value and old CPU priority level.
A Trap Service Routine (TSR) is coded like an ISR, except that the appropriate trap status flag in the
INTCON1 register must be cleared to avoid re-entry into the TSR.
INTERRUPT DISABLE
1. Push the current SR value onto the software stack using the PUSH instruction.
2. Force the CPU to priority level 7 by inclusive ORing the value OEh with SRL. To enable user
interrupts, the POP instruction may be used to restore the previous SR value.
Note that only user interrupts with a priority level of 7 or less can be disabled. Trap sources (level
8-15) cannot be disabled.
The DISI instruction provides a convenient way to disable interrupts of priority levels 1-6 for a fixed
period. Level 7 interrupt sources are not disabled by the DISI instruction.
Each interrupt source has five associated control bits, allocated in various special-function
registers (Table 5.1):
l The Interrupt Enable bit (typically represented with a suffix -IE). When cleared, the specific trigger
event is prevented from generating interrupts. When set, it allows the interrupt to be processed.
At power on, all interrupt sources are disabled by default.
l The Interrupt Flag (typically represented with a suffix -IF), a single bit of data, is set each time the
specific trigger event is activated. Notice how, once set, it must be cleared (manually) by the user.
In other words, it must be cleared before exiting the interrupt service routine, or the same
interrupt service routine will be immediately called again.
l The Priority Level (typically represented with a suffix -IP). Interrupts can have up to seven levels
of priority. Should two interrupt events occur at the same time, the highest priority event will be
served first. Three bits encode the priority level of each interrupt source. The PIC24 execution
priority level value is kept in the SR register in three bits referred to as IPL0..IPL2. Interrupts with a
priority level lower than the current value of IPL will be ignored. At power on, all interrupt sources
are assigned a default level of four and the processor priority is initially set at level zero. Within an
assigned priority level there is also a natural (or default) priority amongst the various sources in
the fixed order of appearance in the IVT table.
Nesting of Interrupts
Interrupts can be nested so that a lower-priority interrupt service routine can be, in its turn,
interrupted by a higher-priority routine. This behavior can be changed by the NSTDIS bit in the
INTCON1 register of the PIC24.
When the NSTDIS bit is set, as soon as an interrupt is received, the priority level of the processor
(IPL) is set to the highest level (7) independently of the specific interrupt level assigned to the
event. This prevents new interrupts being serviced until the present one is completed. In other
words, when NSTDIS bit is set, the priority level of each interrupt is used only to resolve conflicts if
multiple interrupts should occur simultaneously. In this case all interrupts will be serviced
sequentially.
Traps
Eight additional vectors occupy the first locations at the top of the IVT table (Table 5.2). They are
used to capture special error conditions such as a failure of the selected CPU oscillator, an
incorrect address (word access to an odd address), stack underflow/overflow or a divide by zero
(math error).
How interrupts work on the PIC24F series
Like most functions on the PIC24 microcontrollers, and all microcontrollers for that matter,
interrupts are controlled by a series of registers. On the PIC24F series they controlled by the
registers STATUS REGISTER (SR), CORCON, INTCON1 and INTCON2, INTERRUPT ENABLE CONTROL x
(IECx), INTERRUPT FLAG STATUS x (IFSx) and INTERRUPT PRIORITY CONTROL x (IPCx), INTERRUPT
CONTROL STATUS REGISTER (INTTREG). In general the default settings work fairly well, but it
always pays to check the relevant section of the datasheet to confirm anything you are not sure
about. Never underestimate the power of the datasheet! We will however go through the main
settings you’ll need in the remainder of this tutorial.
In general all interrupts are controlled in the same way. There is an ENABLE bit, for each interrupt
source, which turns the interrupt on or off, that can be found in the IECx register. When an
interrupt is trigger (or activated) a status bit, for that particular interrupt source, is set in the
relevant IFSx register. This flag is cleared, manually (by setting it back to zero), in software when
the interrupt is “serviced”. Each interrupt source can also be assigned an individual priority level
(1-8) using the relevant IPCx register. This priority functionality allows the designer to priorities
one interrupt source above another. For example, it allows you to say that an external pin
interrupt is more important (or higher priority) than a UART interrupt. This priority will take effect
if two interrupts occur at the same time (7 is the highest priority and 0 is disabled).
All global interrupt control functionality is set in using the INTCON1 and INTCON2 registers.