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 ENDMFirst 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 setNOTE: 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:
The Unknown Author code is short, but doesn't work, nowhere near - I can't figure out what it was even aiming for.
The Kubek code works great, very clever, just needs you to copy the data byte first.