BIT
Operations
Bit
operations
allow us
to
manipulate
a single
bit
within a
word.
They
allow us
to move,
set and
clear
single
bits in
registers
or
numbers
that we
specify.
At the
end of
this
tutorial
we will
show you
a
program
that
will
produce
a set of
running
lights
that go
one way,
then the
other
way.
We saw
this
done
previously
when we
looked
at the
exclusive
OR
function,
where we
Exclusively
ORed the
ports
with a
word.
We have
already
seen a
couple
of bit
operations
when we
set up
the
ports on
the PIC,
and we
will
repeat
their
use
here.
BCF
This
instruction
will
clear a
bit that
we
specify
in a
register
that we
specify.
The
syntax
is:
BCF
<register>,<bit>
We used
this
previously
to
change
from
page 1
to page
0 by
clearing
a bit in
the
STATUS
register.
We can
also use
it to
set a
bit to 0
in any
other
register/location.
For
example,
if we
wanted
to set
the
third
bit in
11001101
stored
in
location
0C to 0,
we would
enter:
BCF
0C,03
BSF
This
instruction
will set
any bit
we
specify
to 1 in
any
register
that we
specify.
We used
this
previously
to go
from
Page 0
to Page
1. The
syntax
is:
BSF
<register>,<bit>,
and is
used in
exactly
the same
way as
BCF
above.
BTFSC
So far
we have
set or
cleared
a bit in
a
register.
But what
if we
want to
just
simply
test if
a bit is
a 1 or a
0 in a
register?
Well, we
can use
BTFSC.
It says
Bit Test
Register
F, and
Skip If
It Is
Clear.
This
instruction
will
test the
bit we
specify
in the
register.
If the
bit is a
0, the
instruction
will
tell the
PIC to
skip the
next
instruction.
We would
use this
instruction
if we
wanted
to test
a flag,
such as
the
carry
flag.
This
saves us
having
to read
the
STATUS
register
and
looking
at the
individual
bits to
see
which
flags
are
set.
For
example,
if we
wanted
to test
if the
Carry
flag had
been set
to 1
after we
have
added
two
numbers,
then we
would
enter
the
following:
BTFSC
03h,0
carry
on here
if set
to 1
or here
if set
to 0
If the
status
of the
bit is a
1, then
the
instruction
immediately
following
BTFSC
will be
carried
out. If
it is
set to a
0, then
the next
instruction
is
skipped.
The
following
section
of code
shows
where it
might be
used:
Loop
:
:
:
BTFSC
03,0
Goto
Loop
In the
above
code,
the PIC
will
only
come out
of the
loop if
bit 0 of
the
STATUS
register
(or the
Carry
flag) is
set to
0.
Otherwise,
the goto
command
will be
carried
out.
BTFSS
This
instruction
says Bit
Test
Register
F, And
Skip If
Set.
This is
similar
to the
BTFSC
instruction,
except
that the
PIC will
skip the
next
instruction
if the
bit we
are
testing
is set
to 1,
rather
than 0.
CLRF
This
instruction
will set
the
entire
contents
of a
register
to 0.
The
syntax
is:
CLRF
<register>
We used
this
previously
to set
the
output
of the
Ports to
0, by
using
CLRF 85h.
We also
used it
to set
the
Ports to
have all
pins to
output
by using
CLRF
05h.
CLRW
This is
similar
to the
CLRF
instruction,
except
is only
clears
the W
register.
The
syntax
is quite
simply:
CLRW
RLF
And RRF
These
commands
will
move a
bit in a
register
one
place to
the left
(RLF) or
the
right (RRF)
in a
register.
For
example,
if we
had
00000001
and we
used RLF,
then we
would
have
00000010.
Now,
what
happens
if we
have
10000000
and
carried
out the
RLF
instruction?
Well,
the 1
will be
placed
in the
carry
flag.
If we
carried
out the
RLF
instruction
again,
the 1
will
reappear
back at
the
beginning.
The same
happens,
but in
reverse,
for the
RRF
instruction.
The
example
below
demonstrates
this for
the RLF
instruction,
where we
have
shown
the 8
bits of
a
register,
and the
carry
flag :
C
76543210
0
00000001
RLF
0
00000010
RLF
0
00000100
RLF
0
00001000
RLF
0
00010000
RLF
0
00100000
RLF
0
01000000
RLF
0
10000000
RLF
1
00000000
RLF
0
00000001
Example
Program
We are now
going to
give you
an
example
code
which
you can
compile
and
run. It
will
produce
a
running
light
starting
at PortA
bit 0,
going to
PortB
bit 8
and then
back
again.
Connect
LEDs to
all of
the Port
pins.
You will
see some
of the
bit
operations
mentioned
in this
tutorial.
TIME
EQU
9FH
;
Variable
for the
delay
loop.
PORTB
EQU 06H
;
Port B
address.
TRISB
EQU
86H
;
Port B
Tristate
address.
PORTA
EQU 05H
;
Port A
address.
TRISA
EQU
85H
;
Port A
Tristate
address.
STATUS
EQU 03H
; Page
select
register.
COUNT1
EQU 0CH
; Loop
register.
COUNT2
EQU
0DH
; Loop
register.
BSF
STATUS,5
;
Go to
page 1
MOVLW
00H
;
and set
up
MOVWF
TRISB
; both
Ports A
and B
MOVLW
00H
; to
output,
MOVWF
TRISA
;
then
return
to
BCF
STATUS,5
;
page 0.
MOVLW
00H
; Clear
Port A.
MOVWF
PORTA
;
; Start
of main
program
RUN
MOVLW
01H
; Set
the
first
bit
MOVWF
PORTB
;
on Port
B.
CALL
DELAY
; Wait
a while
CALL
DELAY
;
; Move
the bit
on Port
B left,
then
pause.
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
CALL
DELAY
CALL
DELAY
RLF
PORTB,1
; This
moves
the bit
into the
carry
flag
; Now
move
onto
Port A,
and move
the bit
left.
RLF
PORTA,1
;
This
moves
the bit
from the
zero
flag
into
PortA
CALL
DELAY
CALL
DELAY
RLF
PORTA,1
CALL
DELAY
CALL
DELAY
RLF
PORTA,1
CALL
DELAY
CALL
DELAY
RLF
PORTA,1
CALL
DELAY
CALL
DELAY
; Move
the bit
back on
Port A
RRF
PORTA,1
CALL
DELAY
CALL
DELAY
RRF
PORTA,1
CALL
DELAY
CALL
DELAY
RRF
PORTA,1
CALL
DELAY
CALL
DELAY
RRF
PORTA,1
;
This
moves
the bit
into the
zero
flag
; Now
move the
bit back
on Port
B
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
RRF
PORTB,1
CALL
DELAY
CALL
DELAY
;
Now we
are back
where we
started,
;
GOTO
RUN
;
let's go
again.
;
Subroutine
to give
a delay
between
bit
movements.
DELAY
MOVLW
TIME
;
Get the
delay
time,
MOVWF
COUNT1
; and
put it
into a
variable.
LOOP1
;
DECFSZ
COUNT1
;
Decrement
1 from
the
delay
time
until it
GOTO
LOOP1 ;
reaches
zero.
MOVWF
COUNT1
; Get
the
delay
time
again,
LOOP2
;
and
repeat
the
count
down.
DECFSZ
COUNT1
;
GOTO
LOOP2
;
RETURN
; End
of
subroutine.
END ;
Click
here >>>>
Tutorial
10
|