Archive for February 2003

Conditional Jumping in PIC16 Assembly

PIC Microcontrollers have a funky way of handling conditionals. I’d like to present a set of macros I’ve made to make this easier to use, as well as explain the basics behind the technique in general.

Most MCU’s I’ve worked with before PICs had nice simple conditional statements… The mnemonic was usually to the effect of “branch if x to destination”. Not so on the PICs.

On a PIC, we have to do an operation between the data to test, then either skip the next instruction or not, based on the results of this test.

Take the instruction “BTFSS” meaning “Bit-test F, Skip if Set”. This instruction takes a register and a bit number, and will jump over the next instruction if that bit number in the register is set. For example:

We have 2 registers, REG1 and REG2. We want to know if the value in REG1 equals the value in REG2. A quick, simple way to do this is first to load one into W, then subtract the other from it, with the result going in to W as not to destroy one of the variables. This sets the “ZERO” bit in the STATUS register to either 1 if the operation resulted in a 0, or 0 otherwise. We know if the operation resulted in 0 the two values are equal, so we can code like so:

TESTIFZERO
  movf REG1, w
  subwf REG2, w
  btfss STATUS, Z
    goto NOTEQUAL
EQUAL
  ; they were equal
  goto DONETESTING
NOTEQUAL
  ; they weren't equal

So we can test for equality.

We can also macro-ize it for ease of use…

BEQ macro REG1, REG2, DEST	; branch if REG1 == REG2
  movf REG2, W			; W <- REG2
  subwf REG1, W			; W <- REG1 - REG2
  btfsc STATUS, Z		; if result was nonzero: skip out
    goto DEST			; otherwise jump
  endm

This gives us a macro we can call with 2 registers and a destination, and have it jump there if the condition ends up being true, and just pass on through if it’s not true. Much, much easier to use.

The other tests: inequality, less than, greater than, less than or equal to, greater than or equal to and so on follow a similar pattern. They are all covered in the “conditionals.inc” file I use quite often. I have both register-register comparisons and register-literal comparisons in there. Feel free to grab a copy and use it in your next project.

Downloads