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  |