标题：韦根协议
简介
Wiegand协议是国际上统一的标准，有很多格式，标准的26-bit 应该是最常用的格式。此外，还有34-bit 、37-bit 等格式。格式的含义如下：当给出这一串数字02888888888，用户并不知道这串数字的含义，但如果说这是一个电话号码的时候，那么你可能就会说：哦，028是成都的区号，而88888888是电话号码。呵呵，不错，这正是四川航空的服务热线。但是安防行业并不愿意把这些格式公开，而安防公司也常常变化这些格式来保证产品的保密性。
而标准26-bit 格式是一个开放式的格式，这就意味着任何人都可以购买某一特定格式的HID卡，并且这些特定格式的种类是公开可选的。26-Bit格式就是一个广泛使用的工业标准，并且对所有HID的用户开放。几乎所有的门禁控制系统都接受标准的26-Bit格式。
Wiegand（韦根）协议是由摩托罗拉公司制定的一种通讯协议，它适用于涉及门禁控制系统的读卡器和卡片的许多特性；其协议并没有定义通讯的波特率、也没有定义数据长度韦根格式主要定义是数据传输方式：Data0和Data1两根数据线分别传输0和1.现在应用最多的是26bit,34bit，36bit，44bit等等。
韦根数据输出的基本概念
韦根数据输出由二根线组成，分别是DATA0 和 DATA1 ；二根线分别为‘0’或‘1’输出。
输出‘0’时：DATA0线上出现负脉冲； 
输出‘1’时：DATA1线上出现负脉冲； 
负脉冲宽度TP=100微秒；周期TW=1600微秒； 
具体时序如下：
例如：数据‘01000’的时序如下：
韦根26位输出格式
韦根26位输出格式：
E XXXX XXXX XXXX XXXX XXXX XXXX O 
前12BIT偶校验 前12位 后12位 后12BIT奇校验
以上数据从左至右顺序发送。高位在前。
如果电卡的地区码位2个字符，即8位则可用那设置255个地区码（（15x16）+15=255）；电子卡的卡
号位4个字符，即16位则可设置65535个卡号
（（15x16x16x16）+（15x16x16）+（15x16）+15= 65,535）。
以电子卡为标准26位韦根格式为例，假设电子卡号码为：
地区码 ：01 卡号：0001 
韦根输出为： 
1 0000 0001 0000 0000 0000 0001 0 
前12BIT偶校验 前12位 后12位 后12BIT奇校验 
地区码 卡号
韦根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） 
{ 
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; 
} 
}
Wiegand（韦根）接口
Wiegand接口通常由3根线组成，它们是：数据0（Data0），数据1（Data1）和 Data return。这3条线负责传输Wiegand信号。D0，D1在没有数据输出时都保持+5V高电平。若输出为0，则D0拉低一段时间，若输出为1，则D1拉低一段时间。
两个电子卡韦根输出之间的最小间隔为0.25秒。
标准26位Wiegand通讯协议
标准韦根输出是由26位二进制数组成，每一位的含义如下：
1 2 9 10 25 26
X X X X X X X X X X X X X X X X X X X X X X X X X X 二进制 
第1位为2—13位的偶校验位
第2—9位对应与电子卡HID码的低8位
第10-25位对应电子卡的PID号码
第26位为14-25位的奇校验位
这26位数据在读出器的韦根输出线D0，D1上输出。
HID和PID
HID号码即Hidden ID code 隐含码，PID号码即Public ID code 公开码。PID很容易在读出器的输出结果中找到，但HID在读出器的输出结果中部分或者全部隐掉。HID是一个非常重要的号码，它不仅存在于卡中，也存在于读卡器中。如果卡中的HID与读卡器中的HID不同的话，那么这张卡就无法在这个读卡器上正常工作。
Wiegand接口硬件设计
可以将Wiegand接口的Data0和Data1两个输出接到MCU的两个IO脚上，采用查询的方式接收数据，但这样接收并不可靠。比较好的方法是将Data0和Data1接到MCU的两个中断引脚上，采用中断的方式接收数据。
韦根信号是两根数据线传输二进制数据，在空闲时端，两线的对0V的电源都为TTL电平的水平，也就是5V，一般通过5K电阻上拉，当有数据传输时，两根线交替地发送400uS低脉冲，当Data0线发脉冲时，数据是0；当Data1发脉冲时，发送的数据是1，不能两根线同时发脉冲。脉冲的间隔时间是1mS。
什么是韦根26
韦根26是一种通讯协议，象485、232、TCP/IP等通讯协议一样． 
韦根传感器是由一根双稳态磁敏感功能合金丝和缠绕其外的感应线圈组成的。它的工作原理是：在交变磁场中，当平行于敏感丝的某极性（例如n极）磁场达到触发磁感应强度时，敏感丝中的磁畴受到激励会发生运动，磁化方向瞬间转向同一方向，同时在敏感丝周围空间磁场也发生瞬间变化，由此在感应线圈中感生出一个电脉冲。此后若该磁场减弱，敏感丝磁化方向将保持稳定不变，感应线圈也无电脉冲输出；但当相反极性（s极）磁场增强触发磁感应强度时，敏感丝磁化方向又瞬间发生翻转，并在感应线圈中感生出一个方向相反的电脉冲。如此反复，韦根传感器便将交变磁场的磁信号转换成交变电信号。