Mastering the art of doing nothing. How to sleep efficiently and wake up instantly.
The MSP430 is a sleep champion. Configure the 4 bits in the Status Register (SR) to shut down clocks and save battery.
The CPU constantly asks: "Are you ready? Are you ready?"
Hardware passes the signal down the line. First come, first served.
Direct jump to the handler function. Fastest response.
A peripheral (Timer, GPIO) sets its flag IFG = 1.
The CPU checks if IE = 1 and
global GIE = 1.
The CPU automatically does this (taking ~6 cycles):
The CPU reads the address from the Vector Table (0xFF80 - 0xFFFF) and jumps
to your ISR code.
Special instruction. It POPs SR and PC back from the stack. The CPU returns to exactly where it was (and importantly, returns to sleep if it was sleeping!).
BIS.B #BIT0, &P1DIR ; P1.0 = output (LED) BIC.B #BIT1, &P1DIR ; P1.1 = input (BTN) BIS.B #BIT1, &P1REN ; Enable pull resistor BIS.B #BIT1, &P1OUT ; Pull-up BIC.B #BIT1, &P1IFG ; Clear flag first! BIS.B #BIT1, &P1IE ; Enable interrupt BIS.W #GIE+LPM3, SR ; Sleep + enable GIE
P1_ISR: XOR.B #BIT0, &P1OUT ; Toggle LED BIC.B #BIT1, &P1IFG ; Clear flag RETI ; Return & sleep ; --- Vector Table --- .intvec PORT1_VECTOR, P1_ISR
Simulating Port 1 Interrupts. Click pins to set flags.
Hardware Priority: P1.0 (Highest) > P1.7.
*Automatically clears its flag when read!
Waiting...
Do the minimum (set a flag, copy a byte) and exit. Leave heavy processing for `main()`.
NEVER use `__delay_cycles()` or polling loops inside an ISR. You will freeze the system.
Clear an interrupt flag (e.g., `P1IFG`) BEFORE enabling the interrupt to avoid instant unplanned jumps.
Variables shared between `main()` and ISRs must be declared `volatile` so the compiler doesn't optimize them away.