Wiegand(韦根)协议是由摩托罗拉公司定制的一种通讯协议,它适用于涉及门禁控制系统的读卡器和卡片的许多特性。韦根数据输出由两条数据线DATA0和DATA1,和公共的信号地GND组成。在没有数据输出时,DATA0和DATA1都保持高电平(典型为+5V电平),若输出'0'时,DATA0输出低脉冲而DATA1保持为高电平,输出'1'时,DATA1输出低脉冲而DATA0保持为高。典型的低脉冲宽度为50us,输出每一bit之前的间隔为1ms(如下图,实际的信号电平和时序由实际的韦根读卡器决定)。
韦根协议包含很多种格式来传输串行数据,英创公司工控主板支持最常用的韦根26 bit和韦根34 bit格式。
韦根26是已经广泛使用的工业校准,一个“韦根包”有26位数据,第1位为第1到第13位的偶检验,最后1位为第14到第26位的奇校验。中间24位为数据位。
韦根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个状态)的键盘信号检测。
韦根信号需要正确连接到英创工控主板后,驱动程序才能正常工作,英创各个主板连接韦根信号的定义如下:
Wiegand_DATA0 |
Wiegand_DATA1 |
|
ESM928x / ESM335x / EM335x |
GPIO14 |
GPIO15 |
EM9280 / EM9281 / EM9287 |
GPIO26 |
GPIO27 |
如前所述,韦根读卡器通常输出5V TTL电平,而英创工控主板的GPIO要求输入电平不能超过3.3V,所以韦根读卡器输出的信号需要经过转换后才能与英创主板的GPIO相连。下图是一个简单的5V转3.3V的电平转的电路。
下面是应用程序读取韦根信号的示例代码:
#include "stdafx.h"
#include
#include
#include
#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;
}
原文:WinCE工控主板对韦根信号的支持