Masking address bits


Closed Thread
Results 1 to 13 of 13
  1. #1
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597

    Default Masking address bits

    Hi,

    Can someone explain how masking works please?

    I've seen Mr. E use it a lot in his code, but he likes using HEX which makes it a 'bit' more foreign to me. I'd appreciate an example using binary masking if at all possible, that way I'll be able to have maximum control over data.

    The application I have right now is how to control bits within the address byte (A0, A1 and A2). I have 7 MCP23016 I/O expanders and I'd like to poll them in a loop.

    Thanks!

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    It turns out PIC BASIC calls this isolating bits, not masking. I found instructions for that on p.37 of my manual:

    B0 = B0 & %00000001 ' Isolate bit 0 of B0

    This brings up another question, is it possible to concatenate bits? Like this:

    A0 = (B0 & %00000111) SomeBitCommand (C0 & %11111000)

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  3. #3
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    D'uh, nevermind, I found the answer to that also.

    Just shift the 2nd value over by the proper number of digits and then add both together.

    (don't mind me, I'm talking to myself - god I hate finding the answer a few minutes after giving up and posting)

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

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


    Did you find this post helpful? Yes | No

    Default

    Dear Sir De La Demon

    Everything is based on logical operation. you can use Decimal, Hex or binary... use the one you're confortable with

    Boolean operation, short tutorial and truth table

    Short example:


    I have 4 push buttons attach to PORTB<3:0> (<3:0> mean on PORTB.0, PORTB.1, PORTB.2 AND PORTB.3) the other PORTB pins ae used for something else.

    I want to read the status of those pushbutton and discard the other pins. In this case you have two choice. Read every single bit OR read the whole PORT and keep only PORTB<3:0>. I prefer the last one.

    To keep only the 4 lower bits you can use bitwise AND
    Code:
    PushButton=PORTB & $0F
    OR
    Code:
    PushButton=PORTB & 15
    OR
    Code:
    PushButton=PORTB & %00001111
    OR bitwise OR
    Code:
    PushButton=PORTB | $F0
    OR
    Code:
    PushButton=PORTB | 240
    OR
    Code:
    PushButton=PORTB | %11110000
    Depending of your pushButton 'normal state' you'll read the result as follow. In my case 'normal state=0'
    Code:
    	'
    	' Reading PushButtons on PORTB
    	' Using AND
    	'
    start:
    PushButton=PORTB & $0F ' or PORTB & %00001111
    	'
    	' Using select case to handle pushbutton and
    	' jump to specific Subroutines
    	'
    Select case PushButton
    	case 1 ' %00000001 or $1
    		Gosub PORTB_0
    	case 2 ' %00000010 or $2
    		Gosub PORTB_1
    	case 4 ' %00000100 or $4
    		Gosub PORTB_2
    	case 8 ' %00001000 or $8
    		Gosub PORTB_3
    	end select
    You can even use bitwise OR and change the results...
    Code:
    	'
    	' Reading PushButtons on PORTB
    	' Using AND
    	'
    start:
    PushButton=PORTB | $F0 ' or PORTB | %11110000
    	'
    	' Using select case to handle pushbutton and
    	' jump to specific Subroutines
    	'
    Select case PushButton
    	case 241 ' %11110001 or $F1
    		Gosub PORTB_0
    	case 242 ' %11110010 or $F2
    		Gosub PORTB_1
    	case 244 ' %11110100 or $F4
    		Gosub PORTB_2
    	case 248 ' %11111000 or $F8
    		Gosub PORTB_3
    	end select
    Now let's say that i want to turn off a led on a specific PORTB pin.
    Code:
    LedOnPORTB var byte
    
    LedOnPORTB=%11001111
    PORTB=LedOnPORTB
        '
        ' Let's turn off the LED on PORTB.7
        '
    LedOnPORTB=LedOnPORTB %01111111
    PORTB=LedOnPORTB
    that's just an example, read and understand the boolean operator, you'll find them handy... even if you just want to toglle a bit state..
    Code:
    PORTB=%11110001
    
    start:
        PORTB.0=PORTB.0 ^ 1
        pause 500
        goto start
    this will blink led on PORTB.0

    HTH


    EDIT: DOH! just notice you found something... BAH, this could be handy for somebody here.. one day or another... i guess.

    Quote Originally Posted by VieilleChose
    The application I have right now is how to control bits within the address byte (A0, A1 and A2). I have 7 MCP23016 I/O expanders and I'd like to poll them in a loop.
    You can even use an array to store their specific control byte then use it in a loop
    Code:
    IOExpander var byte[7]
    IOExpander[0]=%11110000
    IOExpander[1]=%11110001
    IOExpander[2]=%11110010
    IOExpander[3]=%11110011
    IOExpander[4]=%11110100
    IOExpander[5]=%11110101
    IOExpander[6]=%11110110
    
    For Loop = 0 to 6
        I2cWRITE blah,blah2,IoExpander[Loop],[SteakBledindePatate]
        pause 5
        next
    Last edited by Demon; - 4th October 2016 at 18:06.
    Steve

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

  5. #5
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    mister_e, I don't think the statement:
    I2cWRITE blah,blah2,IoExpander[Loop],[SteakBledindePatate] will work as the variable "IoExpander" is not a constant but rather an array. I have tried using this syntax in the past with no success.

    Dave Purola,
    N8NTA

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


    Did you find this post helpful? Yes | No

    Default

    mmm, interesting, never tried it before... Thanks Dave!

    Anybody else tried that before and got bad results with this ?

    anyways, here's an easy workaround.

    Code:
    IOExpander var byte[7]
    WichIOExpander var byte
    IOExpander[0]=%11110000
    IOExpander[1]=%11110001
    IOExpander[2]=%11110010
    IOExpander[3]=%11110011
    IOExpander[4]=%11110100
    IOExpander[5]=%11110101
    IOExpander[6]=%11110110
    
    For Loop = 0 to 6
        WichIOExpander=IoExpander[Loop]
        I2cWRITE blah,blah2,WichIOExpander,[SteakBledindePatate]
        pause 5
        next
    OR
    Code:
    IOExpander=%11110110
    
    For Loop = 0 to 6
        I2cWRITE blah,blah2,(IOExpander+Loop),[SteakBledindePatate]
        pause 5
        next
    And if it doesn't work..
    Code:
    WichIOExpander var byte
    IOExpander=%11110110
    
    For Loop = 0 to 6
        WichIOExpander=IOExpander+Loop
        I2cWRITE blah,blah2,WichIOExpander,[SteakBledindePatate]
        pause 5
        next
    Sorry, i can't check any of the above where i am right now.
    Last edited by mister_e; - 18th November 2005 at 07:25.
    Steve

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

  7. #7
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    mister_e, That is the exact work around I tried in the past with no success. It is still using a variable instead of a constant. I do wish any upcomming versions of PBP will fix this problem. I have 6 PCF8574's that I have addressed in succession and thought I would use 1 address and then just offset it in a formula to access the others. The problem is it only accesses the base address. I had to write seprate statements to access the others. I just thought you and others would like to know.. If any other people on this forum have found a workaround I'm all ears....Chears for now....

    Dave Purola,
    N8NTA

  8. #8
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    Dave, are you serious? You can't use a variable for that field?

    I'm up the creek also then, my project relies heavily on MCP23016 ICs and controlling them within a loop. One easy alternative would be a bunch of IFs:

    IF loop = 0 THEN I2cWRITE blah,blah2,Constant0,[SteakBledindePatate]
    IF loop = 1 THEN I2cWRITE blah,blah2,Constant1,[SteakBledindePatate]
    IF loop = 2 THEN I2cWRITE blah,blah2,Constant2,[SteakBledindePatate]
    IF loop = 3 THEN I2cWRITE blah,blah2,Constant3,[SteakBledindePatate]
    IF loop = 4 THEN I2cWRITE blah,blah2,Constant4,[SteakBledindePatate]
    IF loop = 5 THEN I2cWRITE blah,blah2,Constant5,[SteakBledindePatate]
    IF loop = 6 THEN I2cWRITE blah,blah2,Constant6,[SteakBledindePatate]
    IF loop = 7 THEN I2cWRITE blah,blah2,Constant7,[SteakBledindePatate]

    But I'm not very keen on this idea.

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  9. #9
    Join Date
    Mar 2003
    Location
    Commerce Michigan USA
    Posts
    1,166


    Did you find this post helpful? Yes | No

    Default

    Demon, This is the code I assumed would work:

    UNIT0 CON %01110000 'U5's CONTROL BYTE (PCF8574A) I/O EXPANDER

    ************************************************** ********
    R_WI2CSW:'READ DIGITAL INPUTS FROM or WRITE DIGITAL OUTPUTS TO PCF8574'S
    ************************************************** ********
    SWCNTR = 0
    WHILE SWCNTR < 6
    CONTROL = UNIT0 | (SWCNTR << 1)
    IF READ_WRITE = 0 THEN 'READ INPUT STATUS FROM PCF8574'S
    I2CREAD SDA,SCL,CONTROL,[SWITCHES(SWCNTR)]
    ELSE 'WRITE OUTPUT STATE TO PCF8574'S
    I2CWRITE SDA,SCL,CONTROL,[OUTPUTS(SWCNTR)]
    ENDIF
    SWCNTR = SWCNTR + 1
    WEND
    RETURN

    But it didn't work as explained in my earlyer post. This is what I had to do instead:

    UNIT0 CON %01110000 'U5's CONTROL BYTE (PCF8574A) I/O EXPANDER
    UNIT1 CON %01110010 'U6's CONTROL BYTE (PCF8574A) I/O EXPANDER
    UNIT2 CON %01110100 'U7's CONTROL BYTE (PCF8574A) I/O EXPANDER
    UNIT3 CON %01110110 'U11's CONTROL BYTE (PCF8574A) I/O EXPANDER
    UNIT4 CON %01111000 'U12's CONTROL BYTE (PCF8574A) I/O EXPANDER
    UNIT5 CON %01111010 'U13's CONTROL BYTE (PCF8574A) I/O EXPANDER


    ************************************************** ********
    R_WI2CS:'READ DIGITAL INPUTS FROM or WRITE DIGITAL OUTPUTS TO PCF8574'S
    ************************************************** ********
    IF READ_WRITE = 0 THEN 'READ INPUT STATUS FROM PCF8574'S
    I2CREAD SDA,SCL,UNIT0,[SWITCHES(0)]
    I2CREAD SDA,SCL,UNIT1,[SWITCHES(1)]
    I2CREAD SDA,SCL,UNIT2,[SWITCHES(2)]
    I2CREAD SDA,SCL,UNIT3,[SWITCHES(3)]
    I2CREAD SDA,SCL,UNIT4,[SWITCHES(4)]
    I2CREAD SDA,SCL,UNIT5,[SWITCHES(5)]
    ELSE
    I2CWRITE SDA,SCL,UNIT0,[OUTPUTS(0)]
    I2CWRITE SDA,SCL,UNIT1,[OUTPUTS(1)]
    I2CWRITE SDA,SCL,UNIT2,[OUTPUTS(2)]
    I2CWRITE SDA,SCL,UNIT3,[OUTPUTS(3)]
    I2CWRITE SDA,SCL,UNIT4,[OUTPUTS(4)]
    I2CWRITE SDA,SCL,UNIT5,[OUTPUTS(5)]
    ENDIF
    RETURN

    Now very elegant......

    Dave Purola,
    N8NTA
    Last edited by Demon; - 4th October 2016 at 18:06.

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


    Did you find this post helpful? Yes | No

    Default

    I'll have an eye on this once back in town. Interesting...

    Is the same thing happen with Lookup too?

    Code:
    WichIOExpander var byte
    
    For Loop = 0 to 6
        Lookup WichIOExpander,[%11110000,%11110001,%11110010,%11110011,_
                               %11110100,%11110101,%11110110]
        I2cWRITE blah,blah2,WichIOExpander,[SteakBledindePatate]
        pause 5
        next
    About now? Just curious
    Last edited by mister_e; - 18th November 2005 at 19:18.
    Steve

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

  11. #11
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    Steve, I'm not set up to test right now.

    Dave, are you sure you used a BYTE?

    I reread the manual and there is nothing for I2CREAD that says CONTROL byte must be a constant.

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  12. #12
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    Dave, here's my complete code using a 16F877 and MCP23016:

    ADCON1 = 7 ' A/D off, all digital
    ASM
    @ DEVICE PIC16F877, HS_OSC, WDT_OFF, PWRT_ON, BOD_ON, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, PROTECT_OFF
    ENDASM
    define OSC 20
    DEFINE I2C_SLOW 1 ' Access I2C device above 8MHz
    DEFINE I2C_HOLD 1 ' Permit I2C device to hold clock line low
    I2CSCL VAR PortC.3
    I2CSDA VAR PortC.4
    I2CCTRL con %01000000
    I2CLOCB VAR BYTE
    I2CWORD VAR WORD
    I2CLOCB = $06 ' Set location to IODIR register
    I2CWORD = %0000000000000000
    i2cWRITE I2CSDA,I2CSCL,I2CCTRL,I2CLOCB,[I2CWORD]
    PAUSE 12
    I2CLOCB = $00 ' Set location to GPIO register
    I2CWORD = %1111111111111111
    i2cWRITE I2CSDA,I2CSCL,I2CCTRL,I2CLOCB,[I2CWORD]
    end

    It doesn't work, and it is using a constant.

    I don't understand why either, I had this circuit working a few weeks ago. I'm sure I have something screwed in the code, but I don't see what it can be.

    Robert
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

  13. #13
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default

    Just a bit more on the code above, the 1st I2CWRITE sets the pins as output, the 2nd turns them all ON.
    My Creality Ender 3 S1 Plus is a giant paperweight that can't even be used as a boat anchor, cause I'd be fined for polluting our waterways with electronic devices.

    Not as dumb as yesterday, but stupider than tomorrow!

Similar Threads

  1. Bits, Bytes Words and Arrays
    By Melanie in forum FAQ - Frequently Asked Questions
    Replies: 24
    Last Post: - 14th June 2016, 07:55
  2. Instant Interrupts - Revisited
    By Darrel Taylor in forum Code Examples
    Replies: 772
    Last Post: - 17th February 2016, 22:14
  3. RF Transmitter
    By et_Fong in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 27th October 2005, 16:34
  4. error on compiling
    By parker in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 16th June 2005, 14:31
  5. 18f452 internal eprom help
    By TONIGALEA in forum mel PIC BASIC Pro
    Replies: 13
    Last Post: - 13th July 2004, 15:50

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