Author Topic: Controlling LED Blink Speed MSP430FR6989  (Read 5030 times)

0 Members and 1 Guest are viewing this topic.

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Controlling LED Blink Speed MSP430FR6989
« on: October 07, 2017, 01:45:01 am »
Code: [Select]
#include <msp430.h>

int button_counter;

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;                   // Disable the GPIO power-on default high-impedance mode
                                            // to activate previously configured port settings

    P1DIR |= BIT0;                          // Set P1.0 to output direction -- LED
    P1DIR &= ~BIT1;                         // Set P1.1 to input
    P1REN |= BIT1;                          // Enable Pull Up Resistor for pin1
    P1OUT |= BIT1;                          //SPECIFIED AS A PULLUP FOR P1.1

    TA0CCTL0 |= CCIE;                        // TACCR0 interrupt enabled
    TA0CCR0 = 3000;                          //Set value of CCR0 for comparison
    TA0CTL |= TASSEL_1 + MC_1;              //Pick TA0CLK & Set Counter to Up Mode
    _BIS_SR(LPM0_bits + GIE);               // Enter LPM0 w/ interrupt


    P1IES |= BIT1;                          //Have flag set on High to Low
    P1IFG &= ~BIT1;                         //Clear Pin 1.1 flag so no immediate interrupt
    P1IE |= BIT1;                           //enable interrupts for Pin 1.1



    for(;;)
    {
        while(!(BIT1 & P1IN))
        {
          button_counter++;
        }
    }


}


#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA0_ISR (void)
{
    P1OUT ^= BIT0;
}

#pragma vector = PORT1_VECTOR
__interrupt void P1dot1_ISR(void)
{
    TA0CCR0 = button_counter;
    P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag
}

I'm tasked (school) with controlling the LED blink rate on the MSP430FR6989. This has to been done using Timer A, and some kind of interrupts. My idea is to have LED1 (P1.0) every 250ms by default. This is done by entering TimerA0_ISR every time TA0R equals TA0CCR0 (which is 3000). At which point it sets XOR's P1.0 with 00000001.

To control the LED blinks, I decided to have a forever loop in main.c, which upon pressing (and holding) of button S1 (Pin 1.1) it increments button_counter. On the falling edge of (ie button release) it enters P1.1_ISR and setings TA0CCR0 to the value of button_counter and resets P1.1 interrupt flag.

This isn't happening though.

My hypothesis are that it is either

1.) TimerA is still running when I went P1.1_ISR and I am immediately being entered into TimerA0_ISR, therefore TA0CCR0 never gets set to button_counter.

2.) Because the buttons are active high, I have something backwards and am never entteirng P1.1_ISR.

I am unsure of #1, its just a guess, because I am so new to this. 
 

Offline Phoenix

  • Frequent Contributor
  • **
  • Posts: 432
  • Country: au
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #1 on: October 07, 2017, 02:52:06 am »
I'm not sure how new you are to this, but you can use the debugger and step through or set break points in the code to see exactly whats happening.
 

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #2 on: October 07, 2017, 03:03:10 am »
im extremely new
 

Offline chicken

  • Frequent Contributor
  • **
  • Posts: 257
  • Country: us
  • Rusty Coder
 
The following users thanked this post: Mattjd

Offline Fred27

  • Supporter
  • ****
  • Posts: 727
  • Country: gb
    • Fred's blog
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #4 on: October 07, 2017, 07:45:30 am »
There are plenty of example that come with MSPWare - including how to use the timers. Start from a working example and adjust it one simple step at a time until it meets your requirements.
 

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #5 on: October 07, 2017, 06:05:19 pm »
I realize this is trivial, but the LED blinks. What happening is that upon release of the button. Nothing happens.

Just tell me, is my implementation even remotely possible? I'm trying to not rely on just copying code. Is there something completely wrong? Am I close at all?
 

Offline Fred27

  • Supporter
  • ****
  • Posts: 727
  • Country: gb
    • Fred's blog
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #6 on: October 07, 2017, 08:20:13 pm »
Set a breakpoint on the ISR to see if it is called. (I'm assuming you're using CCS rather than that Arduino nonsense Energia.)

Bear in mind that buttons bounce like crazy from a microcontroller point of view. It will open and close hundreds of times with each single press or release before it settles down.
 
The following users thanked this post: Mattjd

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #7 on: October 07, 2017, 08:50:07 pm »
Okay. So I hate to read up on breakpoints.

But,

I tried 1 breakpoint in my TimerA0_ISR, while in debugging and resumed, it suspended immediately, so that ISR is working. When I tried a breakpoint for P1dot1_ISR, didn't matter how many times i pressed that button, it never suspended.


edit: to to be clear, I changed my code a little also

Code: [Select]
#include <msp430.h>

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;                   // Disable the GPIO power-on default high-impedance mode
                                            // to activate previously configured port settings

    P1DIR |= BIT0;                          // Set P1.0 to output direction -- LED
    P1DIR &= ~BIT1;                         // Set P1.1 to input
    P1REN |= BIT1;                          // Enable Pull Up Resistor for pin1
    P1OUT |= BIT1;                          //SPECIFIED AS A PULLUP FOR P1.1

    TA0CCTL0 |= CCIE;                        // TACCR0 interrupt enabled
    TA0CCR0 = 3000;                          //Set value of CCR0 for comparison
    TA0CTL |= TASSEL_1 + MC_1;              //Pick TA0CLK & Set Counter to Up Mode
    _enable_interrupt();


    P1IES |= BIT1;                          //Have flag set on High to Low
    P1IE &= ~BIT1;                           //enable interrupts for Pin 1.1
    P1IFG &= ~BIT1;                         //Clear Pin 1.1 flag so no immediate interrupt


    for(;;)
    {
        while(!(BIT1 & P1IN))
        {
            if(TA1R == 0)
            {
                TA1CTL = TASSEL_1 + MC_2;
            }
        }
    }


}


#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA0_ISR (void)
{
    P1OUT ^= BIT0;
}

#pragma vector = PORT1_VECTOR
__interrupt void P1dot1_ISR(void)
{
    TA0CCR0 = TA1R;
    P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag
}

I set a breakpoint for the while(button is pressed) and that caused a suspension when I pressed the button, so that is working.
« Last Edit: October 07, 2017, 08:52:29 pm by Mattjd »
 

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #8 on: October 07, 2017, 08:58:02 pm »
Poo, okay. I had the interrupt for pin 1.1 disabled with this line

P1IE &= ~BIT1;

I changed it to

P1IE |= BIT1;

I set a breakpoint for P1dot1_ISR and upon pressing the button, entered it. This means I have edge select backwards for the flag or I have a debouncing issue.

Edit:

And it was an edge select issue. So I had a mix up with that and how the buttons are active high.
« Last Edit: October 07, 2017, 08:59:53 pm by Mattjd »
 

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #9 on: October 07, 2017, 09:12:32 pm »
 Okay, so since I have gotten that working, thanks to you all.

I have a question, when it comes to setting the vector of  a ISR

Code: [Select]
#pragma vector = PORT1_VECTOR
__interrupt void P1dot1_ISR(void)
{
    TA0CCR0 = button_count;
    P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag
}


I have to use PORT1_VECTOR because I am using port 1 pin 1.  The P1dod1_ISR is my choice and doesnt matter.

What if I want another interrupt but for port 1 pin 2. I'm looking through the datasheet for FR6989 and am having trouble figuring out these vector names. My question is, where would I find them? Looking at the data sheet, the acronym for Port 1 Interrupt Vector is P1IV. Now the msp430.h represents that with PORT1_VECTOR. 
 

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #10 on: October 07, 2017, 09:19:44 pm »
Okay, so since I have gotten that working, thanks to you all.

I have a question, when it comes to setting the vector of  a ISR

Code: [Select]
#pragma vector = PORT1_VECTOR
__interrupt void P1dot1_ISR(void)
{
    TA0CCR0 = button_count;
    P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag
}


I have to use PORT1_VECTOR because I am using port 1 pin 1.  The P1dod1_ISR is my choice and doesnt matter.

What if I want another interrupt but for port 1 pin 2. I'm looking through the datasheet for FR6989 and am having trouble figuring out these vector names. My question is, where would I find them? Looking at the data sheet, the acronym for Port 1 Interrupt Vector is P1IV. Now the msp430.h represents that with PORT1_VECTOR.

To reply to myself. I have to do them in the same ISR, but I have to differentiate them using if statements to check the status of P1IFG for the bits.
 

Online rsjsouza

  • Super Contributor
  • ***
  • Posts: 6013
  • Country: us
  • Eternally curious
    • Vbe - vídeo blog eletrônico
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #11 on: October 07, 2017, 11:41:07 pm »
Just one highlight regarding your original implementation: the article linked by chicken above is extremely relevant - it helps explain why it didn't work originally.
Vbe - vídeo blog eletrônico http://videos.vbeletronico.com

Oh, the "whys" of the datasheets... The information is there not to be an axiomatic truth, but instead each speck of data must be slowly inhaled while carefully performing a deep search inside oneself to find the true metaphysical sense...
 
The following users thanked this post: Mattjd

Offline MattjdTopic starter

  • Regular Contributor
  • *
  • Posts: 230
  • Country: us
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #12 on: October 08, 2017, 01:42:52 am »
Code: [Select]
#include <msp430.h>

volatile unsigned int button_count;

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // stop watchdog timer
    PM5CTL0 &= ~LOCKLPM5;                   // Disable the GPIO power-on default high-impedance mode
                                            // to activate previously configured port settings

    P1DIR |= BIT0;                          // Set P1.0 to output direction -- LED

    P1DIR &= ~BIT1;                         // Set P1.1 to button input
    P1REN |= BIT1;                          // Enable Pull Up Resistor for pin1.1
    P1OUT |= BIT1;                          //SPECIFIED AS A PULLUP FOR P1.1

    P1DIR &= ~BIT2;                         // Set P1.2 to button input
    P1REN |= BIT2;                          // Enable Pull Up Resistor for pin1.2
    P1OUT |= BIT2;                          //SPECIFIED AS A PULLUP FOR P1.2

    TA0CCTL0 |= CCIE;                        // TACCR0 interrupt enabled
    TA0CCR0 = 3277;                          //Set value of TA0CCR0 for comparison
    TA0CTL |= TASSEL_1 + MC_1;              //Pick ACLK & Set Counter to Up Mode
    TA0CTL |= TACLR;

    TA1CCR1 = 512;                         //Set value of TA1CCR0 for comparison

    P1IES |= BIT1;                          //Have flag set on High to Low
    P1IE |= BIT1;                           //enable interrupts for Pin 1.1
    P1IFG &= ~BIT1;                         //Clear Pin 1.1 flag so no immediate interrupt

    P1IES |= BIT2;                          //Have flag set on High to Low
    P1IE |= BIT2;                           //enable interrupts for Pin 1.1
    P1IFG &= ~BIT2;                         //Clear Pin 1.1 flag so no immediate interrupt

    _enable_interrupt();

}


#pragma vector = TIMER0_A0_VECTOR
__interrupt void TimerA0_ISR (void)
{
    P1OUT ^= BIT0;
}

#pragma vector = PORT1_VECTOR
__interrupt void P1dot1_ISR(void)
{
    if(P1IFG & BIT1)
    {
        if(TA1R > 0)
        {
            TA0CCR0 = 3277*button_count;          //slow down blink speed
            P1IES ^= BIT1;                        //Flip Edge Select
            P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag

        }
        else
        {
            TA1CTL |= TASSEL_1 + MC_1 + ID_3;      //Pick ACLK & Set Counter to Up Mode & Divide ACLK by 8, so 4096
            TA1EX0 |= TAIDEX_7;                    //Divide ACLK further by 8 to 512 hz
            TA1CTL |= TACLR;
            P1IES ^= BIT1;                        //Flip Edge Select
            P1IFG &= ~BIT1;                       //Clear Pin 1.1 flag
        }
    }
    if(P1IFG & BIT2)
    {
        TA0CCR0 = 3277;                       //reset blink speed
        P1IFG &= ~BIT2;                       //Clear Pin 1.2 flag
    }
}

So, when I enter P1dot1_ISR, I want to start a clock and flip the edge select of port 1.1

None of these are changing. I am setting a break point and viewing the registers. P1ES1 is still set to 1, despite me XOR'ing P1IES with BIT1. Timer A1 is not starting either.

What I am trying to do is, upon pressing (and holding) of p1.1 (button s1), I enter p1.1_ISR, start timer A1. I then flip the edge select of P1.1. When I release the button, because I switched the edge select, I should re-enter the ISR and change the value of CCR0 to some multiple of its old self (basically for every second I hold down the button, the integer I multiply CCR0 by is increased by 1)
 

Offline Cervisia

  • Regular Contributor
  • *
  • Posts: 83
  • Country: 00
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #13 on: October 08, 2017, 08:39:32 am »
Quote
I have to use PORT1_VECTOR because I am using port 1 pin 1.

What if I want another interrupt but for port 1 pin 2.

PORT1_VECTOR is for all pins of port 1. To find out which pin triggered the interrupt, you could check all IFG bits, but it would be easier to use the vector register:
Code: [Select]
#pragma vector = PORT1_VECTOR
__interrupt void P1_ISR(void)
{
    switch (P1IV) {  // this read also clears the corresponding P1IFG bit
    case P1IV_P1IFG1:
        ...
        break;
    case P1IV_P1IFG2:
        ...
        break;
    }
}
 

Online rsjsouza

  • Super Contributor
  • ***
  • Posts: 6013
  • Country: us
  • Eternally curious
    • Vbe - vídeo blog eletrônico
Re: Controlling LED Blink Speed MSP430FR6989
« Reply #14 on: October 08, 2017, 11:38:47 am »
Code: [Select]
    (...)
    P1IES |= BIT1;                          //Have flag set on High to Low
    P1IE |= BIT1;                           //enable interrupts for Pin 1.1
    P1IFG &= ~BIT1;                         //Clear Pin 1.1 flag so no immediate interrupt

    P1IES |= BIT2;                          //Have flag set on High to Low
    P1IE |= BIT2;                           //enable interrupts for Pin 1.1
    P1IFG &= ~BIT2;                         //Clear Pin 1.1 flag so no immediate interrupt

    _enable_interrupt();

}

Where is your while(1) or for(;;) at the end of main()?
Vbe - vídeo blog eletrônico http://videos.vbeletronico.com

Oh, the "whys" of the datasheets... The information is there not to be an axiomatic truth, but instead each speck of data must be slowly inhaled while carefully performing a deep search inside oneself to find the true metaphysical sense...
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf