标准韦根格式

一、韦根定义

     Wiegand协议是国际上统一的标准,是由摩托罗拉公司制定的一种通讯协议。适用于涉及门禁控制系统的读卡器和卡片的许多特性。

     它有很多格式,常用格式有标准的26-bit,此外还有34-bit,37-bit,客户也可自定义3266等格式,其中标准的26-bit格式是一个开放式的格式,是一个广泛使用的工业标准,并且对所有HID的用户开放。几乎所有的门禁控制系统都接受标准的26-bit格式

 

一、接口定义

一般由三条导线组成

DATA 0     DATA 1         GND      

这三条线负责传输Wiegand信号。D 0 , D 1在没有数据输出时都保持+5V高电平。若输出为0,则D 0 拉低一段时间,若输出为1,则D 1 拉低一段时间低电平一般保持100us时间,然后拉高,高电平一般保持1.9ms两个电子卡韦根输出之间的最小间隔为0.25秒(250ms)。

                        HID PIDID卡)

官方产品对每一个电子卡号码的组成都是以HID号码和PID号码来标识的。

HID :   Hidden ID code隐含码。

PID :   Public ID code  公开码。

HID号码一般在读出器(刷卡机)的输出结果中会被隐藏。而PID号码在读出器的输出结果中会显示。

 

一般情况下,一个公司只分配一个HID号码,如16385,那么他所订购的所有电子卡和读出器的HID号码都是16385

订购的电子卡号码即PID号:将从0000165535,因为PID16位数据。2^16 = 65535

如果一个电子卡的HID号码与一个读出器的HID号码不同的话,那么这个电子卡就无法在这个读出器上工作。所以,如果客户不是第一次订购的话,需要在订单上写明产品的HID号码。

     特殊情况下,可以让一个读出器同时含有多个HID号码。

例如:一个读出器内如果含有10HID号码的话,那么将有10 *65535=655350个电子卡可以在该读出器上工作。例如客户想将卡分为贵宾卡和普通卡,贵宾卡可以在多个读出器上工作,而普通卡只能在属于自己的读出器上工作。

读出器读到电子卡后将读到的卡号按照预先设定的格式输出到外部终端,如计算机。我们把读出器的输出结果样式称为输出格式(即通讯协议)。输出格式包含多方面的含义:

1、RS232格式

波特率: 9600,奇偶校验:无, 数据位:8 bit,  停止位:1 bit

 

2、韦根格式

标准26位韦根格式为:

韦根脉冲宽度 = 100us

韦根脉冲周期 = 1.6ms

韦根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位的奇校验位

8

如:一张HID163850100 0000 0000 0001),PID为:0004的电子卡26输出为:

                           PID0004

1  0000  0001  0000  0000  0000  0100  0

 

韦根34位数据帧格式:

1  2          9  10         17 18                        33 34

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 x x x  x x x x  X       二进制

  

   1   位:为输出第2—17位的偶校验位

 2-17 位:ID卡的HID

18-33位:ID卡的PID号码

  34  位:为输出第18-33位的奇校验位

 

例:一张ID卡内容为:

HID32769 PID34953 (卡面印:2147584137 001, 34953 )

相应的二进制为:

HID1000 0000 0000 0001

PID1000 1000 1000 1001

IC

IC卡韦根协议一般用IC卡物理卡号生成。如IC四字节物理卡号为:09F7BD36

韦根32:表示数据没有奇偶校验,即IC卡四字节物理卡号转换为二进制正好32位。

因此韦根32就是09F7BD36

韦根34:四字节物理卡号转换后多出两位,表示数据有奇偶校验。

韦根数据为:84FBDE9B40 ,二进制如下。

1000  0100  1111  1011  1101  1110  1001  1011  0100  0000(截取34位)

韦根34位数据帧格式如下:

1  2          9  10         17 18                        33 34

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 x x x  x x x x  X       二进制

1   0000  1001    1111   0111   1011   1101   0011   0110  1

校验   0    9        F      7      B      D      3      6  校验

  1  位:为输出第2—17位的偶校验位1有偶数个,校验值为0.

2-33位:四字节的物理卡号数据

 34  位:为输出第18-33位的奇校验位1有奇数个,校验值为0.

 

韦根26:先去除第一位物理卡号数据:09,剩下F7BD36用做转换。

韦根数据为:7BDE9B00、二进制如下。

0111  1011  1101  1110  1001  1011  0000 (截取26位)

韦根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             二进制

0  1111   0111    1011   1101   0011    0110  0

校验  F       7       B      D      3       6   校验

 1  位  : 2 --13位的偶校验位。

2~25 位  : ic卡剩下物理卡号F7BD36的二进制数据

 26  位 : 14--25位的奇校验位

 

韦根66:原理与上一致,数据不够在前面补0。如IC四字节物理卡号为:09F7BD36

韦根34数据为:84FBDE9B40

韦根66数据为:00 00 00 00 04 FB DE 9B 00 (因为有校验,所以跟34的有点区别)

韦根66一般只有读身份证物理卡号时才用的到,因为身份证物理卡号为8字节。或者是读 IC卡扇区的时候,因为扇区数据可以写入八个字节。

韦根数据获取51代码示例如下:

 

uint8 code wg_bit_shift_t[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};  //code:定义的数据放到ROM
uint8 code wg_bit_shift[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
#define WG_TIMER_H  19
#define WG_TIMER_L  1

//buff:要生成韦根的物理卡号:如09、F7、BD、36。
void sendWG_n(uint8 *buff,uint16 bit_len) 
{     //bit_len:0x22;十进制为34,表示韦根34。
    uint8 i,tmp_byte = 0;
    uint16 ecc_h = 0,ecc_l = 0;
    uint16 len_tmp = bit_len;
    if(bit_len%8 == 0 || (bit_len%8-2) == 0);
    else return;
    if(bit_len%8)
        bit_len -= 2;
    for(i= 0 ;i <bit_len/2;i++)
    {      //用来生成第一个校验位  
        if(buff[i/8]&wg_bit_shift_t[i%8]) ecc_h++; 
    }
    for(i= bit_len/2 ;i <bit_len;i++)
        {     //用来生成最后一个校验位
        if(buff[i/8]&wg_bit_shift_t[i%8]) ecc_l++;  
    }
    if(len_tmp%8)  //第一个校验
    {
        if (ecc_h % 2) 
            send_bit1();
        else 
            send_bit0();
    }
    for(i= 0 ;i <bit_len;i++)  //获取所有位
    {
        tmp_byte = buff[i/8];
        tmp_byte <<= (i%8);
        if (tmp_byte & 0x80) send_bit1();
            else send_bit0();
    }
    if(len_tmp%8)  //最后一个校验
    {
        if (!(ecc_l % 2)) 
            send_bit1();
        else 
            send_bit0();
    }
}

//发送韦根数据
static void send_bit0(void)
{
    P32 = 0;            //P3.2    D0    
    delay_100us(1);     //100us
    P32 = 1;
    delay_100us(19);    //1.9MS
}
static void send_bit1(void)
{
    P33 = 0;              //P3.3     D1 
    delay_100us(1);       //100us
    P33 = 1;
    delay_100us(19);      //1.9MS
}                

 

注:韦根IO口默认高电平,因此一般配置为推挽输出,若直接输出韦根信号,则此时IO口电压仅3.3V。(实际应用中韦根输出5V为最佳,因此一般用三极管接到5V上,此时需要特别注意,三极管这里需不需要反向,比如输出高电平三极管不导通,IO0V,那么代码里处理就不是低电平延时100us,应该是高电平,因为此时的高电平实际输出为低电平。同理的:初始化时应该把IO拉低,否则第一次稳根数据将出错,因为韦根默认输出高电平)。

 

posted @ 2022-05-26 20:49  耿通宇  阅读(892)  评论(0编辑  收藏  举报