Hello, dear user.
In the
previous article, we began to consider programming under MSP430.
The material described in this article will allow you to familiarize yourself with the
interruptions and understand some of the subtleties of MSP430.
Introduction
Interrupt (English interrupt) - a signal informing the processor about the occurrence of an event. In this case, the execution of the current sequence of commands is suspended and control is transferred to the interrupt handler, which responds to the event and serves it, and then returns control to the interrupted code.
The interrupt mechanism is created to ensure the most rapid response of the program to certain events. This is a very important part of dating with any microcontroller.
Interruptions
Let's start with a small example.
- #include "msp430f2274.h"
- void main ( )
- {
- WDTCTL = WDTPW + WDTHOLD ;
- P1DIR & = ~ BIT2 ;
- P1REN | = BIT2 ;
- P1IE | = BIT2 ; // Enable interrupts on P1.2
- P1IES | = BIT2 ; // Interrupt occurs by 1/0 (release / press)
- P1IFG & = ~ BIT2 ; // Clear interrupt flag for P1.2
- P1DIR | = BIT0 + BIT1 ;
- P1OUT | = BIT0 ;
- P1OUT & = ~ BIT1 ;
- __bis_SR_register ( GIE ) ; // Set global interrupt enable flag
- while ( true ) ;
- }
- #pragma vector = PORT1_VECTOR
- __interrupt void P1INT ( ) // Interrupt Handler
- {
- P1IE & = ~ BIT2 ; // Disable interrupts on P1.2
- P1OUT ^ = BIT0 ; // P1.0 changes its state
- P1OUT ^ = BIT1 ; // P1.1 changes its state
- for ( volatile unsigned int i = 30000 ; i ! = 0 ; i - ) ; // Delay
- P1IE | = BIT2 ; // Enable interrupts on P1.2
- P1IFG & = ~ BIT2 ; // Clear interrupt flag for P1.2
- }
In this example, pressing a button (P1.2) causes an interruption, which changes the state of two LEDs (P1.0 and P1.1). Let's see how this happens.
PxIE enables interrupts for Px port pins. The value “1” written to a certain digit allows receiving interrupts from a certain pin.
')
PxIES determines by what level of signal the interruption will occur. In our case, this means that a unit placed in a particular digit of this register will allow receiving a button press event. And vice versa, zero will allow receiving a button release event.
Let me remind you that the button in this example is “pulled up” to one, which means that the pressed button has a value of zero.
On the wiring diagram, resistor R1 is drawn indicatively, in fact it is inside the microcontroller and turned on by the P1REN register.
PxIFG is the interrupt flag. In the case of a button press event, it will be set to one, which will cause the interrupt handler (__interrupt void P1INT ()). Accordingly, immediately after processing the event, the flag must be reset.
Try removing line 32 from the example at the end of the handler, and then, immediately after first pressing the button, the light bulbs will switch as if you are constantly pressing the button.
__bis_SR_register (GIE) sets the Global Interrupt Enable flag in the status register. In fact, this is equivalent to the SR | = GIE record, but we can access the SR register only by means of the __bis_SR_register and __get_SR_register functions.
Below is a diagram of the bits in the SR register.
The 0, 1, 2, and 8 bits are bits of mathematical operations.
4, 5, 6, 7 - control bits of energy consumption levels, by reducing the frequency or turning off the ALU.
Well, actually bit
3 is the global resolution of interrupts. As long as this bit is not set to one, no interrupts will be processed.
#pragma vector is a directive that specifies that the following function is a handler for the specified interrupt.
A list of all available interrupt vectors can be found in the header file for your controller. In this case, it is msp430f2274.h .
Contact Bounce
About this phenomenon can be
read in detail
in Wikipedia . Contacts bounce occurs when the button is pressed, so that the interrupt handler will be called repeatedly. In this example, this was avoided as follows:
- Immediately after calling the handler, the interrupt ban is set (line 25);
- after switching the states of the LEDs, a delay is made (line 30);
- interrupt resolution is set again (line 31).
The volatile directive in line 30 of the code means that the variable i will not be optimized during compilation. If you remove it, there will be no delay.
Conclusion
After reading the previous article, colleagues and friends reproached me for not paying enough attention to detail. This time I tried to correct this shortcoming and make the article more accessible. However, this greatly increased the amount of information.
Next time I will try to consider transferring data from the controller to a personal computer within the means of the programmer and, depending on the received volume, watchdog.
I hope this article has been helpful to you, reader.