320 likes | 538 Views
Chapter 6: Interrupts and Resets. The 68HC11 Microcontroller. Han-Way Huang. Minnesota State University, Mankato. Basics of Interrupts What is an interrupt? A special event that requires the CPU to stop normal program execution and
E N D
Chapter 6: Interrupts and Resets The 68HC11 Microcontroller Han-Way Huang Minnesota State University, Mankato
Basics of Interrupts What is an interrupt? A special event that requires the CPU to stop normal program execution and perform some service related to the event. Examples of interrupts include I/O completion, timer time-out, illegal opcodes, arithmetic overflow, divide-by-0, etc. Functions of Interrupts - Coordinating I/O activities and preventing CPU from being tied up - Providing a graceful way to exit from errors - Reminding the CPU to perform routine tasks Interrupt Maskability - Interrupts that can be ignored by the CPU are called maskable interrupts. A maskable interrupt must be enabled before it can interrupt the CPU. An interrupt is enabled by setting an enable flag. - Interrupts that can’t be ignored by the CPU are called nonmaskable interrupts.
Interrupt priority The order in which the CPU will service interrupts when all of them occur at the same time. Interrupt Service The CPU provides service to an interrupt by executing a program called the interrupt service routine. A complete interrupt service cycle includes 1. Saving the program counter value in the stack 2. Saving the CPU status (including the CPU status register and some other registers) in the stack 3. Identifying the cause of interrupt 4. Resolving the starting address of the corresponding interrupt service routine 5. Executing the interrupt service routine 6. Restoring the CPU status and the program counter from the stack 7. Restarting the interrupted program
Interrupt Vector Starting address of the interrupt service routine Interrupt Vector Table A table where all interrupt vectors are stored. Methods of Determining Interrupt Vectors 1. Predefined locations (8051 approach) 2. Fetching the vector from a predefined memory location (68HC11) 3. Executing an interrupt acknowledge cycle to fetch a vector number in order to locate the interrupt vector (68000 and x86 families) Steps of Interrupt Programming Step 1. Initializing the interrupt vector table Step 2. Writing the interrupt service routine Step 3. Enabling the interrupt
The Overhead of Interrupts Saving and restoring of CPU status and other registers. (68HC11 needs to save all CPU registers)
Resets - The initial values of some CPU registers, flip-flops, and the control registers in I/O interface chips must be established in order for the computer to function properly. - The reset mechanism establishes these initial conditions for the computer system. - There are at least two types of resets: power-on reset and manual reset. - The power-on reset establishes the initial values of registers and I/O control registers. - The manual reset without power-down allows the computer to get out of most error conditions if hardware doesn’t fail. - A reset is nonmaskable.
68HC11 Interrupts The 68HC11 supports 16 hardware interrupts and two software interrupts. Hardware interrupts include: SCI serial system SPI serial transfer Pulse accumulator input edge Pulse accumulator overflow Timer overflow Timer output compare 5 Timer output compare 4 Timer output compare 3 Timer output compare 2 Timer output compare 1 Timer input capture 3 Timer input capture 2 Timer input capture 1 Real time interrupt IRQ pin XIRQ pin Software interrupts: SWI instruction and illegal opcode. Both are nonmaskable.
The 68HC11 Interrupt-Handling Procedure - Saving the CPU registers in the stack - Fetching the interrupt vector from a predefined memory location for the pending interrupt. - Resuming program execution from the fetched interrupt vector. The 68HC11 Interrupt Stacking Order
Example 6.1 The 68HC11 is executing the TAP instruction of the following program when the IRQ interrupt occurs. List the stack contents immediately before the interrupt service routine is entered. Solution: 1. After line 1: [B] = $20 2. After line 2: [SP] = $FF 3. After line 3: [X] = $1000 4. After line 4: [A] = 0 5. After line 5: [Y] = $100 6. After line 6: [CCR] = $00 The Stack contents are shown in Figure 6.4 in next page.
Priority Structure of the 68HC11 Maskable Interrupts - The priority of each 68HC11 interrupt source is fixed. - The user can promote one of the maskable interrupts to the highest priority among those maskable interrupts by programming the HPRIO register. - The selection of highest priority interrupt is shown in Table 6.2.
IRQ interrupt - can be masked by the I bit of the CCR register - is level-sensitive by default (asserted low) - IRQ interrupt can be configured to be falling edge-sensitive by setting the IRQE bit (bit 5) of the OPTION register to 1 within the first 64 E clock cycles after reset. - IRQ interrupt vector is shared by the IRQ pin interrupt and the I/O handshake subsystem XIRQ interrupt - can be masked by the X bit of the CCR register - the X bit can only be cleared during the first 64 E clock cycles after reset and cannot be cleared and reset after that - when an XIRQ interrupt occurs, all registers are saved in the stack and the X bit in the CCR register is set to 1 (not by the user program) to prevent further XIRQ interrupts. - XIRQ interrupt is often used to detect emergent situation because of its high priority. Illegal Opcode Trap - some of the opcode byte (s) combinations are not defined and hence are illegal instructions - can’t be masked
The Software Interrupt Instruction (SWI) - CPU registers are saved in the stack like any other maskable instruction - cannot be masked by the I and X bits in the CCR register - often used to implement the breakpoint Low-Power Modes - A microcontroller is mainly used as the controller of an embedded product. - An embedded product is often powered by batteries. - A good microcontroller should consume as little power as possible. - The power consumption can’t be avoided during normal operation. - The power consumption of a microcontroller-based product should be reduced to minimal when the CPU is not performing useful works. - The 68HC11 provides two low-power modes: WAIT and STOP modes. The WAIT instruction - The 68HC11 is placed in a low power mode while keeping the oscillator running. - Upon the execution of this instruction, all CPU registers are saved in the stack. - The wait state can be exited only through an unmasked interrupt or reset. - This instruction can be used when the CPU has nothing to do but wait for the arrival of an interrupt.
The STOP instruction - When the S bit in the CCR register is 0, the STOP instruction places the CPU in the lowest power mode. - All clocks including the internal oscillator are stopped, causing all internal processing to be stopped. - Exit from the STOP mode can be accomplished by RESET, an XIRQ interrupt, or an unmasked IRQ interrupt. - When the XIRQ interrupt is used and the X bit in the CCR register is 1, then no XIRQ service routine is executed. The CPU continue to execute the instruction following the STOP instruction. Otherwise, the XIRQ service routine will be executed.
The 68HC11 Resets Four possible sources of resets: RESET pin, power-on reset, computer operating properly, and clock monitor failure. RESET pin Reset - This pin must be driven low for 8 E clock cycles in order to be detected. - This pin should be kept low when VDD is below its minimum operating level so that the contents of the EEPROM won’t be corrupted. - A low-voltage inhibit circuit that holds reset pin low whenever VDD is below its minimum operating level is required to protect against EEPROM corruption.
The Power-On Reset - The power-on reset occurs when a positive transition is detected on VDD. - The power-on circuitry provides a 4064-cycle time delay from the time of the first oscillator operation. - This reset should not be used to detect drops in power supply. The CPU after reset - After reset, the CPU fetches the reset vector from locations $FFFE and $FFFF ( $BFFE and $BFFF in the special test or bootstrap mode) during the first three cycles and begins instruction execution. - The stack pointer and other CPU registers are indeterminate after reset. - The X and I bits of the CCR register are set to mask any interrupt requests. - The S bit of the CCR register is set to 1 to disable the STOP mode. - All I/O control registers are initialized by reset.
Establishing the Mode of Operation - The voltage levels on MODA and MODB pins are latched on the rising edge of the RESET signal to determine the mode of operation. - The upper four bits of the HPRIO register are also set by these mode select signals.
The Computer Operating Properly (COP) Watchdog Timer Reset - The COP watchdog timer system is intended to detect software processing errors. - The COP circuit will not reset the CPU as long as the application software reset the COP timer before it times out. - If the COP timer times out, it is an indication that the application software is no longer being executed in the intended sequence and thus a system reset is initiated. - The COP system is enabled by clearing the NOCOP bit in the CONFIG register and is disabled by setting the same bit. After the change of the NOCOP bit, the CPU must be reset before the new status becomes effective. - The software COP reset is a two-step sequence. The first step is to write a $55 to the COPRST register and then write a $AA into the same register.
- The default COP time-out interval is 215 E cycles. - The COP time out interval is programmable by setting the CR1 and CR0 bits of the OPTION register. - CR1 and CR0 together select a divide factor for E/215.
Clock Monitor Reset - The clock monitor circuit is based on an internal RC time delay. - If no clock (E clock) edges are detected within this RC time delay, the clock monitor can optionally generate a system reset (by asserting the RESET pin). - The clock monitor function is enabled/disabled by the CME bit (bit 3) of the OPTION register. - The RC time-out may vary from lot to lot and from part to part due to the IC fabrication process variation. - An E clock frequency lower than 10 KHz will be definitely detected as a clock monitor error and an E clock frequency higher than 200 KHz will not be detected as a clock monitor error. - The clock monitor is often used as a backup for the COP watchdog system because the COP system requires a clock signal to operate. - The second application of the clock monitor is to protect against unintentional execution of the STOP instruction.
Writing the Interrupt Service Routine - In assembly language xxx_ISR … … RTI - In C language #pragma interrupt_handler xxx_ISR void xxx_ISR ( ) { … } The statement “#pragma …” tells the C compiler to generate RTI instead of RTS as the last instruction of the function.
Set Up Interrupt Vector Table - Use assembler directives to set up interrupt vector table - For example, the vector entry for IRQ interrupt can be set up as follows (in assembly language): ORG $FFF2 FDB IRQ_ISR where IRQ_ISR is the label of the first instruction in the service routine. In C language, #pragma abs_address:0xfff2 void (*interrupt_vectors [ ]) (void) = { IRQ_ISR } #pragma end_abs_address
- The complete interrupt vector table in C language is as follows : #pragma abs_address:0xffd6 void (*interrupt_vectors [ ] (void) = { SCI_ISR, /* SCI interrupt service routine */ SPI_ISR, /* SPI */ PAI_ISR, /* PAI */ PAOV_ISR, /* PAOV */ TOF_ISR, /* TOF */ TOC5_ISR, /* TOC5 */ TOC4_ISR, /* TOC4 */ TOC3_ISR, /* TOC3 */ TOC2_ISR, /* TOC2 */ TOC1_ISR, /* TOC1 */ TIC3_ISR, /* TIC3 */ TIC2_ISR, /* TIC2 */ TIC1_ISR, /* TIC1 */ RTI_ISR, /* RTI */ IRQ_ISR, /* IRQ */ XIRQ_ISR, /* XIRQ */ SWI_ISR, /* SWI */ ILLOP_ISR, /* ILLOP */ COP_ISR, /* COP */ CLM_ISR, /* clock monitor */ _start /* reset */ }
The EVB & EVBU Interrupt Vector Jump Table - The design of EVB and EVBU precludes the user program to write into interrupt vector table because the memory space for the interrupt table is in ROM. - The EVB and EVBU reserve 60 bytes ($00C4-$00FF) of the on-chip SRAM as an interrupt vector jump table. - Each entry of the vector jump table consists of three bytes. The first byte should be set to the opcode ($7E) of the JMP instruction, and the second and third bytes should be set to the starting address of the corresponding service routine. - Each entry (two bytes) of the default vector table of the 68HC11 should contain the address of the first byte of the corresponding entry in the interrupt vector jump table. - To set up interrupt vector jump table (use IRQ as an example) In assembly language, In C language, ORG $00EE void IRQ_ISR ( ); JMP IRQ_HND main ( ) { … *(unsigned char *)0xee = 0x7E; *(void (**)())0xef = IRQ_ISR; … }
Interrupt Vector Jump Table for Demo Boards that Use Buffalo Monitor
Enable Interrupts - Clear the I bit of the CCR register will enable interrupt globally. - Most maskable interrupts have an enable bit that must be set to enable the individual interrupt in addition to setting the I bit. - For example, to enable the OC1 interrupt, we need to use the following statements: In assembly, In C language TMSK1 EQU $22 Use in-line assembly code asm (“cli”); or LDX #$1000 macro INTR_ON ( ); to enable interrupt BSET TMSK1,X $80 globally. CLI Use the statement TMSK1 |= 0x80 to enable OC1 interrupt locally.
Example 6.2 Write a main program and an interrupt service routine. The main program will initialize a variable count to 5, enable the IRQ interrupt, and stay in a loop to check the value of count. When the value of count is 0, the program jump to the BUFFALO monitor. The IRQ pin is connected to some circuit that will generate an interrupt from time to time. Solution: * set up the interrupt vector jump table entry ORG $00EE JMP IRQ_ISR * the main program is in the following ORG $00 count rmb 1 ORG $C000 SEI ; disable all maskable interrupts LDS #$DFFF ; set up stack pointer for EVB LDAA #5 ; initialize the variable count to 100 STAA count ; “ CLI ; enable interrupt to the 68HC11 loop LDAA count BNE loop SWI ; jump to BUFFALO monitor IRQ_ISR DEC count RTI END
Example 6.3 Write a C program for the problem in Example 6.2. Solution: #include <hc11.h> int count; main ( ) { count = 5; *(unsigned char *)0xee = 0x7E; *(void (**)())oxef = IRQ_ISR; INTR_ON ( ): while (count); INTR_OFF ( ); asm (“swi”); } #pragma interrupt_handler IRQ_ISR ( ) void IRQ_ISR ( ) { count -= 1; }