Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] MSP430 - Multiple Interrupts on the same port

Status
Not open for further replies.

Andy2k7

Newbie level 3
Joined
Feb 29, 2012
Messages
4
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,323
This is my code so far and I'm not really sure what I should be putting in the switch statement so that when I push the button connected to P1.3 LED0 will be toggled and when I push the one connected to P1.7 LED1 will be toggled.



Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "io430.h"
#define LED0 BIT0
#define LED1 BIT6 
 
void main( void )
{
  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;
  P1DIR |= (LED0 + LED1);
  P1OUT &= ~(LED0 + LED1);
  P1IE |= (BIT3 + BIT7);
  
  __enable_interrupt();
  
  while(1)
  {
  }
}
 
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
  switch(P1IFG)
  {
  case ????:
      P1OUT ^= LED0; // P1.0 = toggle;
  case ????:
      P1OUT ^= LED1; // P1.6 = toggle
  }
P1IFG &= ~(BIT3 + BIT7); // P1.3 IFG cleared
}

 

doraemon

Super Moderator
Staff member
Joined
Jun 21, 2009
Messages
1,082
Helped
276
Reputation
560
Reaction score
254
Trophy points
1,363
Location
Japan
Activity points
10,756
Hello!

You cannot do like this, because (also not very probable), 2 interrupts may be in the same vector.
For instance, if P1IFG is 0x88 (bit3 and bit7), it will not be caught by case 0x80 and neither by
case 0x88. The solution is:
Code:
if(P1IFG & BIT3) {
    P1OUT ^= LED0;
    P1IFG &= ~BIT3;
}
if(P1IFG & BIT7) {
    P1OUT ^= LED1;
    P1IFG &= ~BIT7;
}

By the way, your while loop is useless. It will simply consume
clock cycles and do nothing more. I don't know what __enable_interrupt()
does, but why not using low power mode?
I would write it like this:

Code:
#include "io430.h"
#define LED0 BIT0
#define LED1 BIT6 
 
void main( void ) {
	// Stop watchdog timer to prevent time out reset
	WDTCTL = WDTPW + WDTHOLD;
	P1DIR |= (LED0 + LED1);
	P1OUT &= ~(LED0 + LED1);
	P1IE |= (BIT3 + BIT7);
	_BIS_SR(LPM0 + GIE);
}
 
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {
	__DINT();
	if(P1IFG & BIT3) {
	    P1OUT ^= LED0;
	    P1IFG &= ~BIT3;
	}
	if(P1IFG & BIT7) {
	    P1OUT ^= LED1;
	    P1IFG &= ~BIT7;
	}
	__EINT();
}

Note that I didn't test it, but I would guess it works.
I have added __DINT an __EINT so that nested interrupts are avoided.

Dora.
 
Last edited:

Andy2k7

Newbie level 3
Joined
Feb 29, 2012
Messages
4
Helped
1
Reputation
2
Reaction score
1
Trophy points
1,283
Activity points
1,323
Thank you. Your first solution works perfectly I'll look into using low power mode in tonight. Also __enable_interrupt() is the exact same command as __EINT
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top