A friend of mine is writing her first PIC program using the 16C64, and she
has asked me this question, because she knows I use PICs, but I can't
think of how to do it!
Her Problem: If you have a value 'n', ranging from 0-7 in W (or a file
reg, whichever makes it work!)
How can you use this to set or clear bit 'n' in another
file reg. (or W)
In other words can you use W or any reg as an indirect bit pointer?
If not (and I think not), what is the best way to implement such a
function?
The best I can think of is something like
.
.
.
MOVLW B'11000001' ; for example obviously these
values will
MOVLW H'02' ; come from somewhere else in the
real prog!
CALL BITSET
IORWF TARGET,1
.
.
.
MOVLW H'06' ;
CALL BITCLR
ANDWF TARGET,1
.
.
.
"Paul B. Webster VK2BZC" wrote:
> Pick another register as pointer, let's call it "ptr".
>
> clrc
> movlw 1
> btfsc ptr,1
> movlw 4
> movwf mask
> btfsc ptr,0
> rlf mask,F
> btfsc ptr,2
> swapf mask,F ; or W if you need that
> Concept not original, copied from Dimitry amongst others.
I think the original version (1 cycle less) goes like this:
movlw 1
btfsc ptr,1
movlw 4
movwf mask
btfsc ptr,0
addwf mask,f
btfsc ptr,2
swapf mask,f
The 'rlf' is replaced with an 'addwf' thus 'clrc' is not needed
anymore. I had also posted a 32 bit version last week for the led bar
solution. I copied the technique for a part. The code is also found on
the website below.
On Tue, 2 Mar 1999 18:57:30 +0000 Paul BRITTON <.....Paul.BRITTONKILLspam@spam@MMSUK.CO.UK>
writes:
>Dear allies,
>
>A friend of mine is writing her first PIC program using the 16C64, and
>she
>has asked me this question, because she knows I use PICs, but I can't
>think of how to do it!
>
>Her Problem: If you have a value 'n', ranging from 0-7 in W (or a
>file
>reg, whichever makes it work!)
> How can you use this to set or clear bit 'n' in
>another
>file reg. (or W)
The PIC CPU core doesn't have an instruction to do it directly. A common
way is what you've done: translate the bit number to a mask, then use a
bytewise AND or OR to clear or set the masked bit. You only really need
one mask translation table or routine. Use the mask as is (all 0 except
one 1) to set bits with OR, and complememt the mask for the bit-clearing
AND instruction. If you need to optimize for speed, maybe a table of bsf
or bcf instructions would be faster:
setbi
rlf bitno,w ;Multiply bit number by 2
andlw b'00001110' ;Keep only relevant bits
addwf PCL,f ;jump into table below
bsf INDF,0
return
bsf INDF,1
return
[...]
bsf INDF,7
return
Thsi routine needs 19 instructions and always takes 9 cycles (including
the CALL and RETURN instructions). A corresponding routine would be
needed to clear bits. As with any table, ensure that PCLATH is set
properly. If you can store the bit number as bitnumber * 2 that would
avoid needing to multiply it every time to form the table index.
___________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]
Mike Keitz wrote:
> setbi
> rlf bitno,w ;Multiply bit number by 2
> andlw b'00001110' ;Keep only relevant bits
> addwf PCL,f ;jump into table below
> bsf INDF,0
> return
> bsf INDF,1
> return
> [...]
> bsf INDF,7
> return
>
> Thsi routine needs 19 instructions and always takes 9 cycles (including
> the CALL and RETURN instructions). A corresponding routine would be
> needed to clear bits. As with any table, ensure that PCLATH is set
> properly. If you can store the bit number as bitnumber * 2 that would
> avoid needing to multiply it every time to form the table index.
A simple lookup table and masking directly is faster. Only 8 cycles and
lesser code space.
main_routine:
.
.
.
call setbi ;7
iorwf INDF,f ;8 use andwf if clearing
.
.
setbi:
movf bitno,w
addwf PCL,f
retlw B'00000001' ; set to B'11111110' if clearing
retlw B'00000010'
.
.
.
retlw B'10000000'