Если интересно, реализация Wiegand на ASM AVR:
;----------------------------------------------------------------------------
;Wiegand interface module
;----------------------------------------------------------------------------
#define WG26BIT ;select 26 bit wiegand
;#define WG34BIT ;select 34 bit wiegand
;----------------------------------------------------------------------------
;Constantes:
.equ PWDTH = 50 ;pulse width, uS
.equ RATE = 1000 ;wiegand bit rate, uS
;----------------------------------------------------------------------------
;Derivated constantes:
.equ PW = PWDTH*FCLK/4000000
.if PW > MAXBYTE
.error "out of range constant"
.endif
.equ WRT = (RATE*FOUT)/500
.if PW > MAXBYTE
.error "out of range constant"
.endif
;----------------------------------------------------------------------------
.DSEG ;Data segment
wgDat: .byte 5 ;wiegand data buffer (MSB first)
wgCnt: .byte 1 ;TX bit counter
;----------------------------------------------------------------------------
.CSEG ;Code segment
;----------------------------------------------------------------------------
;Begin TX via wiegand:
wgTX: ldy wgDat
ld temp,Y+
rcall Parity ;byte 1 parity
mov XL,temp
ld temp,Y+
#ifdef WG34BIT
rcall Parity ;byte 2 parity
lsl temp
or temp,XL
rcall Parity
ror temp ;C - even parity
ldy wgDat
ld temp,Y
ror temp ;shift byte 1
st Y+,temp
ld temp,Y
ror temp ;shift byte 2
st Y+,temp
ld temp,Y
mov XL,temp
ror temp ;shift byte 3
st Y+,temp
ld temp,Y
mov XH,temp
ror temp ;shift byte 4
st Y+,temp
ldi temp,0
ror temp ;shift byte 5
push temp
mov temp,XL
ldi ZL,34
#endif
#ifdef WG26BIT
andi temp,0xF0
rcall Parity ;byte 2 parity
lsl temp
or temp,XL
rcall Parity
ror temp ;C - even parity
ldy wgDat
ld temp,Y
ror temp ;shift byte 1
st Y+,temp
ld temp,Y
mov XL,temp
ror temp ;shift byte 2
st Y+,temp
ld temp,Y
mov XH,temp
ror temp ;shift byte 3
st Y+,temp
ldi temp,0
ror temp ;shift byte 4
push temp
mov temp,XL
andi temp,0x0F
ldi ZL,26
#endif
rcall Parity ;byte 3(2) parity
mov XL,temp
mov temp,XH
rcall Parity ;byte 4(3) parity
lsl temp
or temp,XL
rcall Parity
ldi XL,0x01
eor temp,XL
bst temp,0 ;temp.0 - odd parity
pop temp
bld temp,6
st Y+,temp
sts wgCnt,ZL ;request to TX
ret
;----------------------------------------------------------------------------
;TX wgDat with WRate:
mWieg: lds temp,wgCnt ;check bit counter
tst temp
breq wgtxc ;wgCnt = 0, return
bbrc Flags,WRate,wgtxc
clbr Flags,WRate
dec temp
sts wgCnt,temp ;wgCnt--
ldy wgDat+5
ld temp,-Y
rol temp
st Y,temp
ld temp,-Y
rol temp
st Y,temp
ld temp,-Y
rol temp
st Y,temp
ld temp,-Y
rol temp
st Y,temp
ld temp,-Y
rol temp
st Y,temp
brcc tx_0
tx_1: Port_Data1_1 ;TX 1
rjmp tx_d
tx_0: Port_Data0_1 ;TX 0
tx_d: rcall DelPW ;pulse width delay
Port_Data1_0 ;release ports
Port_Data0_0
wgtxc: ret
;----------------------------------------------------------------------------
;Calculate parity:
;Input: temp - byte
;Out: temp.0
Parity: mov Cnt,temp
swap Cnt
eor Cnt,temp
mov temp,Cnt
lsr temp
eor temp,Cnt
mov Cnt,temp
lsr temp
lsr temp
eor temp,Cnt
andi temp,0x01
ret
;----------------------------------------------------------------------------
;Pulse width delay:
DelPW: ldi temp,PW
del1: dec temp ;1 +
nop ;1 +
brne del1 ;2 = 4
ret
;----------------------------------------------------------------------------
В таймерном прерывании (1 мс) вот это:
stbr Flags,wRate
В основном цикле:
rcall mWieg
Для передачи заполняем данными wgDat и вызываем wgTX. Передача осуществляется в фоновом режиме.