You are on page 1of 37

Functions, Interrupts, and Low-Power Modes

Functions and Subroutines It is good practice to break programs into short functions or subroutines It makes programs easier to write and more reliable to test and maintain Functions are obviously useful for code that is called from more than one place Functions can readily be reused and incorporated into libraries

What Happens when a Subroutine Is Called?


The call instruction first causes the return address, which is the current value in the PC, to be pushed on to the stack The address of the subroutine is then loaded into the PC and execution continues from there At the end of the subroutine the ret instruction pops the return address off the stack into the PC so that execution resumes with the instruction following the call of the subroutine

convention for the use of registers


The scratch registers R12 to R15 are used for parameter passing and hence are not normally preserved across the call The other general-purpose registers, R4 to R11, are used mainly for register variables and temporary results and must be preserved across a call. This means that you must save the contents of any register that you wish to use and restore its original contents at the end.

convention for the use of registers


The stack grows each time a function calls another function within it; in other words, the functions are nested. There is therefore a danger of running out of space if the nesting becomes too deep. Simulators monitor the stack and offer a warning when space is running low. There is no problem when a second function is called after another has returned because the space on the stack used by the first function should have been released.

Storage for Local Variables


Most functions need local variables and there are three ways in which space for these can be allocated CPU registers are simple and fast. The convention is that registers R4R11 may be used and their values should be preserved. This is done by pushing their values on to the stack.

Storage for Local Variables


A second approach is to use a fixed location in RAM There are two serious disadvantages to this approach. The first is that the space in RAM is reserved permanently, even when the function is not being called, which is wasteful. Second, the function is not reentrant. This means that the function cannot call a second copy of itself, either directly or with nested functions between.

Storage for Local Variables


The third approach is to allocate variables on the stack and is generally used when a program has run out of CPU registers

prg1

Prg2

Operation of the stack in the MSP430F1121A for the subroutine

Prg3

Stack in the MSP430F1121A for the subroutine

Complete stack frame for a subroutine with parameters passed, return address, saved copies of registers, and local variables

Interrupts
Interrupts are commonly used for a range of applications: Urgent tasks that must be executed promptly at higher priority than the main code. Infrequent tasks, such as handling slow input from humans. This saves the overhead of regular polling. Waking the CPU from sleep. This is particularly important in the MSP430, which typically spends much of its time in a low-power mode and can be awakened only by an interrupt. Calls to an operating system

ISR
The code to handle an interrupt is called an interrupt handler or interrupt service routine. Interrupts can be requested by most peripheral modules and some in the core of the MCU, such as the clock generator. Most interrupts are maskable, which means that they are effective only if the general interrupt enable (GIE) bit is set in the status register (SR).

ISR
The MSP430 uses vectored interrupts which means that the address of each ISR is stored in a vector table at a defined address in memory In most cases each vector is associated with a unique interrupt but some sources share a vector. Each interrupt vector has a distinct priority

INTERRUPT HANDLING
Interrupts must be handled in such a way that the code that was interrupted can be resumed without error. The hardware can take two extreme approaches to this 1. Copies of all the registers are saved on the stack automatically as part of the process for entering an interrupt 2. The opposite approach is for the hardware to save only the absolute minimum, which is the return address in the PC as in a subroutine.

What Happens when an Interrupt Is Requested? Hardware performs the following steps to launch the ISR 1.Any currently executing instruction is completed if the CPU was active when the interrupt was requested. 2. The PC, which points to the next instruction, is pushed onto the stack. 3. The SR is pushed onto the stack. 4. The interrupt with the highest priority is selected if multiple interrupts are waitingfor service.

What Happens when an Interrupt Is Requested?


The interrupt vector is loaded into the PC and the CPU starts to execute the interrupt service routine at that address.

Stack before and after entering an interrupt service routine.

Return from interrupt instruction reti


The SR pops from the stack.

The PC pops from the stack and execution resumes at the point where it was interrupted.

Interrupts vs. Polling


The most common alternative to interrupts for event-based control is polling, which is the process of manually checking values for changes on a repetitive basis Polling is inefficient, and very software intensive. Polling will turn your otherwise short main loop into a lengthy, time consuming one, creating unacceptable system latencies.

Interrupts vs. Polling


They cause conflicts require careful stack management create a host of debugging problems

Low-Power Modes of Operation


Active mode: CPU, all clocks, and enabled modules are active I 300A. The MSP430 starts up in this mode, which must be used when the CPU is required An interrupt automatically switches the device to active mode

Low-Power Modes of Operation


LPM0: CPU and MCLK are disabled, SMCLK and ACLK remain active, I 85A. This is used when the CPU is not required but some modules require a fast clock from SMCLK and the DCO.

Low-Power Modes of Operation


LPM3:
CPU, MCLK, SMCLK, and DCO are disabled, only ACLK remains active. I 1A. This is the standard low-power mode when the device must wake itself at regular intervals and therefore needs a (slow) clock. It is also required if the MSP430 must maintain a real-time clock

Low-Power Modes of Operation


LPM4: CPU and all clocks are disabled, I 0.1A.

The device can be wakened only by an external signal. This is also called RAM retention mode.

Low-Power Modes of Operation


The usual instructions in assembly language can be used to modify the bits that control the low-power modes symbols such as LPM0 are defined in the header file for each mode. bis.w #LPM3 ,SR ;

Low-Power Modes of Operation


The MSP430 can be awakened only by an interrupt so these must be enabled by setting the GIE bit in SR if it has not been done already. The following line is therefore much safer:

bis.w #GIE | LPM3 ,SR

Low-Power Modes of Operation


This cannot be done in standard C an intrinsic function is required. The function that follows is taken from intrinsics.h and sets both the low-power and GIE bits _low_power_mode_3 (); This simply calls another intrinsic function, _ _bis_SR_register()

Waking from a Low-Power Mode


An interrupt is needed to awaken the MSP430

Waking from a Low-Power Mode

Waking from a Low-Power Mode


The line with _ _enable_interrupt() is unnecessary because interrupts are enabled when the MSP430 is put into the low-power mode with _ _low_ power_mode_0().

Returning from a Low-Power Mode to the Main Function


Sometimes it is not appropriate to carry out all actions in an ISR and it is better to return to the main function in active mode this means returning to the function that put the device into the low-power mode. intrinsic function _ _low_ power_mode_off_on_exit() is available to do the job.

Returning from a Low-Power Mode to the Main Function

Returning from a Low-Power Mode to the Main Function

You might also like