WinCE工控主板对韦根信号的支持

 2016-5-30         

  Wiegand(韦根)协议是由摩托罗拉公司定制的一种通讯协议,它适用于涉及门禁控制系统的读卡器和卡片的许多特性。韦根数据输出由两条数据线DATA0和DATA1,和公共的信号地GND组成。在没有数据输出时,DATA0和DATA1都保持高电平(典型为+5V电平),若输出'0'时,DATA0输出低脉冲而DATA1保持为高电平,输出'1'时,DATA1输出低脉冲而DATA0保持为高。典型的低脉冲宽度为50us,输出每一bit之前的间隔为1ms(如下图,实际的信号电平和时序由实际的韦根读卡器决定)。


wiegand.gif


  韦根协议包含很多种格式来传输串行数据,英创公司工控主板支持最常用的韦根26 bit和韦根34 bit格式。


  韦根26是已经广泛使用的工业标准,一个“韦根包”有26位数据,第1位为第1到第13位的偶检验,最后1位为第14到第26位的奇校验。中间24位为数据位。


wiegand.gif

韦根26格式定义


  对于韦根34格式,即一个“韦根包”有34位数据,第1位为第1到第17位的偶检验,最后1位为第18到第34位的奇校验。中间32位为数据位。


  英创公司在WinCE内核中添加了韦根协议解析的设备驱动程序,应用程序只需要打开"WIG1:"设备,然后调用DeviceIoControl等待驱动程序返回(调用DeviceIoControl,应用程序会挂起,不会占用CPU资源),当驱动程序接收到韦根数据后,会自动检查奇偶校验,然后由DeviceIoControl返回接收情况,可能返回的原因有:


  #define WG_DATA_VALID       0       // 接收到有效的韦根数据

    #define WG_PARITY_ERROR     1       // 奇偶校验错误

    #define WG_TIMEOUT          2       // 接收数据超时

    #define WG_BIT_LENGTH_ERROR 3       // 不能识别的韦根格式


  如果DeviceIoControl返回为0(WG_DATA_VALID),表示接收到有效的韦根数据,应用程序通过ReadFile函数从驱动读取数据,如果读回3个字节,表示为韦根 26格式,如果读回4字节,表示韦根 34格式。ReadFile读回的数据不包含韦根协议中的头尾奇偶校验位,仅为有效的数据位。


  如果ReadFile函数返回1个字节,表示接收到韦根读卡器按键信号,驱动程序目前支持4 bit(16个状态)的键盘信号检测。


  韦根信号需要正确连接到英创工控主板后,驱动程序才能正常工作,英创各个主板连接韦根信号的定义如下:



  

ESM680x / ESM335x /

ESM928x  / EM335x

EM9280 / EM9281 / EM9287
第一路韦根("WIG1:")Wiegand_DATA0GPIO14GPIO26
Wiegand_DATA1GPIO15GPIO27
第一路韦根("WIG2:")Wiegand_DATA0GPIO16 
Wiegand_DATA1GPIO17 


  如前所述,韦根读卡器通常输出5V TTL电平,而英创工控主板的GPIO要求输入电平不能超过3.3V,所以韦根读卡器输出的信号需要经过转换后才能与英创主板的GPIO相连。下图是一个简单的5V转3.3V的电平转的电路。


wiegand.gif


  下面是应用程序读取第一路韦根信号("WIG1:")的示例代码:


  #include "stdafx.h"

  #include <windows.h>

  #include <commctrl.h>

  #include <winioctl.h>

  #include "bsp_drivers.h"

 

  #define WG_DATA_VALID       0

  #define WG_PARITY_ERROR     1

  #define WG_TIMEOUT          2

  #define WG_BIT_LENGTH_ERROR 3

 

  DWORD WaitWiegandEvent(HANDLE hIRQ, DWORD dwTimeout)

  {

      DWORD   dwReturn = 0;

 

      if (!DeviceIoControl(hIRQ,  // file handle to the driver

          IOCTL_WAIT_FOR_WIG,     // I/O control code

          &dwTimeout,             // in buffer

          sizeof(DWORD),          // in buffer size

          &dwReturn,              // out buffer

          sizeof(DWORD),          // out buffer size

          NULL,                   // pointer to number of bytes returned

          NULL))                  // ignored (=NULL)

      {

          dwReturn =  WAIT_FAILED;

      }

 

      return dwReturn;

  }

 

  int _tmain(int argc, _TCHAR* argv[])

  {

      HANDLE  hWIG;

      DWORD   dwReturn, dwNumberOfBytesRead, i;

      BOOL    bRet;

      BYTE    WIGData[4];

 

      printf("Wiegand(26/34) Demo.\r\n");

      hWIG = CreateFile(_T("WIG1:"),         

          GENERIC_READ|GENERIC_WRITE,        

          FILE_SHARE_READ|FILE_SHARE_WRITE,  

          NULL,                              

          OPEN_EXISTING,                     

          FILE_FLAG_RANDOM_ACCESS,           

          NULL);

      if(hWIG == INVALID_HANDLE_VALUE)

      {

          printf("Can not open WIG1:\r\n");

          return -1;

      }

 

      while(TRUE)

      {

          dwReturn = WaitWiegandEvent(hWIG, INFINITE);

          switch( dwReturn )

          {

          case WG_DATA_VALID:

              dwNumberOfBytesRead = 0;

              bRet = ReadFile(hWIG, WIGData, sizeof(WIGData),

                    &dwNumberOfBytesRead, NULL);

              if(bRet)

              {

                  if(dwNumberOfBytesRead == 3 )

                      printf("WG26:0x");

                  else if(dwNumberOfBytesRead == 4)

                      printf("WG34:0x");

                  else if(dwNumberOfBytesRead == 1)

                      printf("Key:0x");

                  for( i = 0; i < dwNumberOfBytesRead; i++)

                      printf("%x", WIGData[i]);

                  printf("\r\n");

              }

              break;

 

          case WG_PARITY_ERROR:  

              printf("Parity checking error!\r\n");

              break;

          case WG_TIMEOUT:               

              printf("Timeout!\r\n");

              break;

          case WG_BIT_LENGTH_ERROR:

              printf("Unsupported bit length!\r\n");

              break;

          default:;

          }

      }

 

      CloseHandle(hWIG);

      return 0;

  }