PIC Tutorial 9 – BIT Operations

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                               ;

Comments

dfgdfsgdfgfdg

You may also like...