This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430FR5994: Trying to integrate 7 Segment display

Part Number: MSP430FR5994

Tool/software: Code Composer Studio

Hi, 

I am trying to use a common cathode 7 segment display with FR5994 launchpad to implement HEX display counter based on the pushbutton toggle. I feel all declarations are done properly but, it's not coming up.

Need your guidance/help please to help me figure out wrong/additional things.

Using P3.0 to P3.7 for display bits.

Using P5.6 for pushbutton [onboard] 

The main.c file is attached below.

Thanks.

#include <msp430.h>

#define SW      BIT6                    // Switch -> P5.6

// Define Pin Mapping of 7-segment Display
// Segments are connected to P1.0 - P1.7
#define SEG_A   BIT0
#define SEG_B   BIT1
#define SEG_C   BIT2
#define SEG_D   BIT3
#define SEG_E   BIT4
#define SEG_F   BIT5
#define SEG_G   BIT6
#define SEG_DP  BIT7

// Define each digit according to truth table
#define D0  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F)
#define D1  (SEG_B + SEG_C)
#define D2  (SEG_A + SEG_B + SEG_D + SEG_E + SEG_G)
#define D3  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_G)
#define D4  (SEG_B + SEG_C + SEG_F + SEG_G)
#define D5  (SEG_A + SEG_C + SEG_D + SEG_F + SEG_G)
#define D6  (SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
#define D7  (SEG_A + SEG_B + SEG_C)
#define D8  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
#define D9  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G)
#define DA  (SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G)
#define DB  (SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
#define DC  (SEG_A + SEG_D + SEG_E + SEG_F)
#define DD  (SEG_B + SEG_C + SEG_D + SEG_E + SEG_G)
#define DE  (SEG_A + SEG_D + SEG_E + SEG_F + SEG_G)
#define DF  (SEG_A + SEG_E + SEG_F + SEG_G)


// Define mask value for all digit segments except DP
#define DMASK   ~(SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)

// Store digits in array for display
const unsigned int digits[16] = {D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, DA, DB, DC, DD, DE, DF};

volatile unsigned int i = 0;

/*@brief entry point for the code*/
void main(void) {
    WDTCTL = WDTPW | WDTHOLD;           //! Stop Watch dog (Not recommended for code in production and devices working in field)

    // Initialize 7-segment pins as Output
    P3DIR |= (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E+ SEG_F + SEG_G + SEG_DP);

    P5DIR &= ~SW;                       // Set SW pin -> Input

    while(1)
    {
        if(!(P5IN & SW))                // If SW is Pressed
        {
            __delay_cycles(20000);      //Delay to avoid Switch Bounce
            while(!(P5IN & SW));        // Wait till SW Released
            i++;                        //Increment count
            if(i>15)
            {
                i=0;
            }
        }
        P3OUT = (P3OUT & DMASK) + digits[i];    // Display current digit
    }
}

  • Hi Navadeep,

    Does your code register the pushbutton input and get to line 58? Does your pushbutton have a pullup resistor and is it active low in hardware?

  • On some MSP430's the GPIOs are locked after reset and until you clear LOCKLPM5. I believe this is one of them.

  • Hi David,

    Yes you are right, please include this line in your code after initializing P3 and P5:

    PM5CTL0 &= ~LOCKLPM5;

  • Yes, the pushbutton is directly connected to ground and no pullup is present in hardware.

  • Hi,

    That seems right. MSP430FR5994 stays in low power mode with GPIOs deactivated until they are told to activate.

    So, I added PM5CTL0 &= ~LOCKLPM5;  just before while(1) [line 50 now] and all GPIOs got activated showing up big "8." in seven segment.

    Is this the issue with pushbutton mode ?

    Counter isn't accessed and pushbutton doesn't respond keeping all GPIOs activeted everytime.

  • Hi Navadeep,

    You'll want to enable the pullup resistor and set it using these two lines of code:

    P5REN |= SW;
    P5OUT |= SW;

    I don't think you need the if(!(P5IN & SW)), it can be kept as if(!(SW)). Also when debouncing the switch, I would use a second "if" statement rather than a while so you don't increment through the 7-seg LEDs quickly. A delay can be introduced between outputting the outputs as needed.

    I attached the updated code below, let me know how it works.

    #include <msp430.h>

    #define SW BIT6 // Switch -> P5.6

    // Define Pin Mapping of 7-segment Display
    // Segments are connected to P1.0 - P1.7
    #define SEG_A BIT0
    #define SEG_B BIT1
    #define SEG_C BIT2
    #define SEG_D BIT3
    #define SEG_E BIT4
    #define SEG_F BIT5
    #define SEG_G BIT6
    #define SEG_DP BIT7

    // Define each digit according to truth table
    #define D0 (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F)
    #define D1 (SEG_B + SEG_C)
    #define D2 (SEG_A + SEG_B + SEG_D + SEG_E + SEG_G)
    #define D3 (SEG_A + SEG_B + SEG_C + SEG_D + SEG_G)
    #define D4 (SEG_B + SEG_C + SEG_F + SEG_G)
    #define D5 (SEG_A + SEG_C + SEG_D + SEG_F + SEG_G)
    #define D6 (SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define D7 (SEG_A + SEG_B + SEG_C)
    #define D8 (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define D9 (SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G)
    #define DA (SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G)
    #define DB (SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define DC (SEG_A + SEG_D + SEG_E + SEG_F)
    #define DD (SEG_B + SEG_C + SEG_D + SEG_E + SEG_G)
    #define DE (SEG_A + SEG_D + SEG_E + SEG_F + SEG_G)
    #define DF (SEG_A + SEG_E + SEG_F + SEG_G)


    // Define mask value for all digit segments except DP
    #define DMASK ~(SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)

    // Store digits in array for display
    const unsigned int digits[16] = {D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, DA, DB, DC, DD, DE, DF};

    volatile unsigned int i = 0;

    /*@brief entry point for the code*/
    void main(void) {
    WDTCTL = WDTPW | WDTHOLD; //! Stop Watch dog (Not recommended for code in production and devices working in field)

    // Initialize 7-segment pins as Output
    P3DIR |= (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E+ SEG_F + SEG_G + SEG_DP);
    P5REN |= SW;
    P5OUT |= SW;
    P5DIR &= ~SW; // Set SW pin -> Input

    while(1)
    {
    if(!(SW)) // If SW is Pressed
    {
    __delay_cycles(20000); //Delay to avoid Switch Bounce
    if(!(SW)); // Wait till SW Released
    i++; //Increment count
    if(i>15)
    {
    i=0;
    }
    }
    P3OUT = (P3OUT & DMASK) + digits[i]; // Display current digit
    }
    }

  • Hi,

    This didn't work straight forward and tried some alternative ways to fix and ended up with same result having 0 written in 7-Segment.  *my bad skills :(

    [PM5CTL0 &= ~LOCKLPM5;  should be added to enable GPIOs in the above code]

    I suspect, the pushbutton itself isn't getting functional. i.e, counter loop isn't showing increment.

    Thanks. I appreciate some advise/support.

  • Hi Navadeep,

    I forgot to include that line in the code above (PM5CTL0 &= ~LOCKLPM5;)

    I've attached some resources for pushbutton and 7-seg display:

    Pushbutton:

    https://e2e.ti.com/support/microcontrollers/msp430/f/166/t/438994?MSP430F5529-Using-the-Push-Button-P1-1

    7-Seg Display:

    https://www.xanthium.in/interfacing-7-segment-led-with-msp430-launchpad

    https://embeddedprojecthunter.wordpress.com/2015/08/28/control-seven-segment-display-with-msp430g2553/

    e2e.ti.com/.../279004

    Let me know if you still need help to get the push button to increment, make sure that you can get past the   if(!(P5IN & SW))   line of code. 

  • Thank you very much. I will go through those.

  • Hi, 

    After going through the device specific datasheet and above resources, the issue got resolved.

    Key Takeaway-

     if(!(P5IN & SW))                                   // If SW is Pressed
            {
                __delay_cycles(20000);            //Avoid Switch Bounce with a delay
                while(!(P5IN & SW))                 // Wait till SW Released
                i++;                                           //Increment count
                if(i>15)
                {
                    i=0;
                }
            }
            P3OUT = (P3OUT & DMASK) + digits[i];    // Display current digit
        }

    In the above, the count was not incrementing since it was waiting till the pushbutton is released and every time it was reaching count '0'. The display is done after ending the loop which always read 0.

    Since wait till release wasn't needed, I removed it and put the display inside the loop to show it instantaneously as it counts. Later constraint to reset to '0' is added if the increment is above 15.

    This is after fixing.

              if(!(P5IN & SW)) // If SW is Pressd
    
               {
    
                __delay_cycles(250000);                              //Avoid Switch Bounce with a delay
                P3OUT = (P3OUT & DMASK) + digits[i];       // Display current digit
                i++;                                                               //Increment count
                if(i>15)
                {
                    i=0;
                }
            }

    I have attached the full working code below for reference and threads future purposes.

    Thanks ;]

    #include <msp430.h>
    
    #define SW      BIT6     // Switch -> P5.6
    
    // Define Pin Mapping of 7-segment Display
    // Segments are connected to P1.0 - P1.7
    #define SEG_A   BIT0
    #define SEG_B   BIT1
    #define SEG_C   BIT2
    #define SEG_D   BIT3
    #define SEG_E   BIT4
    #define SEG_F   BIT5
    #define SEG_G   BIT6
    #define SEG_DP  BIT7
    
    // Define each digit according to truth table
    #define D0  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F)
    #define D1  (SEG_B + SEG_C)
    #define D2  (SEG_A + SEG_B + SEG_D + SEG_E + SEG_G)
    #define D3  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_G)
    #define D4  (SEG_B + SEG_C + SEG_F + SEG_G)
    #define D5  (SEG_A + SEG_C + SEG_D + SEG_F + SEG_G)
    #define D6  (SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define D7  (SEG_A + SEG_B + SEG_C)
    #define D8  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define D9  (SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G)
    #define DA  (SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G)
    #define DB  (SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    #define DC  (SEG_A + SEG_D + SEG_E + SEG_F)
    #define DD  (SEG_B + SEG_C + SEG_D + SEG_E + SEG_G)
    #define DE  (SEG_A + SEG_D + SEG_E + SEG_F + SEG_G)
    #define DF  (SEG_A + SEG_E + SEG_F + SEG_G)
    
    
    // Define mask value for all digit segments except DP
    #define DMASK   ~(SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G)
    
    // Store digits in array for display
    const unsigned int digits[16] = {D0, D1, D2, D3, D4, D5, D6, D7, D8, D9, DA, DB, DC, DD, DE, DF};
    
    volatile unsigned int i = 0;
    
    /*@brief entry point for the code*/
    void main(void) {
            WDTCTL = WDTPW | WDTHOLD;           //! Stop Watch dog
    
        // Initialize 7-segment pins as Output
        P3DIR |= (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E+ SEG_F + SEG_G + SEG_DP);
        P5DIR &= ~SW;                 // Set SW pin for Input
        P5REN |= SW;
        P5OUT |= SW;
    
        PM5CTL0 &= ~LOCKLPM5;        //Come out of Low Power Mode and activate GPIOs
        while(1)
        {
            if(!(P5IN & SW))                          // If SW is Pressed
            {
                __delay_cycles(250000);               //Avoid Switch Bounce with a delay
                P3OUT = (P3OUT & DMASK) + digits[i];  // Display current digit
                i++;                                  //Increment count
                if(i>15)
                {
                    i=0;
                }
            }
        }
    }
    

**Attention** This is a public forum