Menu

Access single bit in a word variable

Help
jackjames
2021-06-03
2021-09-01
1 2 > >> (Page 1 of 2)
  • jackjames

    jackjames - 2021-06-03

    A question:
    Is it possible to access a single bit of a word variable in this way?
    Dim Wa as word
    dim Bi as byte
    Bi = 15
    Wa.Bi = 1
    and also:
    Result = Wa.Bi


    Resolved: Use variable.bit addressing. Compiler builds after 6/6/2021 now checks the source variable type is a bit or a constant.

     

    Last edit: Anobium 2021-06-07
  • Anobium

    Anobium - 2021-06-03

    Yes.

    and, you can set set a bit within a variable, use this method:

    Dim my_variable as byte
    Dim my_bit_address_variable as byte
    
    my_variable = 0
    my_bit_address_variable = 7
    
    'Sets bit 7 of my_variable therefore 128
     'Where 1 or 0 or any bit address is valid
    my_variable.my_bit_address_variable = 1  
    
     
    • jackjames

      jackjames - 2021-06-03

      Thanks

       
    • jackjames

      jackjames - 2021-06-03

      I wrote two routines and did some tests with Simul Ide.
      They don't seem to work well, both SetBit and GetBit.
      I create a word variable, assign 0, set bit 0 to 1 and then go to read it. I should be reading 1 and reading 0 instead.

      Sub SetBit (BitArray As Word, In BitNum As Byte, In BitState As Byte)
              bitarray.bitnum=bitstate
      End Sub
      
      Function GetBit (In BitArray As Word, In BitNum As Byte) As Byte
              getbit = bitarray.bitnum
      End Function
      
       
      • Anobium

        Anobium - 2021-06-04

        This is a very odd approach. The sub and function will be slow, even if it worked.

        Just use variable_name.bit_name = 1|0 and targetBitVar = variable_name.bit_name

        Do these work? If these do not work then the sub and function will fail.

         
  • stan cartwright

    stan cartwright - 2021-06-03

    Hi @jackjames. your code is above my capabilities.
    I would if testing a bit .... AND the var with zero except the bit which would be set.

     
    • jackjames

      jackjames - 2021-06-03

      Yes, if the word variable is = 0 and I raise bit 0 the value I have to read is 1, obviously if I also raise bit 2 I have to read 3 and so on with all 16 bits.
      Unfortunately, in the simulation with Simul Ide i the read values ​​are not exact.

       
      • Chris Roper

        Chris Roper - 2021-06-03

        Have you tried PICSimLab?

        https://sourceforge.net/projects/picsim/
        lcgamboa is very quick to replay and make changes if we find any bugs and it has a Small but representative selection of devices including Devices with PPS and an Arduino UNO simulation.

        I tend to use SimulIDE if I am testing a potential hardware interface but PICSimLab is my go to for testing Libraries and functions.

         
      • stan cartwright

        stan cartwright - 2021-06-03

        Er nor really @jackjames, I am not into clever basic. I thought var and 0x00000001 would test bit 0 as would var and 0x00000010 test bit 2 etc.
        Or you could test any bits at the same time var and 0x11001010
        Am I missing something here cos I test bits in bytes sometimes. What's different about word vars?

         
        • jackjames

          jackjames - 2021-06-04

          @stan:
          You now gave me the example using an 8-bit variable.
          In this case, accessing the single bit of a byte-type variable works.
          The problem arises when you have to read / write the bits in a 16-bit word type variable.

           
  • stan cartwright

    stan cartwright - 2021-06-04

    @jackjames. I'm thinking there's no way to and a word with another word so get your point but why can't the hi/lo bytes be masked with and? There is a method of using the hi or lo byte of a
    word var.
    Code that directly addresses bits of a var are probably masking bytes anyway and are probably
    slower.
    In your original post you say access the bits in a word and thought you just meant read them.
    To set the bits I guess you or the mask.

     
  • stan cartwright

    stan cartwright - 2021-06-04

    Function GetBit (In BitArray As Word, In BitNum As Byte) As Byte
    getbit = bitarray.bitnum
    End Function

    I thought bitnum would only be 0 to 7.

     
    • jackjames

      jackjames - 2021-06-05

      I solved the problem and now both the sub and the two functions work.
      Practically the compiler does not like the variable with the status of the bit (1/0) in byte format.
      Passing it as BIT, both the Sub and the Functions work perfectly.
      Here is the written listing to perform the tests and the output result.
      Tested with SimulIde.

      Source:

              Dim ww1 As Word
              Dim b1 As Byte
              Dim c1 As Byte
      '       -
      '       -
              ww1=0
              b1=8
              c1=1
              Dim d1 As Bit
      '       -
              HSerPrint "ww1:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              ww1.15=1
              HSerPrint "ww1 Direct Bit access:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              ww1.1=1
              HSerPrint "ww1 Direct Bit access:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              ww1=0
              b1=8
              ww1.b1=1
              HSerPrint "ww1 Bit access:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              ww1=0
              b1=15
              d1=1
              ww1.b1=d1
              HSerPrint "ww1 Bit access:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              ww1=0
              SetBit ww1, b1, d1
              HSerPrint "ww1 Sub SetBit:"
              HSerPrint ww1
              HSerSend 13
              HSerSend 10
      '       -
              b1=15
              HSerPrint "GetBit:"
              HSerPrint GetBit(ww1, b1)
              HSerSend 13
              HSerSend 10
      '       -
              HSerPrint "Getbit2:"
              HSerPrint GetBit2(ww1, b1)
              HSerSend 13
              HSerSend 10
      '       -
      '       -
      '       ========================================================================
      '       Setta alto o basso un determinato bit di una variabile.
      '       ------------------------------------------------------------------------
      Sub SetBit (BitArray As Word, In BitNum As Byte, In BitState As Bit)
              bitarray.bitnum=bitstate
      End Sub
      '       -
      '       -
      '       ========================================================================
      '       Legge un determinato bit da una variabile
      '       ------------------------------------------------------------------------
      Function GetBit(In BitArray As Word, BitNum As Byte) As Bit
              Repeat BitNum + 1
                 Rotate BitArray Right
              End Repeat
              GetBit = STATUS.C
      End Function
      '       -
      '       -
      Function GetBit2 (In BitArray As Word, In BitNum As Byte) As Bit
              getbit2 = bitarray.bitnum
      End Function
      

      This is the result:
      ww1:0
      ww1 Direct Bit access:32768
      ww1 Direct Bit access:32770
      ww1 Bit access:256
      ww1 Bit access:32768
      ww1 Sub SetBit:32768
      GetBit:1
      Getbit2:1

       
      • Anobium

        Anobium - 2021-06-06

        What version of the compiler are you using ? var.bit = 0|1 only works on 0.98.07 or greater.

         
  • Anobium

    Anobium - 2021-06-06

    I think I have identified the issue. See the code below but essential you need to help the compiler to determine which bit of the byte you passed needs to be used.

    I have adapted the code. There is an overloaded SUB to show how to resolve to ensure the correct code is generated. Does this work for you?

    We should update the help?

    Evan

    ;Program compiled by Great Cow BASIC (0.98.07 2021-05-27 (Windows 64 bit)) for Microchip MPASM
        #OPTION Explicit
        'USART settings for USART1
        #define USART_BAUD_RATE 9600
        #define USART_TX_BLOCKING
        #define USART_DELAY OFF
    
       Dim ww1 As Word
            Dim b1 As Byte
            Dim c1 As Byte
    '       -
    '       -
            ww1=0
            b1=8
            c1=1
            Dim d1 As Bit
            Dim d2 as Byte
    '       -
    
            HSerPrintCRLF 2
    
            HSerPrint "1. Reset ww1 should read 0 :"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    '       -
            ww1.15=1
            HSerPrint "2. ww1 Direct Bit access should read 32768 :"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    '       -
            ww1.1=1
            HSerPrint "3. ww1 Direct Bit access should read 32770 :"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    '       -
            ww1=0
            b1=8
            ww1.b1=1
            HSerPrint "4. ww1 Bit access should read 256:"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    '       -
            ww1=0
            b1=15
            d1=1
            ww1.b1=d1
            HSerPrint "5. ww1 Bit access  should read 32768 :"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    
            ww1=0xFFFF
            b1=15
            d1=0
            ww1.b1=d1
            HSerPrint "6. ww1 Bit access  should read 32767 :"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    
    '       -
            ww1=0
            b1=15
            d1=1
            SetBit ww1, b1, d1
            HSerPrint "7. ww1 Sub SetBit using BIT should read 32768:"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    
            ww1=0
            b1=15
            d2=1
            SetBit ww1, b1, d2
            HSerPrint "8. ww1 Sub SetBit using BYTE should read 32768:"
            HSerPrint ww1
            HSerSend 13
            HSerSend 10
    
    
    '       -
            ww1=0
            b1=15
            HSerPrint "9. GetBit should read 0:"
            HSerPrint GetBit(ww1, b1)
            HSerSend 13
            HSerSend 10
    '       -
            ww1=0
            b1=15
            HSerPrint "A. Getbit2  should read 0:"
            HSerPrint GetBit2(ww1, b1)
            HSerSend 13
            HSerSend 10
    
    Wait 100 ms
    '       -
    '       -
    '       ========================================================================
    '       Setta alto o basso un determinato bit di una variabile.
    '       ------------------------------------------------------------------------
    Sub SetBit (BitArray As Word, In BitNum As Byte, In BtyeState As Byte)
            'Ensure the compiler uses bit 0 of the Byte
            bitarray.bitnum=BtyeState.0
    End Sub
    
    Sub SetBit (BitArray As Word, In BitNum As Byte, In BitState As Bit)
            bitarray.bitnum=bitstate
    End Sub
    
    
    '       -
    '       -
    '       ========================================================================
    '       Legge un determinato bit da una variabile
    '       ------------------------------------------------------------------------
    Function GetBit(In BitArray As Word, BitNum As Byte) As Bit
            'Use C not status.C for portability
            Set C Off
            Repeat BitNum + 1
               Rotate BitArray Right
            End Repeat
            GetBit = C
    End Function
    '       -
    '       -
    Function GetBit2 (In BitArray As Word, In BitNum As Byte) As Bit
            getbit2 = bitarray.bitnum
    End Function
    
     
  • Anobium

    Anobium - 2021-06-06

    @JackJames

    See https://sourceforge.net/projects/gcbasic/files/Release%20Candidates/Patches/GCB%40Syn/GreatCowBASIC/

    I do think now think this is bug not a usability issue. The compiler was not generating the code ASM when you used a BYTE. So, I have updated the compiler and message file to improved IndirectBitSet handling - the compiler now verifies the source is either a BIT or a CONSTANT.

     
    • jackjames

      jackjames - 2021-06-06

      I'll do some tests then I'll let you know.

       
    • jackjames

      jackjames - 2021-06-06

      This is the result of the compilation:

      Summary:
      Read by GCBASIC:
      Input lines: 152
      Subroutines: 424
      Chip resource usage:
      Program Memory: 1699/8192 words (20,74%)
      RAM: 74/368 bytes (20,11%)

      Assembling program ...
      Building symbol table ...
      Generating machine code ...
      (Assembly time: 0.093 seconds)

      Errors have been found:

      Error: GCASM: Symbol SYSBITVAR2 has not been defined at BTFSC SYSBITVAR2,5
      Error: GCASM: Symbol SYSBITVAR2 has not been defined at BTFSC SYSBITVAR2,6

      The message has been logged to the file Errors.txt.

      (Total time: 1.261 seconds)

       
      • Anobium

        Anobium - 2021-06-06

        I need the source code. I cannot reproduce.

        Evan

         
        • jackjames

          jackjames - 2021-06-06
           
          • Anobium

            Anobium - 2021-06-06

            That has no chip, no pps etc.

            Did you add this? if yes. Please attached this source.

             
            • jackjames

              jackjames - 2021-06-06

              Everything good.
              It was my mistake. There were unwanted lines left at the bottom of the file.

               

              Last edit: jackjames 2021-06-06
              • Anobium

                Anobium - 2021-06-06

                Does the change help? or, did I break something?

                 
                • jackjames

                  jackjames - 2021-06-06

                  They have been helpful to me.
                  It seems that everything works, I work on it a bit and see what happens.
                  Thanks

                   
1 2 > >> (Page 1 of 2)

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.