PIC Microcontroller Bit Math Method

Parity

Olin Lathrop [olin at cognivis.com], http://www.cognivis.com says:

Parity is a one-bit checksum for a string of bits. There are two kinds of parity, even and odd. Even parity is the one-bit sum of all the bits, and odd parity is the complement of that. A one-bit sum means the addition is carried out in a one-bit word, which is the same as the least significant bit of an addition using a larger word. This low bit therefore only indicates whether the sum was odd (1) or even (0). Therefore the even parity is 0 iff there are an even number of 1 bits in the string of bits being tested.

Note that one-bit addition is the same as XOR (make a truth table for addition and XOR if you're not conviced), so even parity can also be thought of as the XOR of all the bits being tested. That is how the compact example apparently from John Payson worked. First the high and low nibbles were XORed. Each bit in each nibble is now the parity of itself and the same bit in the other nibble. In other words, this reduces the problem to finding the parity of one of the nibbles. This value is XORed again with itself shifted right one bit. Bits 0 and 2 are now the parity of the upper and lower half of the nibbles. Bit 0 is then incremented if bit 2 is set, creating the combined parity in bit 0.

ODD parity is most useful for serial transmission like RS-232. This guarantees that each 9 bit word (8 data bits, 1 parity bit) sent contains at least one 0 bit and at least one 1 bit, which means all zeros or all ones is definitely an error condition. Parity isn't used as much today because it can only detect single bit errors. Most communications systems tend to use checksums for blocks of data with some sort of ACK/NACK higher level protocol.

From: John Payson
comments from Andrew Warren of Fast Forward Engineering

;8-bit parity
;This routine will leave the parity of X in X.0 
;while blenderizing most of the rest of X 
        swapf   X, W	;x =     abcdefgh  w =     efghabcd
        xorwf   X, F	;x =     abcdefgh  w =     efghabcd
			;    xor efghabcd
        rrf     X, W 	;x =     abcdefgh  w =     -abcdefg
			;    xor efghabcd      xor -efghabc
        xorwf   X, F 	;x =     abcdefgh  w =     -abcdefg
			;    xor efghabcd      xor -efghabc
			;    xor -abcdefg
			;    xor -efghabc

	; at this point, the parity for half the bits
	; (a, b, e, and f) is in bit 2 of X, and the
	; parity for the other half (bits c, d, g, and h)
	; is in bit 0 of X.

        btfsc   X, 2 	; if the parity of (a,b,e,f) is 0,
                        ; then the parity of (a,b,c,d,e,f,g,h)
                        ; is equal to the parity of (c,d,g,h)...
                        ; which is already in bit 0, so skip ahead.


        incf    X, F 	; otherwise, the parity of (a,b,e,f) is 1,
			; so the parity of (a,b,c,d,e,f,g,h) is
			; NOT equal to the parity of (c,d,g,h).
			; invert bit 0.

	; at this point, bit 0 contains the parity of
	; (a,b,c,d,e,f,g,h).

 

Scott Dattalo says:

; 7-bit parity
;
; This routine will calculate the parity of a 7-bit
; integer and place the result in the 8-position

    bcf    byte_to_send,7  ;assume the parity is even
                           ;Note: for odd parity, use bsf

 ; assume the bits in byte_to_send are abcdefgh

    swapf  byte_to_send,w  ;W = efghabcd
    xorwf  byte_to_send,w  ;W = ea.fb.gc.hd.ea.fb.gc.hd
                           ; where ea means e^a, etc
    movwf  t               ;
    rlf    t,f             ;t = fb.gc.hd.ea.fb.gc.hd.??
    rlf    t,f             ;t = gc.hd.ea.fb.gc.hd.??.ea
    xorwf  t,f             ;t = gcea.hdfb.gcea.hdfb.gcea.?.?
                           ;again, gcea means g^c^e^a
    rlf    t,w             ;w = hdfb.gcea.hdfb.gcea.hdfb.?.fb
    xorwf  t,w             ;w = abcdefgh.abcdefgh.....
                           ;ie, the upper 5-bits of w each contain
                           ;the parity calculation.
    andlw  0x80            ;We only need one of them
    iorwf  byte_to_send,w  ;copy it to the MSB of the byte to send.

Kübek Tony [tony.kubek at FLINTAB.COM] says

;++++++++++++
;
; CALC_PARITY - Calculates parity of one byte, content is trashed,
result in lowest bit
; There '1' means ODD and '0' means EVEN
; 
CALC_PARITY MACRO ARG_BYTE
        SWAPF   ARG_BYTE, W 
        XORWF   ARG_BYTE, F 
        RRF     ARG_BYTE, W 
        XORWF   ARG_BYTE, F 
        BTFSC   ARG_BYTE, 2 
        INCF    ARG_BYTE, F 
        ENDM

First save the parity bit,either the 8'th bit in 7 bit comms. or the 9'th in 8 bit comms ( with parity ).

In the case of 7 bit comms do not forget to clear it prior to using the macro below.

Using for example 7 data bits even parity, the parity bit ( 8'th bit ) should always make sure that totally the byte will have an even number of bits.

So ( excluding the parity bit of cource ) maybe you have 3 [ones] bit in the received byte, then the parity bit is ( should be :-) ) set to '1', to achive an even number of bits.

hsantana_at_kavlico.com shares this code:

Here is a parity generator that I used on a PIC16F872. Its main features are that it does not alter the words for which parity is generated, except, of course, the parity bit and can be extended over many words easily.
; Parity generator for PIC microprocessor Henry Santana
; Used in PIC16F872
;
; WordHigh, WordLow and carry are returned unmodified except for the parity bit.
;
; Enter with two 8-bit words (16 bits).
;
; WordHigh and WordLow = XDDDDDDD & DDDDDDDD
; P is parity bit WordHigh(7)
; D is data bit WordHigh(6...0) & WordLow(7...0)
;
; Assign WordHigh and WordLow before calling Sub_Parity16
; Program constants
    fReg equ 0
    Status equ 0x03
    Carry equ 0
    Bit0 equ 0
    Bit7 equ 7
;Program variables
cblock 0x20
WordHigh
WordLow
BitCount
Parity
endc

Sub_Parity16:
    movlw 0x01 ;0x01 for odd parity, 0x00 for even parity
    movf Parity ;Preset the parity bit store
    movlw 0x10 ;Total # of bits (16 in two bytes)
    movwf BitCount
Rotate:
    rrf WordHigh, fReg
    rrf WordLow, fReg
    btfsc Status, Carry
    comf Parity, fReg ;Complement parity bit store
    decsz BitCount, fReg
    goto Rotate

    rrf WordHigh, fReg
    rrf WordLow, fReg
    btfsc Parity, Bit0
    goto Parity1

Parity0:
    bcf WordHigh, Bit7
    goto Done

    Parity1: bsf WordHigh, Bit7
Done:
    return ;Return with parity set

NOTE: The routine can be extended to any number of words up to 127 by adding rrf instructions (1 for each 8-bit word), changing the bit counter (=2 X number of 8-bit words) and adding a variable store for each 8-bit word.

Unknown author from microchip forum post^ by Dario Greggio:

 CheckParity:              
     swapf    X, w    ; John's idea: reducing byte to nibble
     xorwf    X, w
     addlw    41H    ; bit 1 becomes B0^B1 and bit 7 becomes B6^B7
     iorlw    7CH    ; for carry propagation from bit 1 to bit 7
     addlw    2    ; Done! the parity bit is bit 7 of W
     andlw    80H    ; set NZ if odd parity, and leave 00 or 80 in W
     return
 
or as a C define:

#define PARITY(b) ((((((b)^(((b)<<4)|((b)>>4))) + 0x41) | 0x7C ) +2 ) & 0x80)

Archive:

Comments: