• AVR Freaks

Hot!How does this statement work?

Page: 12 > Showing page 1 of 2
Author
momiccioli
New Member
  • Total Posts : 12
  • Reward points : 0
  • Joined: 2019/07/18 06:05:48
  • Location: 0
  • Status: offline
2019/09/23 04:29:58 (permalink)
0

How does this statement work?

Hello,
 
this is a question about how a particular statement works.  I know what the end result is and why it is being done.  It was automatically generated by MCC.  I am learning CPP but this statement is new to me.
 
I have a pic12f1572 and I am using TMR0, my program runs fine no issues.  In the initialize section the OPTION_REG is being set with the following statement.
     OPTION_REG = (uint8_t) ((OPTION_REG & 0xC0) | (0xD0 & 0x3F));
 
The following statement does the exact same thing
     OPTION_REG = 0b01111111;
 
I understand what the OPTION_REG is and what is does.  Just need an explanation of the first statement mechanics.
 
Thanks.
#1

24 Replies Related Threads

    ric
    Super Member
    • Total Posts : 27977
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: How does this statement work? 2019/09/23 04:35:41 (permalink)
    +2 (2)
    Presumably the "0xD0" value is being inserted from somewhere else.
     
    (OPTION_REG & 0xC0) preserves the top two bits of OPTION REG, and zeroes the rest.
    (0xD0 & 0x3F) clears the top two bits of 0xD0, and merges the rest with the previous value of OPTION_REG
    The following statement does the exact same thing
         OPTION_REG = 0b01111111;

    No it doesn't. That statement totally discards the previous value of OPTION_REG.
    The quoted expression preserves bits 6 and 7 from the previous value.
     
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    ric
    Super Member
    • Total Posts : 27977
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: How does this statement work? 2019/09/23 04:40:44 (permalink)
    +1 (1)

    I am learning CPP but this statement is new to me.

    n.b. If it's a PIC12F1572, then the compiler is XC8, which is most certainly NOT a C++ compiler.
    It's plain vanilla C. To be specific, C89 in version 1.xx, or your choice of C90 or C99 in v2.xx.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #3
    JPortici
    Super Member
    • Total Posts : 1114
    • Reward points : 0
    • Joined: 2012/11/17 06:27:45
    • Location: Grappaland
    • Status: offline
    Re: How does this statement work? 2019/09/23 04:51:51 (permalink)
    0
    they do not do the same thing, at all.
    Did you really copy and paste, because in that code there is nothing that sets the lower four bits.
    #4
    1and0
    Access is Denied
    • Total Posts : 10987
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How does this statement work? 2019/09/23 05:42:06 (permalink)
    +2 (2)
    momiccioli
    this is a question about how a particular statement works.  ...  It was automatically generated by MCC. ...
     
         OPTION_REG = (uint8_t) ((OPTION_REG & 0xC0) | (0xD0 & 0x3F));


    Is that really generated by MCC?  Now I've seen everything!
     
    The & is a bit-wise AND operator and the | is a bit-wise OR operator. The cast is used to suppress signed to unsigned conversion warning. Here are the truth tables of the two operators:
     
    A & B = Y        A | B = Y
    ---------        ---------
    0   0   0        0   0   0
    0   1   0        0   1   1
    1   0   0        1   0   1
    1   1   1        1   1   1
    #5
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/23 06:05:02 (permalink)
    0
    Ric,
    Sorry made a typo; The value of OPTION_REG after the first statement is 0101000 this came from the debugger in MPLAB.
     
    So what I meant to say is that OPTION_REG = 0b01010000; accomplishes the same result.
    I agree that statement just blows the values away and totally disregards the current value. 
     
    If the first part of the first statement is a mask which makes sense what does the more bar "|" and the second portion of the equation accomplish?   I tried capturing the data in debugger but does not make sense.  The & is acting as a mask but the more is not making sense.
     
    #6
    1and0
    Access is Denied
    • Total Posts : 10987
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How does this statement work? 2019/09/23 06:39:25 (permalink)
    +2 (2)
    momiccioli
    If the first part of the first statement is a mask which makes sense what does the more bar "|" and the second portion of the equation accomplish?   I tried capturing the data in debugger but does not make sense.  The & is acting as a mask but the more is not making sense.


    Applying the two truth tables shown in my previous post.
     
      abcd efgh
    & 1100 0000
    -----------
      ab00 0000

      1101 0000
    & 0011 1111
    -----------
      0001 0000

      ab00 0000
    | 0001 0000
    -----------
      ab01 0000
     
    So, it keeps the two most significant bits and sets bit 4 of the OPTION register.
    #7
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/23 08:20:14 (permalink)
    0
    OK this is very helpful and I have a better understanding of what is happening.  Dare I ask why it is defaulted this way?  Here is my break down of how OPTION_REG is  initialized.
     
    First half of the statement (OPTION_REG & 0xC0)
       Initial value of OPTION_REG = 0x7F = 0111 1111
                       Mask value of 0xC0 = 1100 0000
    -------------------------------------------------
                Result1 OPTION_REG = 0x40 = 0100 0000
     
    Second half of the statement (0xD0 & 0x3F)
                              0xD0 = 0xD0 = 1101 0000
                          2nd mask = 0x3F = 0011 1111
    -------------------------------------------------
                Result2 OPTION_REG = 0x10 = 0001 0000
     
    Third Result "|"
                Result1 OPTION_REG = 0x40 = 0100 0000
                Result2 OPTION_REG = 0x10 = 0001 0000
    -------------------------------------------------
                  Final OPTION_REG = 0x50 = 0101 0000
     
    The only 2 questions I have are Where did the initial value of 0x7F come from.  Is that a predetermined default?  And where did the 0xD0 come from? I assume possibly something to do with the options I choose in the MCC screens.  My goal of validating the contents of OPTION_REG are accomplished.  But know I will research why it's done this way.
     
    Thanks for the contributions.   
    #8
    1and0
    Access is Denied
    • Total Posts : 10987
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How does this statement work? 2019/09/23 10:38:15 (permalink)
    0
    momiccioli
    ... Dare I ask why it is defaulted this way?  Here is my break down of how OPTION_REG is  initialized.
     
    First half of the statement (OPTION_REG & 0xC0)
       Initial value of OPTION_REG = 0x7F = 0111 1111
     
    The only 2 questions I have are Where did the initial value of 0x7F come from.  Is that a predetermined default?

    According to page 157 of the PIC12F1572 datasheet, the default value of the OPTION_REG register is 0xFF, not 0x7F.
     

    And where did the 0xD0 come from? I assume possibly something to do with the options I choose in the MCC screens. 

    I'd assume so.
    #9
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/23 10:51:21 (permalink)
    0
    I saw that and I think the reason for the 0x7F is because I have WPUEN (bit 7 configured in MCC) disabled.  I would have that would have been set in the same place.  I found that bit set explicitly in the pin_manager.c file which looks to execute first.
         OPTION_REGbits.nWPUEN = 0;
     
     
     
     
     
    #10
    1and0
    Access is Denied
    • Total Posts : 10987
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How does this statement work? 2019/09/23 11:57:10 (permalink)
    +2 (2)
    MCC is a bloated mess. ;)
     
    #11
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/23 12:09:21 (permalink)
    0
    Agreed! good for getting acclimated but you pay for all the files and confusion it creates. What happened to keep it simple.
    #12
    ric
    Super Member
    • Total Posts : 27977
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: How does this statement work? 2019/09/23 13:13:49 (permalink)
    0
    momiccioli
     
    If the first part of the first statement is a mask which makes sense what does the more bar "|" and the second portion of the equation accomplish?

    Where did you get the expression "more bar" ?
    That is the "bitwise OR" operator. Its operation has been discussed in more detail in subsequent posts.
    If you go back and re-read post#2, you'll see it already states what you realised in post#8.

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #13
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/23 14:54:26 (permalink)
    0
    The "more bar" is the character used in piping output in linux/unix expressions.  For instance the command 
       cat testfile.txt | more
     
    The first portion of the command "cat testfile.txt" will display a file to the screen.  If the file has more data than a single screen it will scroll too fast for reading until the end of the file is reached.  By piping the output of the cat command to the more command via the "more bar" or pipe "character" it will pause when the screen is full and wait for the user to press a key to fill the next screen or end of file which ever comes first.  Hence the more bar with us older unix/linux guys. 
     
    And before anybody says it there are ways to do this without piping the output.  It comes down to style and preferences when using the command line.
     
    Yes I realize I came full circle on this.  What was important to me was to understand the mechanics of the statement. Once I learned that it was a compound mask statement and that it took advantage of bit-wise AND and bit-wise OR I was able to understand the statement and it's results. 
     
    While it was overly complicated to me at first I felt it necessary to dissect the statement since I am coding in this environment. 
     
    And very appreciative of the information and help to get me there.
    #14
    nigelwright7557
    Super Member
    • Total Posts : 447
    • Reward points : 0
    • Joined: 2006/11/06 08:15:51
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/24 18:30:42 (permalink)
    0
    Its just a convulated way of setting the option_reg with a value.
    Some programmers go out of their way to make it look as difficult as possible.
    option_reg=0xd0; is the simplest way to do it.
     
     
    #15
    ric
    Super Member
    • Total Posts : 27977
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: offline
    Re: How does this statement work? 2019/09/24 18:42:09 (permalink)
    +1 (1)
    nigelwright7557
    ...
    option_reg=0xd0; is the simplest way to do it.

    As already explained multiple times, that is NOT the same as the original expression.
    i.e. it clobbers the previous values of bits 6 & 7.
     
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #16
    momiccioli
    New Member
    • Total Posts : 12
    • Reward points : 0
    • Joined: 2019/07/18 06:05:48
    • Location: 0
    • Status: offline
    Re: How does this statement work? 2019/09/25 03:57:37 (permalink)
    0
    Agreed on both.  Using the masking is very convoluted especially in this case since the values are being set once. I am sure there is a reason for MCC doing it this way but it does make it more difficult to track down where all the changes occur.  Basically the register is being initialized in two places in two different ways.
     
    It was acknowledged early on, that the assignment statements;
      option_reg=0xd0; and  OPTION_REG = 0b01111111;
    accomplish the same result which is setting the value of the register. Yes, the direct assignments ignore the current value entirely for the new value. Different method same end result.
    #17
    PStechPaul
    Super Member
    • Total Posts : 2812
    • Reward points : 0
    • Joined: 2006/06/27 16:11:32
    • Location: Cockeysville, MD, USA
    • Status: offline
    Re: How does this statement work? 2019/09/25 21:12:17 (permalink)
    +1 (1)
    momiccioli
    It was acknowledged early on, that the assignment statements;
      option_reg=0xd0; and  OPTION_REG = 0b01111111;
    accomplish the same result which is setting the value of the register. Yes, the direct assignments ignore the current value entirely for the new value. Different method same end result.

    This is incorrect, and apparently a typo which you corrected in your post #6.
     
    Usually bit masks use bitwise OR (|) to set bits and bitwise AND (&) to clear bits. To make it clearer, also use the NOT operator (~) to invert bits to be cleared. So assuming the register is originally 0xff,
     
    To clear bits 0, 1, 2, 3, and 5:
     
    OPTION_REG &= (~0b00101111); // value is now 0b11010000

     
    To set bits 1 and 2:
     
    OPTION_REG |= (0b00000110); // value is now 0b11010110

     
    Comments should be used to indicate the function of the bits being set or cleared.

     
    #18
    crosland
    Super Member
    • Total Posts : 2014
    • Reward points : 0
    • Joined: 2005/05/10 10:55:05
    • Location: Warks, UK
    • Status: offline
    Re: How does this statement work? 2019/09/26 06:57:44 (permalink)
    +1 (1)
    nigelwright7557
    Its just a convulated way of setting the option_reg with a value.
    Some programmers go out of their way to make it look as difficult as possible.
    option_reg=0xd0; is the simplest way to do it.

    Some programmers don't understand how things work.
    A simple assignment is the "wrongest" way to do it.
    #19
    1and0
    Access is Denied
    • Total Posts : 10987
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    Re: How does this statement work? 2019/09/26 07:27:45 (permalink)
    +2 (2)
    Here's a convoluted but correct and efficient way to do it ;)
    OPTION_REG ^= (OPTION_REG ^ 
                    ((0 << _OPTION_REG_T0CS_POSN) |
                     (1 << _OPTION_REG_T0SE_POSN) |
                     (0 << _OPTION_REG_PSA_POSN) |
                     (0b000 << _OPTION_REG_PS0_POSN)
                    )
                   ) & 0x3F;
    grin: grinmr green: mr greengrin: grin
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2020 APG vNext Commercial Version 4.5