一、概述:
Wiegand(韦根)协议是由摩托罗拉公司制定的一种通讯协议,它适用于涉及门禁控制系统的读卡器和卡片的许多特性;其协议并没有定义通讯的波特率、也没有定义数据长度。韦根格式主要定义是数据传输方式:Data0 和 Data1 两根数据线分别传输 0 和 1. 26bit,34bit36bit,44bit 等等。
二、Wiegand
Wiegand接口通常由3根线组成,它们是:数据0(Data0),数据1(Data1)和 Data return。这3条线负责传输Wiegand信号。D0,D1在没有数据输出时都保持+5V高电平。若输出为0,则D0拉低一段时间,若输出为1,则D1拉低一段时间。
输出‘0DATA0
输出‘1DATA1
负脉冲宽度 TP=100 TW=1600
具体时序如下:
例如:数据‘01000
三、标准26 Wiegand
标准韦根输出是由26位二进制数组成,每一位的含义如下:
1 2 9 10 25 26
E X X X X X X X X X X X X X X X X X X X X X X X X O 二进制
第1位为2—13位的偶校验位
第2—9位对应与电子卡HID码的低8位
第10-25位对应电子卡的PID号码
第26位为14-25位的奇校验位
这26位数据在读出器的韦根输出线D0,D1上输出。
以上数据从左至右顺序发送。高位在前。
四、韦根 26
DATA0为 0 DATA0 1 0 bit CPU ID 唯一的办法是在外部中断里接收每个 bit。 (仅仅在中断里获得开始接收 wiegand 数据还不行,因为这是尽管给开始接收 wiegand 数据标志位置位了,但是主程序还在执行其他代码而没有到达查询开始接收 wiegand 数据标志位这条指令)。
五.韦根接口定义:
Wiegand 接口界面由三条导线组成:
DATA0:暂定,兰色,P2.5
DATA1:暂定,白色,P2.6
GND:(通常为黑色), 暂定信号地。 当安装商拿到读卡器时,他们希望在读卡器和门禁控制面板的连接点(终端)上都能够看到这三个名称。
目前所有的标准型读卡器都提供可选择的 Wiegand 接口。这三条线负责传送 Wiegand 数据,也被称为Wiegand 信号。
代码仅供参考,没有实测,实际应用时,做发送,注意延时。做接收,一般用中断采集数据。
- 发送程序:
-
- //------------------------------------------------------
- //功能:把数组封包成韦根 26 的格式,并发送出去
- // 原理是把每个字节的低 4 位取出,来计算这个字节的值
- //入口:str=要封包的数组,
- //出口:DATA0P3.0;DATA1=P3.1
- //设计:大鹏,大鹏艾迪,2006/4/11
- //------------------------------------------------------
- void send_wiegand26(uchar *str)
- {
- //| wiegand[0] | wiegand[1] | wiegand[2] |
- //| *str *(str + 1) | *(str + 2) *(str + 3)| *(str + 4) *(str + 5)|
- uchar data i;
- static uchar data one_num; //计算 1 的个数
- uchar data check_temp; //韦根包奇偶效验中间暂存
- bit data even; //韦根包前 12 位偶效验
- bit data odd; //韦根包后 12 位齐效验
- static uchar data wiegand[3]; //韦根包数据 24 位
- //--------------------------------端口方向定义
- P3M0 = 0x00; //普通 I/O 口
- P3M1 = 0x00;
- //================================数组到韦根包的转化
- wiegand[0] = wiegand[0]|((*str)<<4);//原理是把每个字节的低 4 位取出,来计算这个字节的值
- wiegand[0] = wiegand[0]|(*(str+1)&0x0f);
- //--------------------------------计算前 8 位 1 的个数,为偶效验用
- check_temp = wiegand[0];
- for(i = 0;i<8;i++)
- {
- if(check_temp&0x01) //(check_temp&0x01)
- {
- one_num++;
- }
- check_temp >>= 1;
- }
- wiegand[1] = wiegand[1]|(*(str+2)<<4);
- //--------------------------------计算接下来的 4 位 1 的个数,为偶效验用
- check_temp = wiegand[1];
- for(i = 0;i<4;i++)
- {
- if(check_temp&0x80)
- Copyright(C) 2006-2007 DAPID. All Rights Reserved
- 3
- {
- one_num++;
- }
- check_temp<<=1;
- }
- //--------------------------------判断 1 的个数
- one_num%2 == 0 ? (even = 0):( even = 1);
- one_num = 0;
-
- wiegand[1] = wiegand[1]|(*(str+3)&0x0f);
- //--------------------------------计算接下来的 4 位 1 的个数,为奇效验用
- check_temp = wiegand[1];
- for(i = 0;i<4;i++)
- {
- if(check_temp&0x01)
- {
- one_num++;
- }
- check_temp>>=1;
- }
- wiegand[2] = wiegand[2]|(*(str+4)<<4);
- wiegand[2] = wiegand[2]|(*(str+5)&0x0f);
- //--------------------------------计算接下来的 8 位 1 的个数,为奇效验用
- check_temp = wiegand[2];
- for(i = 0;i<8;i++)
- {
- if(check_temp&0x01)
- {
- one_num++;
- }
- check_temp >>= 1;
- }
- //--------------------------------判断 1 的个数
- one_num%2 == 0 ? (odd = 1):( odd = 0);
- one_num = 0;
-
- //================================启动发送,用定时器做时间延时
- //--------------------------------韦根 输出端初始化
- WG_DATA0 = 1;
- WG_DATA1 = 1;
- //--------------------------------发送偶效验
- if(even)
- {
- WG_DATA1 = 0;
- //-------------------------延时 100us
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
-
- TF0 = 0;
- WG_DATA1 = 1;
- }
- else
- {
- WG_DATA0 = 0;
- //------------------------延时 100us
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
-
- TF0 = 0;
- WG_DATA0 = 1;
- }
- //----------------------------延时一个发送周期
- TR0 = 0;
- TH0 = (65536 - 1382)/256; //定时 1500us
- TL0 = (65536 - 1382)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
-
- TF0 = 0;
- //-------------------------------发送 24 位数据
- for(i = 0;i<24;i++)
- {
- //---------------------------韦根 输出端初始化
- WG_DATA0 = 1;
- WG_DATA1 = 1;
- if((wiegand[0])&0x80)
- {
- WG_DATA1 = 0;
- //----------------------延时 100us
-
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
-
- while (!TF0) { ;}
- TF0 = 0;
- WG_DATA1 = 1;
- }
- else
- {
- WG_DATA0 = 0;
- //---------------------延时 100us
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
- TF0 = 0;
- WG_DATA0 = 1;
- }
- (*(long*)&wiegand[0]) <<= 1;
- //-------------------------------延时一个发送周期
- TR0 = 0;
- TH0 = (65536 - 1382)/256; //定时 1500us
- TL0 = (65536 - 1382)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
- TF0 = 0;
- }
- //==============================发送奇效验位
- //------------------------------韦根 输出端初始化
- WG_DATA0 = 1;
- WG_DATA1 = 1;
-
- if(odd)
- {
- WG_DATA1 = 0;
-
- //-------------------------延时 100us
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
- TF0 = 0;
- WG_DATA1 = 1;
- }
- else
- {
- WG_DATA0 = 0;
- //-------------------------延时 100us
- TR0 = 0;
- TH0 = (65536 - 78)/256; //定时 100us
- TL0 = (65536 - 78)%256;
- TF0 = 0;
- ET0 = 0;
- TR0 = 1;
- while (!TF0) { ;}
- TF0 = 0;
- WG_DATA0 = 1;
- }
- }