help with receive interrupts

Hi. I’m new with Msp430 and I need help. Is there a way to run receive interrupt anywhere in a program, instead of using LPMs

_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt

#pragma vector= USART1RX_VECTOR

__interrupt void usart1_rx (void)

{

_BIC_SR_IRQ( LPM3_bits) ;…

etc…

What I want to do is, my program will run in an infinite loop. I want to stay in this loop (loop blinks a led), till I receive something. If I receive anything, program will exit from the loop.

Well, the easy way is enable interrupt without entering low power mode.

volatile uint8_t wakeup=0;

main()

{

eint();//Enable interrupt

while(wakeup==0)

{

delay();

P2OUT^=(1<<4);//Blink led on P2.4

}

__interrupt void usart1_rx (void)

{

wakeup=1;

}

Anyway this will increase power consumption, and the call to delay within the loop will cause problems if the micro needs fast response to usart interrupt. For example, if the delay is 200ms, and an interrupt occurs at the start of delay, the program won’t exit the loop until 200ms…

If this is a problem you need to blink the led from another interrupt routine (a timer interrupt).

OT: What is _BIC_SR_IRQ?

Thanks for your reply. I tried to do it as you explained but failed. Can you help me? Here’s my first code…

#include <msp430x16x.h>

void checkMes (char );

void delay(); // delay

void blinker(); // blink led

char message; // check received data

unsigned int delm=1; // # of delays

int t=0; // led’s not blinking when it is 0

void main(void)

{

WDTCTL = WDTPW + WDTHOLD; // Stop WDT

P3SEL |= 0xC0; // P3.6,7 = USART1 option select

ME2 |= UTXE1 + URXE1; // Enable USART1 TXD/RXD

UCTL1 |= CHAR; // 8-bit character

UTCTL1 |= SSEL0; // UCLK = ACLK

UBR01 = 0x0D; // 32k/2400 - 13.65

UBR11 = 0x00;

UMCTL1 = 0x6B; // Modulation

UCTL1 &= ~SWRST; // Initialize USART state machine

IE2 |= URXIE1; // Enable USART1 RX interrupt

P1DIR |=BIT0;

P1OUT =~BIT0;

// Mainloop

for (;:wink:

{

_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/interrupt

#if 1

while (!(IFG2 & UTXIFG1)); // USART1 TX buffer ready?

TXBUF1 = RXBUF1;

#endif

}

}

#if 1

// UART1 RX ISR will for exit from LPM3 in Mainloop

#pragma vector= USART1RX_VECTOR

__interrupt void usart1_rx (void)

{

_BIC_SR_IRQ( LPM3_bits) ;// Clear LPM3 bits from 0(SR)

t=0;

message=RXBUF1;

checkMes (message); //checks received message

}

#endif

void delay()

{

unsigned int i;

i=10000;

while(i>0)

i–;

}

void blinker () // blinks led

{

while (t==1){

int i=delm;

P1OUT ^=BIT0;

while (i>0) // waits for delay * # of delays

{

i–;

delay();

}

}

}

void checkMes (char m)

{

char c2;

int com;

if ((m & 0x80) == 0x80) //Check if it is command

{

if ((m & 0x10) == 0x10){ //check if it is blink button

t=1;

blinker();}

else

{

c2=(m & 0x07);

delm=c2; // # of delays

}

}

}

Besides this, I got a c# interface. When I press a button, led on board will start blinking. And with the help of a trackbar, I will change delays (blinking speed). The problem is When I press blink button, program is stuck. I can change blinking speed, before I press button. How can I fix it?

Ok, let me see if I’ve understood what you’re doing:

you’ve got a c# program on your PC that communicates trough a serial port to an MSP430 microcontroller that blinks a led. The c# program sends commands to start bilnking and change led speed, is this correct?

Now to the code you posted:

You’re calling blinker() from within checkMes(), which is called from the interrupt routine, right? So the led is blinked from within the interrupt code. That’s bad, for two reasons. First, because interrupt rutines should be short routines thet interrupt the main program flow, and is considered a bad programming tecnique do the opposite. Second, it is bad (and this is why your program is stuck) because by default interrupt nesting is disabled, so you can’t catch an interrupt if you’re already within an interrupt (or a function called within an interrupt, which is always part of the interrupt). Therefore when you push the button the led starts blinking from within the interrupt, and no other interrupt is accepted, so your program is stuck.

You can enable nested interrupt, but sooner or later, all the interrupt that pile up every time you change the blinking speed will likely cause a stack overflow and your application will crash.

Instead do like this:

//Global variables (volatile means something like they can be changed within interrupt, it's long to explain)
volatile unsigned int delm=1; // # of delays
volatile int t=0; // led's not blinking when it is 0
int main()
{
 ...
 int i;//Declare i outside loop
 eint();//Enable interrupt
 for( ; ; )
 {
  while(t==0) LPM3;//go to sleep if nothing to do
  while(t==1)
  {
   i=delm;
   P1OUT ^=BIT0;
   while (i>0) // waits for delay * # of delays
   {
    i--;
    delay();
  }
 }

This way the code that blinks the led is in the main, and the interrupt need only to modify t and delm.

Sorry, I haven’t noticed that you posted the code to the forum in addition to sending me a message. In the message I sent you I also used the word “brightness” instead of “blinking speed” because I was thinking at a similar project that uses PWM to change brigthness