Bitwise operations and masks: basics, help?


Closed Thread
Results 1 to 12 of 12
  1. #1
    xnihilo's Avatar
    xnihilo Guest

    Smile Bitwise operations and masks: basics, help?

    Hi,

    I know there are the bitwise operators to work at bit level. I'm not familiar with these and logic was never my strong point. That's why I would need some help here.

    I'm using a 7 segments led display (plus a dot, which makes 8 leds, and two ground pins, for a total of 10 pins).
    Each segment is a led. The 7 sements (plus the dot led) have common cathode.
    Each led anode is connected to a pin of a PIC16F684. So to turn on a segment, I just need to output 5V on the appropriate pin. To display a digit, I just have to turn on the appropriate pins/segments/leds.

    I'm using RC4 to RC0 for 5 of the 7 segments (segments a to e) and RA1 to RA2 for the 2 last segments (f, g) (while the "dp" dot is on RA0).

    I have to set the appropriate pins to display the adequate segments to display a digit.
    For example, to display digit "0", I need to turn on the pins that will light the segments a, b, c,d, d, e, f, thus, for my design, the pins RC4 to RC0 and RA1. (a little complicated, yes).
    Anyway, I have to set portA and portC to:


    porta: xxxx10x, portc: x11111

    where the "x" represent bits that must not be changed.

    How can I replace the needed bits without changing the "x" bits?

    I guess I should use bits mask but what is the magic?

    Thanks for any help here.

    Regards.

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    when you want to clear a bit you use AND, set a bit OR

    portc: x11111

    PORTC=PORTC | %00011111

    <hr>
    porta: xxxx10x,

    for this one you may also do it simple..
    TempVar=PORTA
    TempVar.1=0
    TempVar.2=1
    PORTA=TempVar

    OR, in some case, the following will work without much problem
    PORTA.1=0
    PORTA.2=1

    HTH
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by mister_e View Post
    when you want to clear a bit you use AND, set a bit OR

    portc: x11111

    PORTC=PORTC | %00011111

    <hr>
    porta: xxxx10x,

    for this one you may also do it simple..
    TempVar=PORTA
    TempVar.1=0
    TempVar.2=1
    PORTA=TempVar

    OR, in some case, the following will work without much problem
    PORTA.1=0
    PORTA.2=1

    HTH
    Hello,

    Simple?
    Not so simple because each digit on the 7segments display needs (in my design) a pair of bytes for porta and portc that are found in a 10 entries array, and I prefer not to use intermediate variable.
    Sorry but I didn't understand your example above:

    portc: x11111
    PORTC=PORTC | %00011111
    porta: xxxx10x,



    let's say porta value is %00011001 and I need to alter only bits 1 and 2 with the following pattern stored in a BYTE varible called "avar":
    variable avar value is %-----10-

    ???

    Can I isolate a chunk of a byte and insert it at a desired position in anoter byte?
    Last edited by xnihilo; - 18th April 2008 at 15:43.

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Yes i see some different ways, just paste your pattern here and where to send them, i'll give you something to think about.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile Bits replacement

    Example:

    The bits I need to set to display the "0" digit on the 7 segments display are:

    on porta: %***01* , all other bits are left untouched
    on portc: %*11111 , bit 5 is left untouched.

    I have two arrays of bytes:
    cval VAR BYTE[10] and aval VAR BYTE[10], each index represents a duet of bytes containing the bits configuration to display a digit.
    arrays index 0 for digit "0",... up to digit "9" in index 9.

    I only need to 'insert' chunks of bits in porta and portc registers.


    For a given array index (representing the 7 bits to make a digit):
    For porta I will need to replace bits 1 and 2 from porta by bits 1 and 2 from aval variable.
    For portc I will need to replace bits 4 to 0 from portc by bits 4 to 0 from cval variable

    is this clear ???

  6. #6
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Why not a WORD array instead? Anyways, yes it's clear enough. I'll do something a little bit later.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  7. #7
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Quote Originally Posted by mister_e View Post
    Why not a WORD array instead? Anyways, yes it's clear enough. I'll do something a little bit later.
    Yes, I may use a WORD array instead... Anyway, it wont be much different I guess. The principle of bit manipulations will remain the same I beleive...

    Anyway, thank you very much for your help.

  8. #8
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Code:
            '
            '   Tested on 16F877
            '   ----------------
    @       __CONFIG _XT_OSC & _LVP_OFF & _WDT_OFF
    
            TRISA=0
            TRISB=0
            TRISC=0
            TRISD=0
            
            
            Aval VAR byte [10]
            Cval VAR BYTE [10]
            CounterA VAR BYTE
            CounterB VAR BYTE
            
            PORTA=0
            PORTB=0
            PORTC=0
            PORTD=0
            ADCON1=7
            
            AVAL[0]=%00000000
            AVAL[1]=%00000010
            AVAL[2]=%00000100
            AVAL[3]=%00001010
            AVAL[4]=%00010000
            AVAL[5]=%00100010
            AVAL[6]=%01000100
            AVAL[7]=%10000010
            AVAL[8]=%10101001
            AVAL[9]=%11111111
    
            CVAL[0]=%00000000
            Cval[1]=%00000001
            CVAL[2]=%00000010
            CVAL[3]=%00000100
            CVAL[4]=%00001000
            CVAL[5]=%00010000
            CVAL[6]=%00101000
            CVAL[7]=%01000100
            CVAL[8]=%10000010
            CVAL[9]=%11100001
    
    Start:
            for CounterB = 0 to 255
                PORTA=CounterB
                PORTB=COUNTERB
                PORTC=CounterB
                PORTD=COUNTERB
                fOR CounterA = 0 TO 9
                    '
                    '   this should be the section you need
                    PORTA = (PORTA & %11111001) | (AVAL[COUNTERA] & %00000110)
                    PORTC = (PORTC & %11100000) | (CvAL[CounterA] & %00011111)
                    '
                    '
                    PAUSE 250
                    NEXT        
                NEXT
            STOP
    PS: As you only use 7 bit... you could also us ONLY 1 byte array instead of 2.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  9. #9


    Did you find this post helpful? Yes | No

    Default

    What I would do is:
    Code:
    PORTC = PORTC & %11100000   / Clear all the bits in PORTC that are segments
    PORTC = AVAL[x] | PORTC        / sets the bits in PORTC that are '1' in AVAL[x]
    
    PORTA = PORTA & %11111001  /  Clear all the bits in PORTA that are segments
    PORTA = CVAL[x] | PORTA       / sets the bits in PORTA that are '1' in CVAL[x]
    if you just want to use one matrix for segment data you can do this:
    Code:
    ORMASK = SEGVAL[x] & %00011111 / makes sure only 5 lsb of SEGVAL[x] '1' bits get set below
    PORTC = PORTC & %11100000    / Clear all the bits in PORTC that are segments 
    PORTC = ORMASK | PORTC         / sets the bits in PORTC that are '1' in AVAL[x]
    
    ORMASK = SEGVAL[x] >> 4         / shift data 4 to right to position correct SEGVAL[x] bits for PORTA
    ORMASK = ORMASK & %0000110 / makes sure only 2 bits of SEGVAL[x] '1' bits get set below
    PORTA = PORTA | %11111001    / Clear all the bits in PORTA that are segments
    PORTA = ORMASK | PORTA        / sets the bits in PORTC that are '1' in AVAL[x]
    Last edited by falingtrea; - 18th April 2008 at 20:52. Reason: fixed logic
    Tim Barr

  10. #10
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Yup, mine is just in case something is badly define in the array, unless

    PORTA = (PORTA & %11111001) | AVAL[COUNTERA]
    PORTC = (PORTC & %11100000) | CvAL[CounterA]

    Would work anyways.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  11. #11
    xnihilo's Avatar
    xnihilo Guest


    Did you find this post helpful? Yes | No

    Smile

    Hello,

    Thank you for this information.
    Bitwise operations are less simple than I thought but are necessary

  12. #12
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Nah not that complicated.. but once you get them they're pretty handy.
    http://en.wikipedia.org/wiki/Bitwise_operation
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts