3149 views|0 replies

1379

Posts

0

Resources
The OP
 

Issues that need attention when using the interrupt system of PIC16F87X microcontroller [Copy link]

Abstract: The hardware structure and instruction system of the PIC series microcontroller developed by Microchip Technology Inc. in the United States adopt a unique design method. It has made some groundbreaking changes to the traditional microcontroller in terms of architecture and concept, but it has also brought some special problems to the application of this type of microcontroller. This article makes necessary explanations on the characteristics of the interrupt of the PIC16F87X series microcontroller and several issues that should be paid attention to during the application process. The content includes interrupt sources, interrupt logic, interrupt-related registers, interrupt delay, interrupt field protection and precautions, etc.

Keywords: microcontroller PIC16F87X interrupt system interrupt source


  Among some of the world's famous single-chip microcomputer product series, the PIC16F87X series of single-chip microcomputers is one of the single-chip microcomputer varieties with the largest number of peripheral device modules inside the chip. The PIC16F874 and PIC16F877 single-chip microcomputers have 15 peripheral device modules integrated inside the chip; the PIC16F873 and PIC16F876 single-chip microcomputers have 12 peripheral device modules integrated inside the chip. Among the new models of this series recently launched, the PIC16F870 single-chip microcomputer has 10 peripheral device modules integrated inside the chip; the PIC16F871 single-chip microcomputer has 13 peripheral device modules integrated inside the chip; the PIC16F872 single-chip microcomputer also has 10 peripheral device modules integrated inside the chip (one more USART module and one less SSP module than the PIC16F870).
  When these peripheral device modules are enabled and during operation, they all require the CPU to participate in various service tasks such as control, coordination or data exchange. Since the CPU runs at a very high speed, while the peripheral modules work at a very low speed, and these peripheral modules do not frequently require CPU services, a scheduling method is usually adopted to allow many peripheral modules to share one CPU and get CPU services in a timely manner - interrupts.

1. Interrupt sources of PIC16F87X

  The PIC series of microcontrollers are the most influential reduced instruction set (RISC) microcontrollers in the world today, with rich interrupt functions. Among them, the powerful mid-range and high-end models have as many as 18 interrupt sources. In the PIC microcontroller family, the PIC16F87X sub-series microcontrollers, which are ranked in the upper-middle level, have as many as 14 interrupt sources. Among them, the types and numbers of interrupt sources vary with the models of microcontrollers, as listed in Table 1. Its shortcomings are: there is only one interrupt vector, and there is no priority level between the interrupt sources, and there is no non-maskable interrupt.

Table 1 PIC16F87X microcontroller interrupt sources and their number
Interrupt source type Interrupt source flag Interrupt source mask bit 873/ 876 874/ 877 870 871 872
External trigger interrupt INT INTF INTE
TMR0 overflow interrupt T0IF T0I
RB port level change interrupt RBIF RBIE
TMR1 overflow interrupt TMR1IF TMR1IE
TMR2 Interrupt TMR2IF TMR2IE
CCP1 Interrupt CCP1IF CCP1IE
CCP2 Interrupt CCPS CCP2IE
SCI Synchronous Transmit Interrupt TXIF TXIE
SCI synchronous receive interrupt RCIF RCIE
SSP Interrupt SSPIF SSPIE
SSP I2C bus collision interrupt BCLIF BCLIE
Parallel Port Interrupt PSPIF PSPIE
A/D conversion interrupt ADIF ADIE
E2PROM Interrupt EEIF EEIE
13 types 14 types 10 types 11 types 10 types


  As can be seen from Table 1, each interrupt source basically corresponds to each peripheral device module. Among them, most peripheral device modules correspond to one interrupt source (such as the timer/counter TMR0 module), some peripheral device modules correspond to two interrupt sources (such as the general synchronous/receiver/transmitter SCI module), and some peripheral device modules have no interrupt source corresponding to them (such as the input/output port RA and RC modules), and some interrupt sources have no peripheral device module corresponding to them (such as the external trigger interrupt source INT).

2. PIC16F87X Interrupt Hardware Logic

  In the PIC16F87X sub-series, the interrupt logic circuits vary according to the specific models, and the types and numbers of interrupt sources are also different: the most have 14 interrupt sources; the least have 10 interrupt sources (see Table 1 for details). Among them, the parallel port module and parallel port interrupt source are only available in the 40-pin package models (PIC16F871, PIC16F874 and PIC16F877); while the 28-pin package models (PIC16F870, PIC16F872, PIC16F873 and PIC16F876) do not have them.
  The logic circuit of the interrupt system of the PIC16F87X series microcontroller is shown in Figure 1. Each interrupt source corresponds to an interrupt flag bit (denoted as XXXF, F is the first English letter of Flag) and an interrupt mask bit or interrupt enable bit (denoted as XXXE, E is the first English letter of Enable). Whether the interrupt flag signal generated by the interrupt source can be forwarded will be controlled by the corresponding interrupt mask bit. Each interrupt flag bit corresponds to a trigger. When the interrupt source requests a CPU interrupt, the corresponding trigger is automatically set by the hardware, and the clearing of the trigger is implemented by the user's program; each interrupt mask bit also corresponds to a trigger. The setting and clearing of the trigger are both completed by the user program.
  The logic circuit depicted in Figure 1 is a combinational logic circuit composed of simple gate circuits. All 14 interrupt sources are arranged in two echelons in parallel. Only 3 interrupt sources are arranged in the first echelon, and the rest of the interrupt sources are arranged in the second echelon. This is done to be compatible with the early PIC series microcontroller models (the number of peripheral device modules configured in the microcontroller models developed in previous years is relatively small, and the number of corresponding interrupt sources is naturally small. For example, PIC16C61 only has 3 interrupt sources in the first echelon). Some new PIC microcontroller models developed recently are obtained by expanding some functions on the basis of the original microcontroller chip.
  All interrupt sources are controlled by the global interrupt mask bit (also known as the total mask bit) GIE. The interrupt sources of the first echelon are controlled not only by the global interrupt mask bit, but also by their respective interrupt mask bits; the interrupt sources of the second echelon are controlled not only by the global interrupt mask bit and their respective interrupt mask bits, but also by an additional peripheral interrupt mask bit PEIE.


Figure 1 Interrupt logic

3. Interrupt related registers

  There are five special function registers related to the interrupt function: interrupt control register INTCON, the first peripheral interrupt flag register PIR1, the first peripheral interrupt mask register (also known as interrupt enable register) PIE1, the second peripheral interrupt flag register PIR2 and the second peripheral interrupt mask register PIE2. As listed in Table 2, there are 40 bits in the five registers, of which 30 bits are used. They are strictly corresponding to the input logic signals of the interrupt logic circuit in Figure 1 and to the logic expressions. These five registers all have addresses uniformly encoded in the RAM data memory. In other words, the PIC microcontroller can access these five special registers as ordinary register units (i.e., read or write operations). This helps to reduce the instruction types and number of instructions in the instruction set, and is also convenient for learning, memorizing and programming.

Table 2 Registers related to interrupt functions
Register Name
Register Symbols
Register Address
Register contents
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
Option Register
OPTION-REG
81H/181H
/RBPU
INTEDG
T0CS
T0SE
PSA
PS2
PS1
PS0
Interrupt Control Register
INTCON
0BH/8B/
10BH/18BH
GIE
PEIE
T0I
INTE
RBIE
T0IF
INTF
RBIF
1st peripheral interrupt flag register
PIR1
0CH
PSPIF
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
1st peripheral interrupt mask register
PIE1
8CH
PSPIE
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
Second peripheral interrupt flag register
PIR2
0D
-
-
-
REIF
BCLIF
-
-
CCPS
Second peripheral interrupt mask register
PIE2
8DH
-
-
-
EEIE
BCLIE
-
-
CCP2IE

4. Interrupt handling

  After the microcontroller is reset, the hardware automatically sets the global interrupt mask bit GIE=0 to mask all interrupt sources. After the interrupt return instruction "RETFIE" is executed, the hardware also automatically sets the general mask bit GIE=1 to reopen all interrupt sources. Regardless of the status of various interrupt mask bits and the global interrupt mask bit GIE (open or disabled), when the interrupt condition of a certain interrupt source is met, an interrupt request will be issued and the corresponding interrupt flag bit will be set (=1). However, whether the CPU can respond depends on the status of the interrupt mask bit involved in the interrupt source. After the CPU responds to the interrupt, the hardware automatically clears the global interrupt mask bit (GIE=0) to mask all interrupt sources to avoid repeated interrupt responses. Then, the hardware automatically pushes the current program counter PC value (i.e., the program breakpoint address) into the stack (actually the hardware stack), and sets the PC register to the interrupt vector address (0004H), thereby turning to and starting to execute the interrupt service program. After entering the interrupt service program, instructions must be arranged in the program to check the interrupt source that issued the request (if multiple interrupt sources are opened at the same time). This can be achieved by checking the flag bits of each interrupt source. Once the interrupt source that issued the request is determined, the flag bit of the interrupt source is manually cleared to zero by software, otherwise, the interrupt return instruction "RETFIE" is executed. After the interrupt is reopened, the CPU will repeatedly respond to the same interrupt request because the interrupt flag bit is still "1". An interrupt return instruction "RETFIE" must be placed at the end of the interrupt service program. After executing this instruction, not only can the interrupt be reopened, but the hardware can also automatically pop up the breakpoint address retained at the top of the stack and put it back into the program counter PC, so that the CPU returns and continues to execute the interrupted main program.
  1? Delayed response and delayed processing of interrupts
  In an interrupt process, there must be a certain delay time from the interrupt source issuing a request to the CPU responding. The timing diagram of each related signal is shown in Figure 2.


Figure 2 INT pin interrupt timing diagram

  In Figure 2, the first row is the system clock pulse signal, and every 4 clock cycles correspond to 1 instruction cycle. The second row is the instruction cycle signal. This signal can only be sent out of the chip from the OSC2 pin in the RC oscillation mode. The third row is the interrupt pulse signal sent from the external pin INT of the microcontroller. The external interrupt signal INT is edge-triggered. Assuming that the rising edge of the INT interrupt signal is set to be valid, the rising edge of the signal will cause the interrupt flag INTF to be set after 1 clock cycle. The fourth row represents the INTF signal. The signal is sampled once at the rising edge of the second clock pulse in each instruction cycle. Once the INTF signal is detected to be set to "1", the CPU will clear the global interrupt mask bit GIE to zero in the next instruction cycle. The fifth row is the global interrupt mask bit GIE. In the next instruction cycle after the GIE signal is cleared, the program counter PC is set to the interrupt vector 0004H, as shown in the sixth row in Figure 2. At the same time, the jump to the interrupt service program is completed in the instruction cycle, and the first instruction of the subroutine, that is, instruction (0004H), is extracted, as shown in line 7 in Figure 2. In the subsequent instruction cycle, the first instruction of the interrupt service program is officially executed, as shown in line 8 in Figure 2. From the input of the valid signal on the INT pin to the execution of the first instruction of the interrupt service program, it takes about 3 to 4 instruction cycles of delay. The more accurate delay time depends on the timing of the interrupt event.
  The above description is only the delay time from the application of an interrupt to the response of the CPU. The following analyzes the delay time from the CPU responding to an interrupt to the effective processing of the interrupt. Since the PIC series microcontrollers with interrupt function (the low-end products PIC16C5X and PIC12C5X series do not have interrupt function), they adopt the "multi-source interrupt" design (that is, one interrupt vector corresponds to multiple interrupt sources), and there is only one interrupt vector, or only one interrupt service program entry address. This means that only one interrupt service program can be written for such microcontrollers. The hardware structure of this type of microcontroller has been simplified, so the corresponding software design will cost more. In an interrupt service program, if you want to process multiple interrupt sources, you must first execute one or more instructions to investigate the specific interrupt source after entering the interrupt service program, and then provide targeted services to the interrupt sources found. In this way, a delay time is formed from the CPU response to the targeted processing of an interrupt. This time is long or short, and it will increase with the increase in the number of open interrupt sources. The best case is that only one interrupt source is opened, and then there is no need to detect the interrupt source and you can immediately enter the targeted processing; the worst case is that all interrupt sources are opened, and the time spent on detecting the interrupt source will be the longest.
  In addition, the PIC microcontroller uses a hardware stack structure. The advantage is that it does not occupy program memory space or data memory space, and the user does not need to operate the stack pointer; but it also brings an unavoidable weakness, that is, it does not have the push (PUSH) and pop (POP) instructions like other single-chip microcomputer instruction systems, so it is more troublesome to implement interrupt site protection, and the processing time occupied is also correspondingly more.
  2? Interrupt site protection problem
  Interrupt site protection is a very important link in interrupt technology. During the interrupt service program, only the return address, that is, the value of the program counter PC is automatically pushed into the stack. If the contents of other registers need to be retained, the programmer must find another way. Since the instruction system of the PIC microcontroller does not have instructions such as PUSH (pushing) and POP (popping) like other single-chip microcomputers, a user program is required to implement similar functions. Because a program is used to implement site protection, and the execution of the program may affect the W register and the STATUS register, these two registers should be protected first, and then other registers that the user thinks need to be protected should be saved. And in PIC microcontrollers, the interrupt scene data is not saved in the chip stack storage area, but in some file registers (i.e. RAM data memory units) selected by the user. Of course, general registers should generally be selected to protect the scene. The following is a sample program fragment for implementing interrupt scene protection provided by the original manufacturer.
  ; Save the contents of the W, STATUS and PCLATH registers to temporary backup registers
  [1] MOVWFW_TEMP ; Copy W to its temporary backup register W_TEMP
  [2] SWAPFSTATUS,W ; Swap the high and low nibbles of the STATUS register and put them into W
  [3] CLRFSTATUS ; Regardless of the current bank, set bank 0 as the current bank
  [4] MOVWFSTATUS_TEMP ; Save STATUS to the temporary register STATUS_TEMP on bank 0
  [5] MOVF PCLATH, W ; Copy the contents of register PCLATH to W
  [6] MOVWFPCLATH_TEMP ; Transfer the contents of PCLATH to the temporary register PCLATH_TEMP via W
  [7] CLRFPCLATH ; Regardless of the current page, set PCLATH to point to page 0 (the core part of the interrupt service routine)
  [8] MOVFPCLATH_TEMP, W ; Transfer via W
  [9] MOVWFPCLATH ;Restore PCLATH contents
  [10]SWAPFSTATUS_TEMP,W ;Swap the high and low nibbles of the STATUS_TEMP register and put them into W
  [11]MOVWFSTATUS ;Move the contents of W into the STATUS register (and also restore the current bank to the original bank)
  [12]SWAPFW_TEMP,F ;Swap the high and low nibbles of the contents of W_TEMP and put them back
  [13]SWAPFW_TEMP,W ;Swap the high and low nibbles of the contents of W_TEMP and put them into W again
  This program is applicable to all models of microcontrollers in the PIC16CXX series. Before this routine, it is assumed that corresponding temporary backup registers have been defined for each register to be retained. The suffix "_TEMP" is used to indicate a temporary backup register, for example, the temporary backup register of "W" is recorded as "W_TEMP". It is worth considering how many of these temporary backup registers should be defined and where they should be defined in the general register area. In addition, the distribution of the general register area inside the microcontroller is different for different models, so the number and location of the temporary backup register definitions cannot be the same.
  For example, for PIC16F873/874, the register W_TEMP must be defined in both bank 0 and bank 1 of the file register (i.e., RAM data memory), and these two W_TEMP register units must have the same internal address code (for example, if W_TEMP is defined in bank 0 at unit 20H, then another W_TEMP is defined in bank 1 at unit A0H); and the temporary backup registers of other registers (such as STATUS_TEMP and PCLATH_TEMP) only need to be defined in bank 0.
  For another example, the situation is different for the other five models in the PIC16F87X sub-series. The top part of each file register has 16 address spaces, which are all addressed to the same 16 physical units. These 16 units do not require bank select addressing, or in other words, addressing these 16 units is independent of the bank select code, that is, it is independent of the current bank. Therefore, it is most appropriate to arrange all temporary backup registers in this position (only one W_TEMP needs to be defined). This makes it very easy to save and restore the scene. Interrupts are random events. After entering the interrupt service routine, the first thing to save should be the working register W. The reason is that the PIC microcontroller does not have instructions for direct transfer between "different registers". Such a function can only be realized by using W as a transfer (requiring 2 instructions), so the W register should be emptied first (corresponding to the first instruction in the program). In a hurry to empty the W register, the bank selection code in the current status register STATUS cannot be destroyed, and the flag bit in the current status register STATUS cannot be affected. However, it is impossible to determine which bank the main program is in. Therefore, a W_TEMP temporary backup register is defined at the same position on each RAM data storage bank that the main program may select.
  Once the working register W is emptied, the content of the status register STATUS should be transferred to W. The instruction that completes this operation cannot affect the original flag bit in the STATUS register because the content of the STATUS register has not been safely protected before. After careful analysis, it is known that there are 3 "MOV" transfer instructions in the instruction system of the PIC16 series microcontroller. However, only one "MOVF f,W" uses the RAM unit as the source register and W as the target register; and the operation process of this instruction happens to affect the "Z" flag bit. Therefore, this instruction cannot be used, and we have to use a "SWAPFSTATUS,W" which has both high and low nibble swapping and transfer functions to barely replace it (corresponding to the second instruction in the program). However, only its transfer function is used here, and the redundant operations brought by its swapping function must be recorded, and it must be switched back after the work is completed.
When the content of the STATUS register has been saved in W, it can be boldly cleared to 0 so that body 0 defining STATUS_TEMP and PCLATH_TEMP can be set as the current body (corresponding to the third instruction in the program). After the above steps that require special caution, the contents of the registers STATUS and PCLATH can be easily saved to their respective temporary backup registers (corresponding to the 4th to 6th instructions in the program).
  When the microcontroller is initially powered on, PCLATH is automatically cleared to 0 to avoid random values in its content, that is, to avoid unexpected jumps of the CPU during the subsequent program running process, causing the program to "run away". It can be seen that the register PCLATH is crucial to the safe operation of the program and should not be underestimated. Once the program enters the service program, there is no way to verify the current value of PCLATH, and in fact, the program loses the right to know the content of PCLATH. It can only be cleared to 0 like the initial power-on of the microcontroller, and it is forced to "pull" into the informed range again (corresponding to the 7th instruction in the program).
  The content of PCLATH will affect the direction of the program in two cases: the first case is when executing the two jump instructions GOTO and CALL, the 11-bit address code comes from the instruction code, and the highest 2 bits (PC value) that determine the program memory page come from PCLATH<4:3>, that is, in this case, only the 2 bits of PCLATH affect the direction of the program. In this case alone, as long as the user program does not exceed the 2KB range of page 0 (or page 0), for programmers, the highest 2 bits of the PC value can be ignored, and therefore the 2 bits of the PCLATH register PCLATH<4:3> can also be ignored. The second situation is that the arithmetic operation, logic operation or transfer operation instruction targeting PCL (the instruction system of the PIC16 series microcontroller has 14 such instructions) automatically loads the high 5 bits of PC<12:8> with the low 5 bits of the PCLATH register during the operation, and the PCLATH content that affects the program direction is as many as 5 bits. Even if the user program does not exceed 2KB (within the range of page 0), at least 3 bits will affect the program direction. For programmers, the content of PCLATH cannot be ignored and must be protected.
  In short, the protection and processing of the register PCLATH (corresponding to the shaded instructions in the program, that is, items 5 to 9) is not necessary in all cases, but there is no harm in arranging these instructions uniformly when writing interrupt service programs. As long as the content of the PCLATH register does not need to be modified in the main program and the interrupt service program, it can be left unprotected. Specifically, the shaded instructions (that is, items 5 to 9) can only be omitted when the following two conditions are met at the same time.
  (1) There are no cross-page jumps in both the main program and the interrupt service program. For example: the user program does not use the program memory outside the 2KB space of page 0, or although the user program exceeds the range of 2KB, the GOTO or CALL instructions are not used simultaneously in the main program and the interrupt service program, which can meet this requirement.
  (2) The operation instructions with PCL as the target (such as table lookup) are not used simultaneously in the main program and the interrupt service program.
The operation order of saving the scene should be opposite to the operation order of restoring the scene. The 8th to 11th items in the program restore the contents of registers PCLATH and STATUS in the opposite order. However, do not forget the redundant swap operation generated by the "SWAPF STATUS,W" instruction when saving the scene. Here we have to use the same method to swap it back (corresponding to the 10th instruction in the program). The last two instructions swap the high and low nibbles of the content of W_TEMP twice before it is restored to the working register W. If only one transfer instruction "MOVF W_TEMP, W" is used, a new problem will arise: the "MOVF W_TEMP, W" instruction will affect the "Z" flag and destroy the contents of the previously restored register STATUS, which is what we do not want and cannot tolerate. Therefore, two SWAP instructions (i.e., the 12th and 13th instructions) that do not affect the flag are used in the program. Although it is a bit troublesome, this problem can be solved satisfactorily.
  Finally, it must be further emphasized that not all interrupt service routines require field protection, or all need to be protected as in the above example program. In some cases, it is not enough to protect only the three registers W, STATUS and PCLATH. However, based on this program fragment, it is easy to increase or decrease the number of registers that need to be protected. Don't forget that the working register W must be protected before protecting any file registers.
  3? Several issues that need to be noted
  (1) The state of the interrupt flag has nothing to do with whether the interrupt source generates an interrupt. In other words, regardless of whether the interrupt is allowed or not, as long as the interrupt condition is met, the interrupt flag will be set. In addition, the interrupt flag can also be set to "1" or cleared to "0" by software.
  (2) When an interrupt source is enabled, the interrupt source requests an interrupt from the CPU through the interrupt flag. Regardless of the reason, an interrupt will be generated as long as the interrupt flag is set. If the interrupt flag is forcibly set by software, an interrupt will also be generated.
  (3) If the interrupt flag is set when the interrupt is masked (or disabled), it will remain dormant as long as it is not cleared. Then, once the mask is removed, an interrupt will be generated immediately.
  (4) If the interrupt flag is set when the interrupt is disabled, but if it is cleared before the interrupt is allowed, it will not generate an interrupt even if the disablement is removed.
  (5) When any interrupt occurs in the CPU, the global interrupt mask bit GIE will be automatically cleared to 0; when the interrupt returns, it will automatically return to 1. If the reset GIE is reset by software during interrupt processing, and an interrupt request occurs again, interrupt nesting can be formed. In other words, if other interrupt requests are responded to during a certain interrupt, interrupt nesting is formed. When interrupt nesting occurs, the previous interrupt processing process is suspended and the next interrupt processing is entered. After the next interrupt process is processed, the previous interrupt will continue to be processed. In this way, multiple levels of nesting can be formed, even self-nesting. However, the number of nesting levels must not exceed the depth of the hardware stack.
  (6) For applications with strict requirements on interrupt response and processing time, the instruction arrangement of the protection scene should also consider the delay problem.
  (7) If multiple interrupt requests occur at the same time, the interrupt that gets priority depends entirely on the order in which the interrupt sources are checked in the interrupt service program. The reason is that there is no priority level between the interrupt sources.
If the instruction to clear the interrupt flag is placed at the end of the interrupt service routine, the opportunity to respond to the second interrupt request from the interrupt source during the interrupt processing may be lost.

This post is from Microchip MCU
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list