Jump to content
43oh

Interrupts on the Energia


Recommended Posts

Hi all, 

 

I am having some trouble getting interrupts up and running on the energia,  i have a couple of questions.

 

1 ) I have not been able to find a list of pins on the G2553 that are compatible with interrupts.

 

2) I am using the following code, with a tactile button (pulled up to VCC with a 10k and then pressing it connects it to ground) and it only seems to work with the option "FALLING" in the interrupt declaration "CHANGE" does not work. Any suggestions on what might be going wrong ?

 

void setup()
{
 attachInterrupt(P2_0,blinky,FALLING);
 Serial.begin(9600);
}


void loop()
{
if(flag==1) Serial.println(1);
flag=0;
}


void blinky()
{
  flag=1;
}

 

 

 

Thanks for your help in advance....

Link to post
Share on other sites

Hi Sandbox.

Firstly, does your above code work for FALLING? The reason I ask is that I see a few potential problems with your code.  Firstly, you should explicitly set the pin mode to Input, with the following code:

pinMode(P2_0,INPUT); 

Note that the MSP430 has built in resistors, which you can enable by replacing INPUT with INPUT_PULLUP or INPUT_PULLDOWN - this removes the need for your 10k pull-up resistor.

 

In the code you have pasted, you don't declare your flag variable. Any variable which will be modified by an interrupt should be set "volatile" to force the compiler to load it's value every time it is accessed. Otherwise the compiler may attempt to optimise code and use a cached copy, thus never seeing the changes the interrupt has made. This is done by declaring the variable as follows:

volatile int flag;

Of course if you want it to be a type other than int, for example uint8_t, then replace the int with the desired type.

 

 

You also have a slight logic problem in your loop() function.

void loop()
{
if(flag==1) Serial.println(1);
flag=0;
}

The problem here is that you cannot predict when an interrupt will occur. Because you are resetting the flag to 0 at every pass through the loop, it causes a problem if the interrupt happens to trigger between when it starts testing the "if" and when it resets the flag to 0. If the interrupt happens to trigger during that time it will not be 1 when the "if" is evaluated, so it will not execute the conditional code. Then when it reaches the next line the flag will be changed back to 0, so it will not be 1 for the next pass through the loop. Consequently, your code could miss an interrupt if it happened to trigger during that time. Admittedly it is a very short time, so the odds of this happening are small, but they are real.  Instead, I would change the code as follows:

void loop()
{
  if (flag)
  {
    flag=0;
    Serial.println(1);
   }
}

With this change, it will only reset the flag to 0 if it is already set. This means that it doesn't matter when the interrupt triggers, it will be caught by the loop. By resetting it as the first function inside the conditional section, if another interrupt happens while we are executing the Serial.println code, it will again set the flag and we won't miss it.  You'll also notice I changed the condition in the if clause. Explicitly comparing flag to 1 with (flag==1) requires more code than to just test that it is non-zero as (flag) does.

 

Now, getting onto your interrupt problem.  First the good news - the MSP430G2553 supports interrupts on all of its IO ports (ie, P1_0 to P1_7 and P2_0 to P2_7).  The bad news though is that the MSP430 family doesn't support "CHANGE" as a type of interrupt, only FALLING and RISING.  You can emulate CHANGE in software, by adding the following to the end of your interrupt code.

attachInterrupt(P2_0,blinky,digitalRead(P2_0)?FALLING:RISING);

This will work so long as your interrrupts are coming through relatively slowly.  If you need to catch changing interrupts quickly, then the following has worked for me.


void setup(){
  pinMode(P2_0,INPUT_PULLUP);  //set the pin to input, with pull-up resistor
  attachInterrupt(P2_0,intFunc,FALLING); // and initially set the interrupt for falling.
};

void intFunc(){
  //put the code for your interrupt here

  //the following toggles the interrupt mode.
  P2IES=(P2IES & ~B00000001) | (P2IN & B00000001);
}

void loop(){
}

Note the line that toggles the interrupt mode - this works by directly modifying the Interrupt Edge Select register. This example is hard-coded for P2_0. If you wanted to use a different pin, you would need to change the bitmask, and if the pin was on a different port, you would also need to change P2IES & P2IN. For example to use P1_4, you would use P1IES, P1IN & B00010000 instead.  This code works by first clearing the edge select flag for the specified pin, then it OR's it with the current value of the pin. This means if the pin is currently low, our Edge Select will also be low, meaning the interrupt will trigger on a low to high transition. If the pin is currently high, our Edge Select will also be high, meaning the interrupt will trigger on a high to low transition.  This code allows you to reliably simulate the CHANGE interrupt mode at quite high speeds.  If the pin has already changed before the interrupt finishes it won't trigger a second interrupt, but it will be ready to catch the next transition.  I do recommend if using this with push-buttons that you use hardware debouncing rather than software debouncing. Fortunately, the MSP430G2553 has Schmidt trigger inputs, so hardware debouncing is as simple as putting a small capacitor across the switch - I've found 47nF to work quite reliably.

Link to post
Share on other sites
  • 3 months later...
  • 4 weeks later...

How does one find out things like "CHANGE is not supported"?  I look at http://energia.nu/AttachInterrupt.html and CHANGE is listed.

 

--Mark

 

 

The documentation was incorrect. However, recently I submitted a bugfix that will be in the next Energia release to support "CHANGE" for attatchInterrupt in software. You can find it here:

 

https://github.com/energia/Energia/issues/261

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...