HOME

PROJECTS

TUTORIALS

C FUNCTIONS

PROGRAMS

PRODUCTS

VIDEOS

COMPANY

SPANISH

                 

tutorial: handling interrupts in assembly language with 18F2550 microcontroller

 

 

 

Introduction:

Programming using interrupts is a technique based on an automatic mechanism in the hardware of the microcontroller, which allows a device to provide service to internal or external devices, only at the moment it is required.

An interrupt is actually a call to a subroutine, but initiated by the peripheral hardware itself and not by the "CALL" instruction. The interrupt is asynchronous and can occur at any time during the execution of the main program.

The interrupt handling is an alternative to a method known as "polling", which is reviewing the status of each of the peripherals, over and over again in a continuous loop, to see if any of them needs service.

 

 

 

To understand this process, we can set an example in practical life where a speaker (the microcontroller) besides dictating his lecture (main program), asks one by one each of the participants (peripherals), to see if any of them has a question (if they require attention from microcontroller). Obviously such a method leads to a loss of speaker time (processing time of the microcontroller) that could be used more efficiently.

But if the questions were made with the audience raising their hands whenever they need attention, only then an "interrupt" to the main program (the conference) is generated. The speaker then has enough time to answer the question (give attention to peripheral) and continue with his lecture.

The interrupt handling can manage "multitasking", ie, a programming technique which can give attention to many peripherals, minimizing processing time. A very illustrative case is that of PC computers, where the keyboard, mouse, hard disk, the real time clock, printer, modem, and finally, all peripherals are controlled and serviced through the operating system, via an interrupt scheme.

Interrupt Service subroutine

Based on the figures above, when the interrupt signal is generated, the microcontroller finishes first execution of the instruction that is currently being processed, then stores on the stack memory the address of the next instruction code and later calls the "interrupt service subroutine", beginning in the address 0x008H of code memory, for the 18F2550 microcontroller.

At the end of the interrupt service subroutine, using the statement "RETFIE" (Return From Interrupt), the program flow returns to the main program through the same mechanism used by the subroutines "CALL", ie  recovering the return address previously stored on the stack.

Example of interrupt handling in assembly language for Bolt v.Lite or Bolt 18F2550 system

The 18F2550 Bolt system uses the first 2K of memory to store its Bootloader code. In this program, there is a vector for redirecting the interrupt address to 0x808, so that the user has sufficient memory space to program their interrupt service subroutines. Next is an example of interrupt handling in the Bolt system, using the timer interrupt 0.

The example combines two tasks: in Task 1, the processor turns the RB7 led on and off to a period of 1 second. This task is performed by the TIMER interrupt 0. In Task 2, which is in charge of the main program, the microcontroller performs a binary count in bits RB0 ... RB3. The period of the counter in this case is 200 ms.

 

BOLT-TIMER-0-INTERRUPT-2.ASM TEST PROGRAM FOR TIMER 0
BOLT-TIMER-0-INTERRUPT-2.HEX Executable file, load in Bolt v.Lite system
KEYBOLT.inc AUXILIARY FILE

DO NOT FORGET TO STORE IN RAM MEMORY, W AND STATUS REGISTERS ON ENTERING THE INTERRUPT SUBROUTINE.

Once inside the interrupt subroutine, the programmer must immediately save W and STATUS registers to avoid losing its contents upon return from the subroutine. SWAPF instruction, which performs an exchange between the most significant bits and least significant of a memory location is used because its implementation does not alter the STATUS register. In the following examples, we use the locations "SALVAW" to store the W register and "SALVASTATUS" to save the STATUS register:

    MOVWF       SALVAW                ;SAVING W IN MEMORY.
    SWAPF        STATUS,w              ;SAVING STATUS IN W
    MOVWF      SALVASTATUS      ;SAVING STATUS REGISTER IN MEMORY

Then we write here the service subroutine interruption, which performs a specific task. At the end of the subroutine, before returning to the main program, we retrieve the values ​​of W and STATUS registers like this:

    SWAPF       SALVASTATUS,w         ;STATUS  stored back from memory to W
    MOVWF     STATUS                         ;STATUS stored back in file register  
    SWAPF       SALVAW,F                    ;SWAP of register SALVAW. STATUS is not affected

    SWAPF       SALVAW,W                   ;w value is stored back. STATUS is not affected
    RETFIE                                             ;return from interrupt