如何为MSP430G2双位计数器代码添加中断服务程序检测按键事件?
Adding Interrupt Service Routines (ISRs) to Your MSP430G2 Dual-Digit Counter
Got it, let's walk through adding ISRs for your key inputs (S2, P1.7, P2.4) so your counter responds to button presses via interrupts instead of polling. I'll start with a complete, annotated code example and break down the key parts to make it easy to follow.
First, Fill in Hardware Definitions
I'll add common LaunchPad pin definitions since your original code had a partial #define LEDS—adjust these to match your actual hardware if needed:
#define LEDS BIT0 | BIT6 // P1.0 (red) and P1.6 (green) as dual-digit display pins #define S2 BIT3 // LaunchPad's built-in S2 button on P1.3 #define DECREASE1 BIT7 // External decrease switch on P1.7 #define DECREASE2 BIT4 // External decrease switch on P2.4
Full Code with ISRs
#include <msp430.h> #define LEDS BIT0 | BIT6 #define S2 BIT3 #define DECREASE1 BIT7 #define DECREASE2 BIT4 unsigned int counter = 0; // Dual-digit counter (0-99, adjust range as needed) void main(void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer to prevent reset // Configure LED pins as outputs P1DIR |= LEDS; P1OUT &= ~LEDS; // Initialize LEDs to off // Configure input pins with pull-up resistors // Pull-up keeps pins high until button presses pull them low P1REN |= S2 | DECREASE1; P1OUT |= S2 | DECREASE1; P2REN |= DECREASE2; P2OUT |= DECREASE2; // Enable GPIO interrupts for our buttons P1IE |= S2 | DECREASE1; // Turn on interrupts for P1.3 and P1.7 P2IE |= DECREASE2; // Turn on interrupts for P2.4 P1IFG &= ~(S2 | DECREASE1); // Clear pending interrupt flags (critical!) P2IFG &= ~DECREASE2; __enable_interrupt(); // Enable global interrupts (required for any ISR to run) // Enter low-power mode 0 to wait for interrupts (CPU sleeps, saves power) while(1) { __bis_SR_register(LPM0_bits); // Update your dual-digit display here when the counter changes // Example: Map counter digits to LEDs (replace with your actual display logic) P1OUT = (counter % 10) ? BIT0 : 0; // LSB on P1.0 P1OUT |= (counter / 10) ? BIT6 : 0; // MSB on P1.6 } } // Port 1 Interrupt Service Routine (handles S2 and P1.7) #pragma vector=PORT1_VECTOR __interrupt void Port_1_ISR(void) { // Debounce delay: Ignore switch bounce (adjust cycle count if needed) __delay_cycles(10000); if(P1IFG & S2) { // S2 pressed: Increment counter (cap at 99 to avoid overflow) if(counter < 99) counter++; P1IFG &= ~S2; // Clear the interrupt flag (must do this!) } else if(P1IFG & DECREASE1) { // P1.7 pressed: Decrement counter (stop at 0) if(counter > 0) counter--; P1IFG &= ~DECREASE1; // Clear flag for this pin } __bic_SR_register_on_exit(LPM0_bits); // Wake CPU to update the display } // Port 2 Interrupt Service Routine (handles P2.4) #pragma vector=PORT2_VECTOR __interrupt void Port_2_ISR(void) { // Debounce delay __delay_cycles(10000); if(P2IFG & DECREASE2) { // P2.4 pressed: Decrement counter if(counter > 0) counter--; P2IFG &= ~DECREASE2; // Clear interrupt flag } __bic_SR_register_on_exit(LPM0_bits); // Wake CPU }
Key Implementation Notes
Interrupt Setup:
- Pull-up resistors (
RENbit) ensure pins stay high until a button press pulls them low—this is standard for active-low buttons. P1IE/P2IEregisters enable interrupts for specific pins;P1IFG/P2IFGflags track which pin triggered the interrupt. Always clear these flags before entering your main loop to avoid spurious triggers.__enable_interrupt()turns on global interrupts—without this, no ISRs will run.
- Pull-up resistors (
ISR Basics:
- The
#pragma vectordirective tells the compiler which interrupt vector this function handles (PORT1_VECTOR for all P1 interrupts, PORT2_VECTOR for P2). - Debounce delay fixes switch bounce, which causes multiple interrupt triggers from a single button press. Adjust the cycle count if your buttons still misbehave.
- Always clear the interrupt flag after handling the button press—if you skip this, the ISR will fire nonstop.
__bic_SR_register_on_exit(LPM0_bits)wakes the CPU from low-power mode so the main loop can update the display.
- The
Counter Logic:
- I added bounds checking (0-99) to prevent underflow/overflow—tweak this range to match your dual-digit display's capabilities.
- Replace the example LED update code with your actual display logic (e.g., seven-segment decoding if you're using those).
Troubleshooting Tips
- If interrupts don't fire: Double-check that you enabled global interrupts with
__enable_interrupt(), and that you cleared theIFGflags before entering the main loop. - If buttons trigger multiple counts: Increase the debounce delay (
__delay_cyclesvalue). - Ensure external switches are wired correctly: One terminal to the GPIO pin, the other to ground (since we're using pull-up resistors).
内容的提问来源于stack exchange,提问作者Beshoy Hanna
相关产品推荐
相关产品推荐

