韦根协议

大二寒假的时候实验室的门禁坏了,那个时候我们也才刚进入实验室不久,然后修好它就成了我们的任务,程序我有些一部分,硬件不是我负责的,恰逢整理资料,就算是复习一下韦根协议吧~

Wiegand26以及Wiegand34协议, 是由美国工业安全委员会SIA的隶属组织制定的一个关于存取控制的标准协议。非接触式IC卡读写器接口和输出,也采用了该协议标准。

1 韦根协议—韦根协议的数据信号
韦根数据输出由二根线组成,分别是DATA0 和 DATA1 ;二根线分别为‘0’或‘1’输出。
输出‘0’时:DATA0线上出现负脉冲;
输出‘1’时:DATA1线上出现负脉冲;
负脉冲宽度TP=100微秒;周期TW=1600微秒;
韦根协议_第1张图片

2 韦根协议— 韦根码的数据格式(韦根26)
第2到第9位为分组码,分组码共有8个二进制位,有256个状态;(电子卡HID码的低8位)
第10到第25位为标识码,标识码共16个二进制位,有65536个状态;(电子卡的PID号码)
第1位是第2到第13位的偶校验位;
第26位是第14到第25位的奇校验位。
E XXXX XXXX XXXX XXXXXXXXXXXXO
其中E表示前12位偶较验,X表示24位数据,O表示后12位奇校验,以上数据高位在前,从左至右顺序发送。

编号含义:
HID号码即Hidden ID code 隐含码,PID号码即Public ID code 公开码。 PID很容易在读出器的输出结果中找到,但HID在读出器的输出结果中部分或者全部隐掉。HID是一个非常重要的号码,它不仅存在于卡中,也存在于读卡器中。如果卡中的HID与读卡器中的HID不同的话,那么这张卡就无法在这个读卡器上正常工作。

然后我们将韦根两条数据线接到STM32的GPIO,通过外部中断的方式读取26位数据
初始化GPIO:

    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC,ENABLE);//使能PORTA,PORTC时钟

    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);//关闭jtag,使能SWD,可以用SWD模式调试

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_15;//PA15
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA15

    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_5;//PC5
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
    GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC5
//外部中断初始化函数
void EXTIX_Init(void)
{
      EXTI_InitTypeDef EXTI_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟

    //GPIOC.5 中断线以及中断初始化配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

    EXTI_InitStructure.EXTI_Line=EXTI_Line5;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);     //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //GPIOA.15    中断线以及中断初始化配置
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);

    EXTI_InitStructure.EXTI_Line=EXTI_Line15;
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);     //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;          //使能按键所在的外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2, 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                   //子优先级1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); 

    NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;            //使能按键所在的外部中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;    //抢占优先级2, 
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                   //子优先级1
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                             //使能外部中断通道
    NVIC_Init(&NVIC_InitStructure); 
}

中断服务程序:

 void EXTI9_5_IRQHandler(void)
{           

    if(KEY0==0) {
        //LED0=!LED0;
        weigen[ii]=1;
        ii++;
        if(ii==26)
        {
          ii=0;
            check();
        }
    }
     EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}


void EXTI15_10_IRQHandler(void)
{

  if(KEY1==0)   {
        //LED1=!LED1;
      weigen[ii]=0;
      ii++;
      if(ii==26)
      {
          ii=0;
            check();
      }
    }
     EXTI_ClearITPendingBit(EXTI_Line15);  //清除LINE15线路挂起位
}

然后将26位数据转为int类型数据,通过比较预存起来的卡号相比较来判断开门与否

void check()
{
    for(i=0;i<26;i++)
    {
        if(weigen[i] == 1)
        {
            kaHao += pow(2,i);
        }
    }
    for(m=0;m<40;m++)
        {   
            if(kahaoku[m] == kaHao)
            {
                printf("Success!      ");
                LED1=1;
                delay_ms(500);
                LED1=0;
                break;
            }
            else
            {
                //printf("Failed   ");
                LED1=0;
            }                                                           
        }
        printf("%d",kaHao);
        kaHao = 0;
//      delay_ms(1000);
        printf("\n");       
}

写的很渣,用过一段时间后发现还有bug,经不起测试的程序0.0,曾经还被没存卡号的老师刷开门禁,真是丢人了,后来师兄的项目就做着这个就被换了,一开始觉得这个东西其实很简单,但是要做得好真的不是一件容易的事情,加油吧~

你可能感兴趣的:(电子)