Você está na página 1de 5

MSP430 Interrupts Introduction. Interrupts are a relatively advanced topic in microprocessor programming.

They can be very useful in control applications particularly when the microprocessor must perform two tas s apparently at the same time! or when critical timing of program e"ecution is re#uired. $rdinary subroutines are called using the %&'' instruction. Interrupts are very much li e hardware generated %&''(s. )hen an interrupt occurs *and certain other conditions are met+! the microprocessor saves the current state of its program counter and status register on the stac and ,umps to a section of the program which is ,ust li e a subroutine! written for the purposes of servicing *responding to+ the interrupt. )hen this interrupt service routine is complete it e"ecutes a -eturn .rom Interrupt *-/TI+ instruction which restores the saved microprocessor registers to their original state and the interrupted program carries on from where it left off. Interrupts are typically generated by a transition *logic 0 to 0 or 0 to 0+ on a particular pin on the microprocessor or by a particular level *0 or 0+ on a pin. They can also be caused by circuits within the microprocessor itself. The MSP430 recognises the interrupts from many sources and of different priorities. 1etails are #uite model specific however! the 430"44" range support the interrupts shown in Table 0*ta en from TI datasheet+. )hen do you use interrupts2 %onsider the following scenario3 & microprocessor is to be used to maintain a user interface while at the same time wait for data to arrive from some serially connected device. This could be achieved by inserting instructions to read the status of some 4&-T register throughout the controlling program. This is not a great solution however as it re#uires the programmer to be very disciplined *one false move and data could be lost+. Interrupts provide a more elegant way of achieving the same effect. 4sing interrupts! the programmer writes code to handle the user interface without worrying about the arrival of data over the serial lin . 5ardware permitting! the arrival of a byte of data can be used to generate an interrupt. The processor will briefly stop what it is doing! grab the newly arrived byte *perhaps process it+ and then return to the user interface. %omputers do this sort of 6multitas ing7 all the time. &nother useful feature of interrupts! particularly with the MSP430 is that they can be used to save power *great for battery applications+. The processor spends most of its time in a low power state! only wa ing upon receipt of an interrupt when some event ta es place.

Interrupt Source

Interrupt Flag

Maskable

Vector Address

Priority 0> *highest+

Power8up! e"ternal )1TI.9 reset! )atchdog :/;< Timer! .lash memory =MI! $scillator .ault! .lash Memory &ccess <iolation Timer?@A Timer?@A =MII.9! $.I.9! &%%<I.9 T@%%-0 %%I.9 T@%%-0 to T@%%-B %%I.9(s T@I.9 %&I.9 )1TI.9 4-EI.90 4TEI.90 &1%0DI.9 T&%%-0 %%I.9 T&%%-0 and T&%%-D %%I.9(s! T&I.9 P0I.9.0 to P0I.9.A 4-EI.90 4TEI.90 PDI.9.0 to PDI.9.A @TI.9

=o *reset+ 0.../h

=ot globally

0...%h

04

;es ;es

0...&h 0...Ch

03 0D

%omparator?& )atchdog Timer 4S&-T0 -eceive 4S&-T0 Transmit &1%0D Timer?&3 Timer?&3

;es ;es ;es ;es ;es ;es ;es

0...Bh 0...4h 0...Dh 0...0h 0..//h 0../%h

00 00 F C A B

0../&h

> ;es ;es ;es ;es ;es 0../Ch 4 0../Bh 0../4h 0../Dh 0 0../0h 0 3 D

IG$ Port P0 *C flags+ 4S&-T0 -eceive 4S&-T0 Transmit IG$ Port PD *C flags+ @asic Timer0

Table 03 MS9430"44E Interrupts.

/"ample3 4sing the basic timer interrupt. The %8Source code that follows implements a simple real time cloc *apologies in advance if the basic time control register setting is a bit off+.
//****************************************************************************** // This program demonstrates how the Basic Timer may be used to implement a // simple time of day clock. //****************************************************************************** #include <msp43 !44!.h" int seconds# int minutes# int hours# int days# int ticks# // This will drift and will re$uire calibration % ok for testing though. #define T&'()*+,-*),'./0 12 3oid main43oid5 6 70T'T8 9 70T+7 : 70T;.80# // )top 70T # // start clock at run time

ticks 9 seconds 9 minutes 9 hours 9 days 9 &,1 <9 BT&,# BT'T8 9 BT)),8:BT&+1:BT&+=:BT&+ # *,&/T45# for 4##5 6 *B&)*)-4'+@.AA5# */.+45# D // // // // //

,nable BT interrupt 0i3ide )ystem clock by 12> The default system clock is appro! >4 k;? so this should gi3e a tick rate of 12 ;? ,nable interrupts

// ,nter 8+B // -e$uired only for 'Cspy

// Basic Timer interrupt ser3ice routine interruptEBF)&'T&B,-*G,'T.-H 3oid basic*timer43oid5 6 ticks::# if 4ticks "9 T&'()*+,-*),'./05 6 ticks 9 # seconds::# if 4seconds " 2I5 6 seconds 9 # minutes::# if 4minutes " 2I5 6 minutes 9 # hours::# if 4hours " 135 6 hours 9 # days::# // day of weekJ calender etc. not implemented. D D D D D

The details of the basic timer will be left to a later note. )hat is at issue here is the way in which interrupt handling is coded in %. The first step is to enable the specific interrupt involved via the interrupt enable register. This is followed by an enabling of the global interrupt flag using the ?/I=T*+ 6function7 8 this is translated to an 6eint7 machine instruction. The other part of the process of using interrupts it to set the interrupt vector. The I&- %8compiler does

this wor for you. The interrupt service routine must be declared as returning no values and accepting no parameters *after all! it is not called in the traditional manner+. The declaration of the function must be modified using the 6interrupt7 modifier. This along with an argument has two effects3 0+ It replaces the normal subroutine return instruction with a 6reti7 *return from interrupt instruction+ D+ It inserts the address of the function at the specified offset within the interrupt vector table. * BF)&'T&B,-*G,'T.- in this case+. )hen using interrupts care should be ta en to avoid 6collisions7 between sections of code that attempt concurrently use a shared resource *e.g. a port or global variable+. .igure 0a shows how problems of this sort might arise arise. .igure 0b illustrates a mechanism for overcoming this problem.

int main*void+ 3 while*0HH0+ I portHP0$4TJ iH0J ,HD0J P0$4THport K DJ 3 L

P1$%T&" InterruptM
void IS-D*void+I P0$4T H P0$4T K 0J L

P1$%T&1 P1$%T&'

Figure 1a. The main program loop wants to set b1 of Port 1. It does this by copying the current byte of Port 1, updates the copy, and then writing the copy back. However, ust after copying the Port contents, an interrupt takes place which modifies the port !sets b"#. The main routine knows nothing of this and overwrites it with a stale copy. Port1." and Port1.1 should both be 1 after this but only Port1.1 is.

int main*void+ 3 while*0HH0+ I ?1I=T*+J portHP0$4TJ iH0J ,HD0J P0$4THport K DJ ?/I=T*+J 3 L

P1$%T&"

InterruptM P1$%T&'

void IS-D*void+I P0$4T H P0$4T K 0J L

P1$%T&.

Figure 1b. In this case, the main loop disables interrupts while it is updating the port contents. This prevents the local copy of the port contents from becoming stale however it does run the risk of interrupts being lost. (ome te)ts would describe the section of code that performs the update as a *critical section+ i.e. it must not be interrupted. It is generally a good idea to keep critical sections as short as possible. In some cases other techni,ues such as locking !using a global-shared variable# may be more appropriate.

Você também pode gostar