PIC Microcontroller Comparison Math Methods

8 bit compares

So how do you actually use this nifty instruction ?

I'm going to use ``RAMx'' and ``RAMy'' to indicate values in a RAM register, ``K'' to indicate some fixed constant value (often defined using the ``EQU'' assembler directive). (If you want to compare 2 constant values, use the assembler directive ``#if ... #else ... #endif''. The grid below *should* cover all other combinations. ).

Q: Hey ! you left out all the ``greater than'' operators !

A: Whoops. Well, if you need ``A > B'', you can always use ``B < A''.

Most of these are from Tony Nixon.

I'm going to go on the assumption that you want to execute a chunk of code only if the conditional is *true*. (This is what ``if()'' means in C and other decent high-level languages. Don't let those BASIC programmers confuse you.)

Put that chunk of code (or a CALL to it) immediately after these blocks of code, and follow that chunk with some unique label. Then replace the word "Endif" with the name of that label.

If that chunk of code is *exactly* one instruction long (say ``CALL''), and you're very clever, you can optimize this code even more.

[FIXME: how do I code ``if - then - else - endif'' blocks ?]

[FIXME: is there a *reason* Tony Nixon uses ``addlw'' and ``addwf'' rather than ``sublw'' and ``subwf'' ? All PICs support sublw and subwf, don't they ?]

;if RAMx <= K
;Tony Nixon
movf RAMx,w
addlw 255 - K           ; eg if RAMx > 5 ... addlw d'250'
btfsc status,carry
goto Endif


;if K <= RAMx
;Tony Nixon
movf RAMx,w
addlw 255 - K + 1       ; eg if RAMx < 5 ... addlw d'251'
btfss status,carry
goto Endif



;if RAMx < K
; Tony Nixon
movf RAMx,w
addlw 255 - K + 1       ; eg if RAMx >= 5 ... addlw d'251'
btfsc status,carry
goto Endif

;if K < RAMx
; Tony Nixon
movf RAMx,w
addlw 255 - K           ; eg if RAMx <= 5 ... addlw d'250'
btfss status,carry
goto Endif

More.

;if RAMx <= RAMy
; Tony Nixon
movf RAMy,w
sublw 0xFF
addwf RAMx,w
btfsc status,carry
goto Endif

;if RAMx <= RAMy
; Scott Dattalo
  movf  RAMx,w
  subwf RAMy,w
  skpc
  goto Endif
                ; better !
                ;16cxxx 4*14 = 52 bits of program memory (14 bit core)
                ;?????? 4*12 = 48 bits of program memory (12 bit core)

;if RAMx <= RAMy
; better, but only works on 18cxxx chips !
; Scott Dattalo
  movf  RAMx,w  ;wreg = RAMx
  subwf RAMy,w  ;wreg = RAMy - RAMx
  bn    Endif ;Branch if negative
  ; (You could use the bnc [branch if no carry] to achieve the same effect.
  ;  The negative bit has a clearer meaning in this context).
                ;The N bit will be cleared if RAMx == RAMy or
                ;RAMy > RAMx, and will be set if RAMy < RAMx
                ;18cxxx 3*16 = 48 bits of program memory
                ;16cxxx 5*14 = 70 bits of program memory

;[DAV: Huh ? Does bn really work on the 16cxxx 14 bit core ?]

More.

;if RAMy <= RAMx
; Tony Nixon
movf RAMx,w
sublw 0xFF
addwf RAMy,w
btfsc status,carry
goto Endif


;if RAMy <= RAMx
; unknown -- perhaps James Newton ?
movf RAMx, w
subwf RAMy, w
skpz	;for the case that RAMx=RAMy where C will be 1
skpnc
goto Endif



;if RAMx < RAMy
; Tony Nixon
movf RAMx,w
sublw 0xFF
addwf RAMy,w
btfss status,carry
goto Endif

; ``Tony's sequence can be reduced by an instruction. '' -- Scott Dattalo


;if RAMx < RAMy
; better, but only works on 18cxxx chips !
; Scott Dattalo
  movf  RAMy,w    ;wreg = RAMy
  subwf RAMx,w    ;wreg = RAMx - RAMy
  bnn   Endif     ;branch if not negative
                  ;The N bit will be cleared if RAMx == RAMy or
                  ;RAMx > RAMy, and will be set if RAMy < RAMx
  ; Again, you could use the bc (branch on carry) instruction too.




;if RAMy < RAMx
movf RAMy,w
sublw 0xFF
addwf RAMx,w
btfss status,carry
goto Endif