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.

_delay_cycle() repeat problem

Other Parts Discussed in Thread: MSP430G2231

I'm trying to set up a simple code where the red and green LEDs on the launchpad are triggered to flash high for a given length of delay and low for a length of delay.  For example, when Vcc is applied to input pin P1.5, the red LED would come on for some time, then shut down for some time, then the green led would turn on for some time, then shut off.  In the following code, I have found that when the delay is less than a certain range it will seem to repeat the cycle several times.  However, if the delay is longer than that range, it will act as it should only performing the cycle once.  Changing the delay to 100000 will cause the undesired repeating of the if() action, and changing the delay to 200000 will allow it to act normal (albeit slower) only cycling once.  What's going on? I only want it to cycle once, not twice or more as it does with lower delay values.  Thanks for the help/clarification!

#include  <msp430g2231.h>

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
  P1DIR |= 0x01;                            // Set P1.0 to output direction
  P1DIR |= 0x40;                            // Set P6.0 to output direction

for(;;)

  {    
    if (0x20 & P1IN)
    {
      P1OUT |= 0x01;                      
              __delay_cycles(200000);     
      P1OUT &= ~0x01;                      
              __delay_cycles(200000);                    
      P1OUT |= 0x40;                     
              __delay_cycles(200000);       
    }  
    else
    {
      P1OUT &= ~0x01;
      P1OUT &= ~0x40;        
    }                
  }
}



  • Hi Jake,

    is P1.5 maybe floating? Floating pins are often a problem - if your have an active-high pin like above, tie down the pin to ground via a pull-down resistor. This can be done externally or on newer devices with the internal pull-up or pull-down resistors (look at PxREN and PxOUT).

  • Hi!

    Perhaps you want your code to do this? (Remember to change the include).

    #include <msp430g2452.h>

    void main(void)
    {
    WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
    P1DIR |= 0x41; // Set P1.0 and P1.6 to output direction

    for(;;)
    {
    if (0x20 & P1IN) // check P1.5 input
    {
    P1OUT ^= 0x41;
    __delay_cycles(200000);
    }
    else
    P1OUT &= ~0x41;
    }
    }

    I think this is simplified ;) Remember this is NOT low-power.
  • Well, I looked up the PxREN in the family handbook, and tried to implement it in the following revision.  It still seems to behave poorly when the delay value is at 100000 and performs correctly when changed to 200000...

    #include  <msp430g2231.h>

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
      P1DIR |= 0x01;                            // Set P1.0 to output direction
      P1DIR |= 0x40;                            // Set P6.0 to output direction   
      P1REN &= ~0x10;                           
      P1REN &= ~0x20;             
     
      while (1)                               
      {
        if ((0x10 & P1IN))
        {
          P1OUT |= 0x01;                      
                  __delay_cycles(100000);
          P1OUT &= ~0x01;                    
                  __delay_cycles(100000);                     
          P1OUT |= 0x40;                     
                  __delay_cycles(100000);
        }
        else
        {
          P1OUT &= ~0x01;
          P1OUT &= ~0x40;      
        }  
        
        if ((0x20 & P1IN))
        {
          P1OUT |= 0x01;                     
                  __delay_cycles(100000);
          P1OUT &= ~0x01;                     
                  __delay_cycles(100000);       
          P1OUT |= 0x01;                     
                  __delay_cycles(100000);     
          P1OUT &= ~0x01;                       
                  __delay_cycles(100000);                    
          P1OUT |= 0x40;                      
                  __delay_cycles(100000);       
        }  
        else
        {
          P1OUT &= ~0x01;
          P1OUT &= ~0x40;        
        }                
      }
    }


  • Nothing?  There has to be something I'm missing.  Is there some known issue when certain cycles approach a multiple of the clock that are unpredictable such as repeating cycles several times like my case of ~100000 vs 200000?

  • Are you sure those are valid parameter values for __delay_cycles() ... ?

  • No, I'm not sure.  I just thought the parameter input was a manipulation of the core clock to delay cycles.  I'm really just looking for a simple delay to hold a function and delay it from happening.  In this case to blink a light for a certain time in a pattern.  Think Morse code.

  • No, there is nothing wrong about the delay.

    There is a prevision on the PCB to pull-up P1.5. But the pull-up resistor may not be there, or not connected to P1.5. You can also enable the internal resister to pull-up P1.5, but you did not do it correctly.

    Besides, the switch may bounce, and you are not handling that either.

  • Jake Vonderharr said:
    No, I'm not sure

    RTFM time, then!

    Even if it's not the issue here, you really need to be sure that you are using the function correctly!

  • The RTFM comment goes unappreciated...

    I for some reason shut off the PxREN and have since activated on both pins used.  How'd I know to do that?  It's in the manual...

    The symptoms seem to have gone, I believe, Jan, you are correct, and directly it was a 'bouncing' issue.  The faster delay showed it's ugly face, where as the slower delay was able to mask it.

    Thanks for the help guys!

**Attention** This is a public forum