Searching \ for 'Using a variable to clear a bit' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=using+variable+clear
Search entire site for: 'Using a variable to clear a bit'.

Truncated match.
PICList Thread
'Using a variable to clear a bit'
1999\05\08@234030 by Jay Couture

flavicon
face
Hello,   I am trying to use a file register as a mask to clear a bit on
PORTB. I do get a warning when I compile:

Warning[202] E:\PIC\CODE\test.ASM 113 : Argument out of range.  Least
significant bits used.

Here is the code:
Let's say test = 1 for argument's sake (I've tested this and it does)
 movwf   test           ;save request
 movlw   .1             ;need to subtract 1 so range is from 0 to 7
 subwf   test, W        ;w = test - 1
 movwf   test           ;test = test - 1    test = 0
 bcf   PORTB, test      ;clear PORTB.0

It doesn't matter what bit I want to clear, bit five is the only one that
is ever cleared regardless of the value of test. I should point out that
test is in files register 0x015, so it makes sense why bit 5 (the lower
nybble) is the only one cleared, but why is it using it's address and not
it's value?

Thanks, Jay

1999\05\09@131456 by Byron A Jeff

face picon face
{Quote hidden}

Because the instruction doesn't have a way of representing the value. The
bcf instruction only accepts a constant between 0-7.

But fear not it can be done. You in fact need 8 bcf instructions and use
a small jump table. Try this on for size.

movwf   test            ; stick the bit to clear in test.
decf    test            ; subtract one. Takes one less cycle than yours

rlf     test,W          ; Double the value and stick back in W
andlw   0xf             ; make sure to make result in the jump table.
addwf   PCL,F           ; Jump to the appropriate instruction
bcf     PORTB,0         ; Clear bit 0
goto    done            ; and finished.
bcf     PORTB,1         ; Clear bit 1
goto    done            ; and finished.
bcf     PORTB,2         ; Clear bit 2
goto    done            ; and finished.

And so forth. The value in W coming in will select with pair of bcf, goto
instructions to execute.

I use this technique in my NPCI interpreter. To further generalize it the
address of the target is placed in the FSR register and the bcf instructions
are executed on INDF. That way the code can be applied against any register
file in the system instead of just PORTB.

Hope this helps,

BAJ

1999\05\09@133531 by Mik Kim

flavicon
face
Hi Jay,

You can't set bit position using register (or even W). It must be a
literal. bcf PORTB, 0 is ok, but bcf PORTB, test is not since test is a
register. If it did anything, it would operate on address of test and
not test content. I'm guessing the address of test is greater than 7, so
the compiler is giving you a warning.

Also, don't use bit operations on PORT. Instead of bcf, you might do
movf    PORTB, W
movwf   tempB
bcf     tempB, 0        ;must use literal as bit position
movf    tempB, W
movwf   PORTB

Jay Couture wrote:
{Quote hidden}

1999\05\09@193146 by Regulus Berdin

picon face
Hi,

I will do it this way (untested):

clear_bit:
       movlw   0b10000000
       movwf   mask

       movf    test,w
       addwf   PCL,f           ;carry is always clear
       rrf     mask,f
       rrf     mask,f
       rrf     mask,f
       rrf     mask,f
       rrf     mask,f
       rrf     mask,f
       rrf     mask,f

       comf    mask,w          ;invert mask
       andwf   PORTB,f         ;clear bit

Or:

clear_bit:
       movlw   1               ;mask=2^test
       btfsc   test,1
        movlw  4
       movwf   mask

       btfsc   test,0
        addwf  mask,f

       btfsc   test,2
        swapf  mask,f

       comf    mask,w          ;invert mask
       andwf   PORTB,f

regards,
Reggie

--
e-mail: spam_OUTrberdinTakeThisOuTspambigfoot.com
ICQ#:   31651436
URL:    http://www.bigfoot.com/~rberdin


Byron A Jeff wrote:
{Quote hidden}

1999\05\09@195029 by Scott Dattalo

face
flavicon
face
On Mon, 10 May 1999, Regulus Berdin wrote:

{Quote hidden}

I like it. How 'bout:

   rlf   test,W
   andlw 0x0e
   addwf pcl,f

   bcf   PORTB,0
   return

   bcf   PORTB,1
   return

   .
   .
   .

   bcf   PORTB,7
   return


?

7-iso cycles.

1999\05\10@081518 by Caisson

flavicon
face
> Van: Jay Couture <.....jcoutureKILLspamspam@spam@JCOUTURE.UTMEM.EDU>
> Aan: PICLISTspamKILLspamMITVMA.MIT.EDU
> Onderwerp: Using a variable to clear a bit
> Datum: zondag 9 mei 1999 5:24
>
> Hello,

Hello Jay,

>  I am trying to use a file register as a mask to clear a bit on
> PORTB. I do get a warning when I compile:
>
>  Warning[202] E:\PIC\CODE\test.ASM 113 : Argument out of range.  Least
> significant bits used.

<Snip>

>   bcf   PORTB, test      ;clear PORTB.0

> It doesn't matter what bit I want to clear, bit five is the only one that
> is ever cleared regardless of the value of test. I should point out that
> test is in files register 0x015, so it makes sense why bit 5 (the lower
> nybble) is the only one cleared, but why is it using it's address and not
> it's value?

You where on the right way finding the source of your troubles !

1) There is no command (AFAIK) that accepts _two_ File-Registers as
arguments.
2) The second argument of the B?F command is a _constant_ , ranging from 0
to 7

The warning that you are getting is that the _value_ "test" (aka 0x15) is
too large.  So, only the relevant bits ( bits 0, 1 & 2) are used.
Resulting in the ,observed by you, number 0x5.

Greetz,
 Rudy Wieser

1999\05\10@102741 by Dmitry Kiryashov

flavicon
face
Jay Couture wrote:
>
> Hello,   I am trying to use a file register as a mask to clear a bit on
> PORTB. I do get a warning when I compile:
>
>  Warning[202] E:\PIC\CODE\test.ASM 113 : Argument out of range.  Least
> significant bits used.
>
> Here is the code:
> Let's say test = 1 for argument's sake (I've tested this and it does)
>   movwf   test           ;save request
>   movlw   .1             ;need to subtract 1 so range is from 0 to 7
>   subwf   test, W        ;w = test - 1
>   movwf   test           ;test = test - 1    test = 0
>   bcf   PORTB, test      ;clear PORTB.0

Hi Jay. In bcf PORT,test construction test can only be literal in range
from 0 to 7 i.e. you tell to compiler with one bit exactly you need to clear.
If you need to clear differences bits every time you should apply another
idea.

1. Load W register with value with zeroes bits in required positions.
  For instance you need to suppress bit 0 and 2. Load 0xFA (11111010b)

  There was some discussion sometime ago related to this topic, try to
  search through PICLIST archive.

2. ANDWF PORTB,F and that's it! (Sometimes it's better to make operations
  under shadow copy of port in memory and after that copy result to port)

WBR Dmitry.

1999\05\10@103607 by Dmitry Kiryashov

flavicon
face
Mik Kim wrote:

Hi Mik.

{Quote hidden}

It will be exactly the same as just BCF PORTB,0 because you read from PORTB
first and do the Read_Modify_Write operation. Probably you mentioned about
shadow register operation but for this you need keep copy of port in memory
and modify it and after that only copy it to port.

WBR Dmitry.

1999\05\10@104236 by Dmitry Kiryashov

flavicon
face
Hi Reggie.

This way was definitely tested and discussed sometime ago ;-)


{Quote hidden}

1999\05\10@124939 by John Payson

flavicon
face
|I like it. How 'bout:
|
|    rlf   test,W
|    andlw 0x0e
|    addwf pcl,f
|    bcf   PORTB,0
|    return
|    bcf   PORTB,1
|    return
|    .
|    .
|    .
|    bcf   PORTB,7
|    return
|
|7-iso cycles.

Nice.  If code space is a bit tight, an alternative would be...

MaskTbl:                ; Put this part in low 256 bytes
       andlw   7
       addwf   PC
       db      1,2,4,8,16,32,64,128

RoutineThatNeedsToClearBit:
       ...
       movf    BitNum,w
       call    MaskTbl
       xorlw   255
       andwf   PORTB,f

10 cycles as written; each of the following will save a cycle:

-1- If you have the table values complemented, you can eliminate the
   xorlw 255 instruction.  The table is written as it is to allow
   use in bit-setting or bit-toggling applications as well as bit-
   clearing ones.

-2- Skipping the andlw 7 at MaskTbl.  Of course, you'd better make
   sure your bit address is 0-7 if you do that.

-3- Starting with the bit number in W instead of a file register.

Thus, this version--while not as fast as the other one--uses less code
space.  Note that the table in this version may be used by many inst-
ances of the code below.  If there are several places in the program
where you need to selectively clear bits from different registers,
that could be a major asset.

Note also that this version requires one layer of stack depth; the
version posted previously does not [the 'returns' could be replaced
by 'goto's if desired].

1999\05\10@184820 by Regulus Berdin

picon face
Dmitry Kiryashov wrote:
> This way was definitely tested and discussed sometime ago ;-)
>
> > Or:
> > clear_bit:
> >         movlw   1               ;mask=2^test
> >         btfsc   test,1
> >          movlw  4
> >         movwf   mask
> >
> >         btfsc   test,0
> >          addwf  mask,f
> >
> >         btfsc   test,2
> >          swapf  mask,f
> >
> >         comf    mask,w          ;invert mask
> >         andwf   PORTB,f

Hi Dmitry,

I was refering to the first routine I made, not this one.  As I
remember, this routine is from you.

regards,
Reggie

--
e-mail: .....rberdinKILLspamspam.....bigfoot.com
ICQ#:   31651436
URL:    http://www.bigfoot.com/~rberdin

More... (looser matching)
- Last day of these posts
- In 1999 , 2000 only
- Today
- New search...