This post describes INCFSZ and INFSNZ Instructions for PIC Microcontroller with examples. INCFSZ
and INFSNZ
increment a file register and skip the next instruction if the result is zero or not zero respectively.
Note: For this tutorial I am using MPLAB X v5.0 but you can use any version upto v5.35. Version 5.35 is last version that included MPASM i.e. the assembler we require to compile the assembly code used in this tutorial. Code given here may not work for later versions.
INCFSZ: Increment f, Skip if zero
Syntax: INCFSZ
f{,d{,a}}
Length of the Instruction: 2 bytes
Instruction Cycles: 1 cycle if no skip (d != 0
). 2 cycles if skip (d = 0
) and followed by a 2 byte instruction. 3 cycles if skip (d = 0
) and followed by a 4 byte instruction.
Instruction Encoding: 0011 11da ffff ffff
Updated Flags: None
Destination: WREG
if d = 0
/ d = w
. File register f
if d = 1
/ d = f
. Destination is optional and the default is d = 1 / d = f
.
Access Bit: Access bank is used if a = 0
. BSR is used to select the bank if a = 1
. Access bit is optional and the default is a = 0
.
Description: PIC Microcontroller INCFSZ Instruction adds ‘1
‘ to the contents of file register f
and stores the result to WREG
or f
(depending on d
bit). If the result is zero then the next instruction is skipped.
Example: DECFSZ
Consider a loop written using INCFSZ
that runs 10 times. It copies a value from PORTB at each iteration and adds it to WREG. After the loop ends, value of WREG is moved to PORTC. We are using increment and skip instruction, so loop counter is initialized to the 2’s complement of number of times the loop needs to run.
COUNT EQU 0x01 ; Define loop variable
COUNT_Value EQU D'246' ; = (256 - number of times the loop is to be executed)
R1 EQU 0x02
MOVLW COUNT_Value ; load COUNT_Value into WREG
MOVWF COUNT ; Copy WREG (COUNT_Value) into COUNT
SETF TRISB ; Make PORTB an input
CLRF TRISC ; Make PORTC an output
MOVLW 0x0 ; Clear WREG
LOOP
MOVFF PORTB, R1 ; First instruction of the loop. Copy PORTB to R1
ADDWF R1, W ; Add R1 to WREG and place the result in WREG
INCFSZ COUNT,F ; Increment the loop counter (COUNT) and skip the next instruction if COUNT is zero (after increment)
GOTO LOOP ; If COUNT is not zero then unconditional branch to LOOP label occurs and next iteration is executed.
MOVWF PORTC ; Copy WREG to PORTC, after the loop ends
An unconditional branch instruction (
) to the first instruction in the loop is placed immediately after GOTO LOOP
INCFSZ
. Rest of the code (i.e. the code after the loop) is written after GOTO
instruction. During all the iterations except the last iteration, the result of INCFSZ
is not zero and GOTO
instruction is executed. During the last iteration, the result of INCFSZ
is zero and GOTO
instruction is skipped.
INFSNZ: Increment f, Skip if not zero
Syntax: INFSNZ
f{,d{,a}}
Length of the Instruction: 2 bytes
Instruction Cycles: 1 cycle if no skip (d != 0
). 2 cycles if skip (d = 0
) and followed by a 2 byte instruction. 3 cycles if skip (d = 0
) and followed by a 4 byte instruction.
Instruction Encoding: 0100 10da ffff ffff
Updated Flags: None
Destination: WREG
if d = 0
/ d = w
. File register f
if d = 1
/ d = f
. Destination is optional and the default is d = 1 / d = f
.
Access Bit: Access bank is used if a = 0
. BSR is used to select the bank if a = 1
. Access bit is optional and the default is a = 0
.
Description: PIC Microcontroller INFSNZ Instruction adds ‘1
‘ to the contents of file register f
and stores the result to WREG
or f
(depending on d
bit). If the result is not zero then the next instruction is skipped.
Example: DCFSNZ
Consider a loop written using DCFSNZ
that runs 10 times. It copies a value from PORTB at each iteration and adds it to WREG. After the loop ends, value of WREG is moved to PORTC. We are using increment and skip instruction, so loop counter is initialized to the 2’s complement of number of times the loop needs to run.
COUNT EQU 0x01 ; Define loop variable
COUNT_Value EQU D'246' ; = (256 - number of times the loop is to be executed)
R1 EQU 0x02
MOVLW COUNT_Value ; load COUNT_Value into WREG
MOVWF COUNT ; Copy WREG (COUNT_Value) into COUNT
SETF TRISB ; Make PORTB an input
CLRF TRISC ; Make PORTC an output
MOVLW 0x0 ; Clear WREG
LOOP
MOVFF PORTB, R1 ; First instruction of the loop. Copy PORTB to R1
ADDWF R1, W ; Add R1 to WREG and place the result in WREG
INFSNZ COUNT,F ; Increment the loop counter (COUNT) and skip the next instruction if COUNT is not zero (after increment)
GOTO OVER ; If COUNT is zero then unconditional branch to OVER label occurs and the loop ends
GOTO LOOP ; If COUNT is not zero then unconditional branch to LOOP label occurs and next iteration is executed.
OVER
MOVWF PORTC ; Copy WREG to PORTC, after the loop ends
An unconditional branch instruction “GOTO OVER
” is placed immediately after INFSNZ
. Code to be executed after the loop ends, is written at the OVER
label. An unconditional branch instruction “GOTO LOOP
” to the first instruction in the loop is placed after GOTO OVER
. During all the iterations except the last iteration, the result of
is not zero and INFSNZ
instruction is executed. During the last iteration, the result of GOTO LOOP
is zero and INFSNZ
GOTO OVER
instruction is executed (
instruction is skipped).GOTO LOOP