Jump to content
43oh

Interrupt help.


Recommended Posts

Hi, 

 

I have posted about this before but I am still struggling :(

 

I want my code to:

 

Be in LPM until it detects an input on P1.3

When an input on P1.3 and P1.5 are present execute code which turns on P1.5 for a count of i

go back into LPM

 

What I don't understand is what the interrupt is actually DOING. By this I mean I know the code below is the interrupt routine on Port 1 but is this waking the 430 up? Should my code I want to execute whilst the 430 is awake go in here or somewhere else? 

 

        // Port 1 interrupt service routine

         #pragma vector=PORT1_VECTOR

         __interrupt void Port_1(void)

 

Also what does the interrupt flag actually do?

 

P1IFG &=~BIT3;                        // P1.3 IFG cleared

 

 

When I compile my program it compiles ok, but there is obviously something a miss as when I operate it on a 430 it doesn't work. I have read the MSP430x2xx family manual and looked at various examples online but still cannot figure out where i'm going wrong. 

 

Thanks for your help. 

 

 

 

 

FULL CODE BELOW:

 

#include <msp430.h>

 

/*

 * main.c

 */

 

volatile long int i;

 

int main(void) {

    WDTCTL = WDTPW | WDTHOLD;                                 // Stop watchdog timer

    CCTL0 = CCIE;                             // CCR0 interrupt enabled

    TACTL = TASSEL_2 + MC_1 + ID_3;           // SMCLK/8, upmode

 

    P1SEL = 0x00;                                                              // setting all P1 pins to GPIO

 

    P1DIR |= BIT2;                            // Set P1.2 to output direction. The rest are input.

    P1REN |= BIT3;                                                             // Enable Pullup Res on P1.3

    P1OUT |= BIT3;                                                             // Select pullup mode for P1.3 set to "1" in non-operated state.

 

    // INTERRUPTS

    P1IE |= BIT3;                                                              // Enable Interrupt on P1.3

    P1IES |= BIT3;                                                             // HI->LOW edge

    P1IFG &= ~BIT3;                                                    // Clears interrupt flag (IFG) on P1.3

 

    P1IN =BIT2;                                                        // Set P1.2 to LOW

    P1OUT =BIT5;                                                           // Set P1.5 to LOW

 

    _BIS_SR(CPUOFF + GIE);                           // Enter LPM0 w/ interrupt

      while(1)                                //Loop forever, we work with interrupts!

      {}

}

 

         // Port 1 interrupt service routine

         #pragma vector=PORT1_VECTOR

         __interrupt void Port_1(void)

         {

                          P1OUT |= BIT2;                                     // set P1.2 high

                          i=15000;

                         do(i--);

                         while (i !=0);

                          P1OUT &= ~BIT2;                                             // set P1.2 to low

 

                          P1IFG &=~BIT3;                        // P1.3 IFG cleared

         }

Link to post
Share on other sites

Short form:

 

One interrupt is shared by all pins on a given I/O port. When the specified transition occurs on the pin (low to high or high to low), several things happen: The transition sets a flag in the port's interrupt register so the program can identify WHICH pin triggered the interrupt. If the processor is asleep, it is woken up. Then, the interrupt routine is called, which disables maskable interrupts.

 

The line you asked about clears the interrupt bit for P1.3 so that the interrupt isn't retriggered when the interrupt handler ends. When the handler ends, unless you specify that the processor state should be different, it will go back to the same state it was in when the interrupt occurred, until the next one comes along, in your case LPM0.

 

The #pragma specifies to the compiler that the function following is to handle the port1 interrupts, so the compiler places its entry address in the appropriate interrupt vector location.

 

When running, it is all automatic: The transition happens, the flag is set, triggering the interrupt response of wake up. The hardware identifies which interrupt(s) came along, gets the target function address from the appropriate memory location, and does a call interrupt sequence.

 

 

Bad form: putting a loop in an interrupt handler. In a toy/learning program, it is ok, but it should not be done under normal circumstances, as it forces other interrupts to be locked out, and if the same one occurs while in the routine, it can't be serviced.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...