What are the maskable interrupts of MSP430?
[Copy link]
Interrupts largely reflect the performance of a microcontroller. From this point of view, MSP430 does a very good job in interrupts, mainly by providing a very rich interrupt source, the basic ones are IO interrupts, timer interrupts and some interface interrupts (SPI, UART, I2C) and so on.
Now I will talk about some features of MSP430 interrupts, mainly the issues that I feel are useful in project experience, and share them with you.
First, the priority of the MSP430 interrupt.
MSP430 supports interrupt priority, but how to know the priority? There is a very interesting statement in its manual. I quoted it from the original text: "The nearer a module is to the CPU/NMIRS, the higher the priority". The closer to the CPU/NMIRS, the higher the priority. So how do we know which module is close to the CPU? Look at the block diagram given in the datasheet? I always feel that this is impossible to reassure an electronics person. For example, if the block diagram is in the middle and the distance from the CPU is the same, how to distinguish it? So we have another more reliable method. IAR provides corresponding headers for each model of 430. You can know it just by looking at the interrupt vector address. The interrupt vector table of 430 starts from address value 0xFFC0 and ends at 0XFFFF. There are 32 table entries in total (each interrupt vector corresponds to 2 bytes). The interrupt vector corresponding to 0XFFCO has the highest priority, and the interrupt vector corresponding to 0XFFFE has the highest priority. That is, from 0xFFCO to 0xFFFF, the 32 interrupt priorities are from low to high. In this way, it is easy to figure out the priority of each interrupt.
MSP430 Interrupts
Second, the response process of MSP430 interrupt.
First of all, of course, the flag corresponding to the interrupt is set to 1. I will explain the process in detail at this time. It is actually a translated user manual, but it is still good to understand it.
1. The CPU will complete executing the current instruction.
2. The PC pointing to the next instruction is pushed onto the stack.
3. The status register SR is pushed onto the stack.
4. Select the interrupt with the best priority to service.
5. The interrupt flag of a single-source interrupt will be automatically cleared. Be careful here because the interrupt flags of P1 and P2 will not be automatically cleared because the IO interrupts of P1 and P2 are multi-source interrupts, which means that the 8 IOs of P1 or P2 correspond to an interrupt vector. The MCU knows that an interrupt has occurred in P1 or P2. No matter which IO of P1 occurs, it will point to the interrupt vector of P1. The same is true for P2, so it needs to be manually cleared in the code.
6. The status register SR is cleared, any low power state will be terminated, and the global interrupt enable is turned off (GIE). This is quite different from 51. After responding to an interrupt, 430 will turn off the global interrupt enable and will not respond to any other interrupts including those with high priority. That is to say, there is no interrupt nesting in the default state. If interrupt nesting is used, _EINT() needs to be used to enable the global interrupt.
7. The interrupt vector is loaded into the PC and the interrupt service function begins to execute.
The above is the entire interrupt reception process. I have marked the more important parts with colored fonts.
Interrupt return is relatively simple. The interrupt service function will return by the RETI instruction, SR will be popped up, the microcontroller will be restored to the state before the interrupt, PC will also be popped up, and instructions will continue to be executed.
Third, enable interrupts and interrupt service functions.
This is where I struggled in the project, so please be careful.
Once the MSP430 opens the peripheral interrupt, such as the SPI receive interrupt.
When the SPI receive interrupt is enabled, once the microcontroller finds that the SPI receive flag is set, it will load the interrupt vector. But what will happen if we don't use the SPI receive interrupt? Since it is not used, there is no service function for the SPI receive interrupt. What is the address value of the interrupt service function pointed to in the interrupt vector at this time? It is all 0. The CPU fetches instructions from 0-01FFh, and only one thing will happen. PUC, power-on clear. Then the PC will load the content of the 0xFFFE interrupt vector, which is the reset vector, and the program will jump to the startup code we made for IAR. The program will execute to the first sentence of the main() of the code we wrote. This is how tragedy is born, the machine is broken!!!!
|