• Join
  • Sign In with my.TI Login
Texas Instruments
  • Products
  • Applications
  • Tools & Software
  • Support & Community
  • Sample & Buy
  • About TI
Sample & Purchase Cart Sample & Purchase Cart
  • Search
  • Advanced
TI E2E™ Community
  • Support Forums
  • Blogs
  • Groups
  • Videos
  • 简体中文
  • More ...
TI Home » TI E2E Community » Support Forums » Microcontrollers » MSP430™ Microcontrollers » MSP430 Ultra-Low Power 16-bit Microcontroller Forum » When to Use "=" VS "|="
Share
MSP430™ Microcontrollers
  • Forum
  • Announcements
  • E2E Wiki
Options
  • Subscribe via RSS
MSP430 Resources
  • MSP430 Product Folder
  • MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit
  • MSP430 Getting Started Guide
  • MSP430 Microcontroller Projects
  • More Resources >
  • Forums

    When to Use "=" VS "|="

    This question is answered
    Donald Varela
    Posted by Donald Varela
    on Aug 10 2012 17:31 PM
    Intellectual260 points

    I am using Code Composer  Version: 5.2.1.00018 and a MSP430G2553 processor.  I did a post called Port 1 Interrupt Problem.  I spent two weeks tracking down a problem and it turned out to be one of these "|".  I put the following:

    P1OUT = LED1;// Set P1.0 to output direction.

    It turns on the LED but it locks up the PORT 1 ISR.

    If I put "P1OUT |= LED1;// Set P1.0 to output direction" it turns on the LED and doesn't lock out Port1 ISR.

    Yes there is a question:

    Does anyone know a reference that explains when to use "=" verses "|="?

    For example the following that sets up a UART

    P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD
    P1SEL2 = BIT1 + BIT2; //
    UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK
    UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600
    UCA0BR1 = 0; // Set upper half of baud select to 0
    UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1
    UCA0CTL1 &= ~UCSWRST; // Start USCI
    IE2 |= UCA0RXIE;

    Why = in some places and |= in others?


    Report Abuse
    • Reply
    You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    All Replies
    • Mark Green
      Posted by Mark Green
      on Aug 10 2012 17:43 PM
      Intellectual640 points

      P1OUT |= LED1;  

      is the same as

      P1OUT = P1OUT  |   LED1;    // put the result of P1OUT OR'ed with LED1 into P1OUT 

      i.e. set some more bits in P1OUT but dont clear any bits that are already set.

      P1OUT = LED1

      i.e. discard or clear what was in P1OUT then only set the bits indicated by LED1.

      Some examples might help:

      #define LED1   0x01  // 00000001 in binary i.e. bit 0 set

      #define LED2   0x02  // 00000010 in binary i.e. bit 1 set

      -

      Example 1:

      P1OUT = LED1;    // overwrite P1OUT with 0x01

      result is  P1OUT contains 0x01 i.e. bit 0 only is set.

      -

      Example 2.

      P1OUT = LED1;   // overwrite P1OUT with 0x01

      P1OUT |= LED2;    // OR in 0x02

      result is P1OUT contains 0x03. bit 0 is set in the first instruction bit 1 is set in the second

      Hope this helps. 

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Donald Varela
      Posted by Donald Varela
      on Aug 10 2012 18:14 PM
      Intellectual260 points

      You are giving me examples of oring bits.

      What is the difference between

      P1OUT = LED1

      and 

      P1OUT |= LED1

      Why does one lock out my Port 1 ISR and the other doesn't?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Norman Wong
      Posted by Norman Wong
      on Aug 10 2012 19:43 PM
      Guru15120 points

      Some guessing as I don't have this platform. From looking at the user guide, I would guess you have a pin on port 1 configured as an input with pull-up. The direction of the pull is determined by P1OUT. Using "P1OUT = LED1" would set bit LED1 but clear other bits. This changes the pull-up to pull-down. Loss of the ISR implied your input signal requires a pull-up to function, ie. open-collector, switch connected to ground.

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 11 2012 05:00 AM
      Guru32055 points

      Donald Varela
      You are giving me examples of oring bits.

      Because that was the question you asked!

      You asked about the |= operator - and that is about ORing bits!

      Donald Varela
      What is the difference between

      P1OUT = LED1

      and 

      P1OUT |= LED1

      That has already been explained to you - which part(s) did you not understand?

      Note that these are entirely standard 'C' operators - there is nothing about them that is specific to the MSP430. See any 'C' textbook for details...

      Donald Varela
      Why does one lock out my Port 1 ISR and the other doesn't?

      Consider what effect each one has on the value in P1OUT, then consider what effect that would have on the port operation - including interrupts...

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Donald Varela
      Posted by Donald Varela
      on Aug 11 2012 15:21 PM
      Intellectual260 points

      Andy I understand what you are saying about the oring of the bits.  One sets a bit and then clears other bits and the other just sets a bit.  My question is why does

      P1OUT = LED1 lock out Port 1 ISR, which are inputs, and

      P1OUT |= LED1 doesn't.  How do I know which one to use at what time?  I am going to post my program.  The program works OK the way it is written.  Put it on a Launchpad with a MSP430G2553 processor and set the UART jumpers to Hardware.  When connected to the terminal type the character "a" without the quotes.  It will respond by printing three "FIRST".  Then ground P1.7.  This is my button.  It responds with "GO".

      In the "Case a" change 

      P1OUT |= LED1 to

      P1OUT = LED1.  Go through the same steps and notice "GO" is not printed because Port 1 doesn't fire.

      The program does other things but they aren't activated following the above procedures.

      Bottom line I'm trying to figure out when to use = VS |=.


      #include <msp430g2553.h>
      ////////////////Defines////////////////
      #define LED1 BIT6
      #define LED0 BIT0
      #define DAT BIT0 //P2.0 //input signal port
      #define BUTTON BIT7
      #define BUTTON_OUT P1OUT
      #define BUTTON_DIR P1DIR
      #define BUTTON_IN P1IN
      #define BUTTON_IE P1IE
      #define BUTTON_IES P1IES
      #define BUTTON_IFG P1IFG
      #define BUTTON_REN P1REN
      char charbuffer[8];
      int i=0;
      int j=0;
      int dis=0;
      int dissave=0;
      float mycount=0;
      unsigned int capture_array[30]; // RAM array for captures
      int tick=0;
      int cap=0;
      float milesper=1.32/5280;
      int pre_cap=0;
      int first_pulse=0;
      int Start=0;
      int Start2 = 0;
      char disbuffer[8];
      volatile unsigned char butdeb[1];

      ////////////////Function Protos////////////////
      void TX(char *tx_message);
      static char *i2a(unsigned i, char *a, unsigned r);
      char *itoa(int i, char *a, int r);


      static char *i2a(unsigned i, char *a, unsigned r)
      {
      if (i/r > 0) a = i2a(i/r,a,r);
      *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r];
      return a+1;
      }

      char *itoa(int i, char *a, int r)
      {
      if ((r < 2) || (r > 36)) r = 10;
      if (i < 0)
      {
      *a = '-';
      *i2a(-(unsigned)i,a+1,r) = 0;
      }
      else *i2a(i,a,r) = 0;
      return a;
      }


      void TX(char *tx_message)
      {
      unsigned int i=0; //Define end of string loop int
      char *message; // message variable
      unsigned int message_num; // define ascii int version variable
      message = tx_message; // move tx_message into message
      while(1)
      {
      if(message[i]==0) // If end of input string is reached, break loop.
      {break;}
      message_num = (int)message[i]; //Cast string char into a int variable
      UCA0TXBUF = message_num; // write INT to TX buffer
      i++; // increase string index
      __delay_cycles(10000); //transmission delay
      if(i>50) //prevent infinite transmit
      {
      P1OUT |= (LED1+LED0);
      break;
      }
      } // End TX Main While Loop
      } // End TX Function
      int main(void)
      { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer

      //setup clock to 1MHZ
      BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz
      DCOCTL = CALDCO_1MHZ;

      ////////////////USCI setup////////////////
      butdeb[0] = 0; // Reset button debounce
      P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD
      P1SEL2 = BIT1 + BIT2; //
      UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK
      UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600
      UCA0BR1 = 0; // Set upper half of baud select to 0
      UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1
      UCA0CTL1 &= ~UCSWRST; // Start USCI
      IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt
      ////////////////General GPIO Defines////////////////

      BUTTON_DIR &= ~BUTTON;
      BUTTON_OUT |= BUTTON;
      BUTTON_REN |= BUTTON;
      BUTTON_IES |= BUTTON;
      BUTTON_IFG &= ~BUTTON;
      BUTTON_IE |= BUTTON;


      P1DIR |= (LED0 + LED1); //define output ports
      P1OUT &= ~(LED0 + LED1); //turn ports low
      P2REN |=(DAT); //enable pullups on respective ports
      P2IE |= DAT;
      P2IFG &= ~DAT;
      P2SEL = DAT;
      /////////////////SETUP TIMER
      TA1CCTL0 = CM_2 + SCS + CCIS_0 + CAP + CCIE; // falling edge + CCI0A (P2.0)// + Capture Mode + Interrupt
      TA1CTL = TASSEL_2 + MC_2; // SMCLK + Continuous Mode
      __enable_interrupt();
      for(;;)
      {
      if (dis!=dissave){
      TX("D");
      itoa(dis, disbuffer,10);
      TX(disbuffer);
      TX("\r\n");
      TX("S");
      itoa(capture_array[5], charbuffer, 10);
      TX(charbuffer);
      TX("\r\n");
      dissave=dis;
      }
      if (Start2==1){
      Start2=0;
      }

      }

      }


      #pragma vector=USCIAB0RX_VECTOR
      __interrupt void USCI0RX_ISR(void)
      {
      unsigned char c;
      c = UCA0RXBUF;
      //SendChar(c);
      //SendChar( '>' );
      switch( c )
      {
      case 'a':
      // This resets all variables
      WDTCTL = WDTPW + WDTHOLD;// Stop watchdog timer
      tick=0;
      cap=0;
      mycount=0.0;
      pre_cap=0;
      first_pulse=0;
      i=0;
      j=0;
      dis=0;
      TX("FIRST");
      TX("\r\n");
      TX("FIRST");
      TX("\r\n");
      TX("FIRST");
      TX("\r\n");
      Start=0;
      BUTTON_IFG &=~BUTTON;
      BUTTON_IE |= BUTTON;
      butdeb[0] = 0; // Reset button debounce
      P1DIR |= 0x01;
      P1OUT |= LED0;// Set P1.0 to output direction
      __delay_cycles(10000);
      break;
      // main();
      }
      }

      // Timer1 interrupt service routine
      #pragma vector=TIMER1_A0_VECTOR
      __interrupt void TIMER1(void)
      {
      dis+=1;
      if (first_pulse==0)
      {
      pre_cap=TA1CCR0;
      first_pulse=1;
      goto here; //break from interrupt service routine
      }
      tick = TA1CCR0;
      cap = tick- pre_cap;
      mycount=cap;
      mycount=mycount/10000000;
      mycount=mycount/3600;
      mycount=milesper/mycount;
      cap=mycount;
      capture_array[i]=cap;
      i++;
      if (i ==10)
      {
      P1OUT^=LED0;//toggle led
      first_pulse=0;
      i=0;
      mycount=0;
      }
      butdeb[0]?butdeb[0]--:1;
      if (!butdeb[0]){
      BUTTON_IFG &=~BUTTON;
      BUTTON_IE |= BUTTON;
      }
      pre_cap = tick; // store this capture value
      here:
      P1OUT^=LED1;
      }

      #pragma vector=PORT1_VECTOR
      __interrupt void P1_ISR(void) {

      if ((BUTTON_IN & BUTTON) && !butdeb[0]) {

      if(Start==0){
      butdeb[0] = 8;
      //start timer
      // TA1CCTL0 |= CM_2;
      // TA1CTL = TASSEL_2 + MC_2; // SMCLK + Continuous Mode
      TX("GO");
      TX("\r\n");
      Start = 1;
      }
      else{
      butdeb[0] = 8;
      TX("HALT");
      TX("\r\n");
      Start = 0;
      }
      }


      }

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 11 2012 16:38 PM
      Verified Answer
      Verified by Donald Varela
      Guru32055 points

      Donald Varela

      My question is why does

      P1OUT = LED1 lock out Port 1 ISR, which are inputs, and

      P1OUT |= LED1 doesn't.

      Again, consider what value each one causes to be written into P1OUT, and then consider what effect each value has.

      You will have to look in the Datasheet to see the effects of writing to P1OUT.

      Donald Varela
      How do I know which one to use at what time?

      You use whichever will give the value that you require!

       

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • old_cow_yellow
      Posted by old_cow_yellow
      on Aug 11 2012 23:58 PM
      Guru26615 points

      I have a very similar problem.

      I have an application program which did not work at all. Finally I realized that if I change the statement: x = y + 5; into x = y - 5 ; then it works fine.

      My question is, why "-" makes it work and "+" makes it not work?  When should I use "+"? When should I use "-"?

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 12 2012 00:33 AM
      Guru32055 points

      Andy Neil
      You will have to look in the Datasheet to see the effects of writing to P1OUT.

      It may also depend on the external circuitry...

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Donald Varela
      Posted by Donald Varela
      on Aug 12 2012 14:14 PM
      Intellectual260 points

      Andy thanks for pointing me in the right direction on the oring.  I did some more research and found this article.  http://www.glitovsky.com/Tutorialv0_3.pdf.  It explain what you were trying to tell me about P1OUT= and P1OUT |=.

      Still not absolutely sure of the details of why it turns the LED on but locks up the PORT 1 ISR function but I understand more about the effects of the = verses |=.  Thanks again!!!

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 12 2012 15:07 PM
      Guru32055 points

      Donald Varela
      Still not absolutely sure of the details of why it turns the LED on but locks up the PORT 1 ISR function

      Think about it: rather than just writing one bit (the one with the LED connected), you are writing  all bits - so you have to consider all the effects of writing all those bits...

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 12 2012 15:09 PM
      Guru32055 points

      Donald Varela
      Andy thanks for pointing me in the right direction on the oring

      Don't forget that it was by Mark Green who explained it to you first

      Credit where it's due
      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Donald Varela
      Posted by Donald Varela
      on Aug 12 2012 15:26 PM
      Intellectual260 points

      I want to thank everyone.  I wrote a previous program using a WDT ISR and could never get it to fire.  Yes I had "P1OUT=" instead of "P1OUT |=".  Went back and changed it and it works perfectly.  Now that I understand oring better I won't make that mistake any more, MAYBE!!!

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    • Andy Neil
      Posted by Andy Neil
      on Aug 12 2012 16:48 PM
      Guru32055 points

      Donald Varela
      Now that I understand oring better...

      Consider where you might need ANDing;

      Consider where you might need XORing...

      Report Abuse
      • Reply
      You have posted to a forum that requires a moderator to approve posts before they are publicly available.
    TI E2E™ Community
    • Support Forums
    • Blogs
    • Videos
    • Groups
    • Site Support & Feedback
    • Settings
    TI E2E™ Community Groups
    • TI University Program
    • Make the Switch
    • Microcontroller Projects
    • Motor Drive & Control
    Other Communities
    • Deyisupport
    • Designsomething.org
    • beagleboard.org
    • TI on Element 14
    • TI on TechXchangeSM
    Other Technical & Support Resources
    • WEBENCH® Design Center
    • Product Information Centers
    • Technical Documents
    • TI Design Network
    • TI Technical Articles
    • TI Training

    All content and materials on this site are provided "as is". TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with regard to these materials, including but not limited to all implied warranties and conditions of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. TI and its respective suppliers and providers of content make no representations about the suitability of these materials for any purpose and disclaim all warranties and conditions with respect to these materials. No license, either express or implied, by estoppel or otherwise, is granted by TI. Use of the information on this site may require a license from a third party, or a license from TI.

    Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI, its suppliers and providers of content reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

    Follow Us Texas Instruments on Facebook Texas Instruments on Twitter Texas Instruments on LinkedIn Texas Instruments on Google+
    TI Worldwide | Contact Us | my.TI Login | Site Map | Corporate Citizenship | mobile m.ti.com (Mobile Version)

    TI is a global semiconductor design and manufacturing company. Innovate with 100,000+ analog ICs and
    embedded processors, along with software, tools and the industry’s largest sales/support staff.

    © Copyright 1995-2013 Texas Instruments Incorporated. All rights reserved.
    Trademarks | Privacy Policy | Terms of Use