Wiegand(韋根)協(xié)議是由摩托羅拉公司定制的一種通訊協(xié)議,它適用于涉及門禁控制系統(tǒng)的讀卡器和卡片的許多特性。韋根數(shù)據(jù)輸出由兩條數(shù)據(jù)線DATA0和DATA1,和公共的信號地GND組成。在沒有數(shù)據(jù)輸出時,DATA0和DATA1都保持高電平(典型為+5V電平),若輸出'0'時,DATA0輸出低脈沖而DATA1保持為高電平,輸出'1'時,DATA1輸出低脈沖而DATA0保持為高。典型的低脈沖寬度為50us,輸出每一bit之前的間隔為1ms(如下圖,實際的信號電平和時序由實際的韋根讀卡器決定)。
韋根協(xié)議包含很多種格式來傳輸串行數(shù)據(jù),英創(chuàng)公司工控主板支持最常用的韋根26 bit和韋根34 bit格式。韋根26是已經(jīng)廣泛使用的通用工業(yè)校準,一個“韋根包”有26位數(shù)據(jù),第1位為第1到第13位的偶校驗,最后1位為第14到第26位的奇校驗,中間24位為數(shù)據(jù)位。
對于韋根34格式,即一個“韋根包”有34位數(shù)據(jù),常見的格式為第1位為第1到第17位的偶校驗,最后1位為第18到第34位的奇校驗,中間32位為數(shù)據(jù)位。
英創(chuàng)公司為Linux工控主板提供了支持韋根協(xié)議的設(shè)備驅(qū)動模塊,在命令行輸入insmod wiegand-gpio.ko即完成驅(qū)動程序的加載。linux韋根驅(qū)動支持應(yīng)用程序通過非阻塞的輪詢操作(select)和異步通知的方式讀取韋根數(shù)據(jù),這里我們建議使用非阻塞輪詢方式。以非阻塞方式O_NONBLOCK打開設(shè)備文件后,使用num = read(fd,buffer,len)讀取韋根數(shù)據(jù),只讀取Site Code和User Code,不包含奇偶校驗位,各參數(shù)意義如下:
輸入?yún)?shù):
fd:int, 韋根設(shè)備文件描述符;
len:buffer長度,固定4字節(jié),小于4字節(jié)提示錯誤;
輸出參數(shù):
buffer:char *, read結(jié)果緩存,固定4字節(jié),根據(jù)不同返回值num,具有不同意義;
返回值:
num:int, 讀取成功時,表示讀取的字節(jié)數(shù),具體意義如下:
num = 4,讀取成功,數(shù)據(jù)格式為wiegand 34,buffer [0-1]為Site Code,buffer [2-3]為User Code;
num = 3,讀取成功,數(shù)據(jù)格式為wiegand 26,buffer [0]=0,buffer [1]為Site Code,buffer [2-3]為User Code;
num = 1,讀取成功,數(shù)據(jù)格式為鍵盤按鍵(部分讀卡器有此功能),buffer [0]=0, buffer [1]為按鍵值;
num = -1,讀取失敗,buffer [0]存錯誤碼:
-1//格式錯誤,長度不匹配
-2//偶校驗錯誤
-3//奇校驗錯誤
-4//用戶傳入buffer空間太小
英創(chuàng)各個主板連接韋根信號的定義如下:
Wiegand_DATA0 | Wiegand_DATA1 | |
ESM928x / ESM335x / EM335x | GPIO14 | GPIO15 |
EM9280 / EM9281 / EM9287 | GPIO26 | GPIO27 |
韋根讀卡器通常輸出5V TTL電平,而英創(chuàng)工控主板的GPIO要求輸入電平不能超過3.3V,所以韋根讀卡器輸出的信號需要經(jīng)過轉(zhuǎn)換后才能與英創(chuàng)主板的GPIO相連。下圖是一個簡單的5V轉(zhuǎn)3.3V的電平轉(zhuǎn)的電路,WG_DATA0和WG_DATA1為韋根讀卡器輸出信號,注意要將韋根讀卡器與英創(chuàng)工控主板共地。
以下是讀取韋根數(shù)據(jù)的應(yīng)用程序示例代碼:
#include
#include
#include
#include
#include
#include
#defineWIEGAND_ERROR_FORMAT -1 //格式錯誤,長度不匹配
#defineWIEGAND_ERROR_EVEN_PARITY -2 //偶校驗錯誤
#defineWIEGAND_ERROR_ODD_PARITY -3 //奇校驗錯誤
#defineWIEGAND_ERROR_LESS_BUF -4 //用戶傳入buf空間太小
intexitflag; //退出標志
charbuffer[4]; //read結(jié)果
intreadWiegandThreadFunc(void* lparam)
{
intfd = * (int*)lparam;
fd_set fdRead;
structtimeval aTime;
intret;
while(1)
{
FD_ZERO(&fdRead);
FD_SET(fd,&fdRead);
aTime.tv_sec = 2; //s
aTime.tv_usec = 0; //us
ret =select( fd+1, &fdRead, NULL, NULL, &aTime );
if( ret>0 )
{
if( FD_ISSET(fd, &fdRead) )
{
//用戶可以在此加入處理操作
intnum = 0;
num =read(fd,buffer,4);
if(num < 0)
{
interrorCode = (signedchar)buffer[0];
printf("ERROR:read failed! num: %d\n",num);
switch(errorCode)
{
caseWIEGAND_ERROR_FORMAT:
printf("ERROR CODE: %d, wiegand data format did not match wiegand-26,weigand-34 or 4 bits for keyboard!\n",errorCode);
break;
caseWIEGAND_ERROR_EVEN_PARITY:
printf("ERROR CODE: %d, wiegand data even parity was wrong!\n",errorCode);
break;
caseWIEGAND_ERROR_ODD_PARITY:
printf("ERROR CODE: %d, wiegand data odd parity was wrong!\n",errorCode);
break;
caseWIEGAND_ERROR_LESS_BUF:
printf("ERROR CODE: %d, buffer was too small, please set it to 4 bytes!\n",errorCode);
break;
default:
printf("ERROR CODE: %d, Unknown Error!\n",errorCode);
break;
}
}
else
{
printf("result: %x,%x,%x,%x\n",buffer[0],buffer[1], buffer[2], buffer[3]);
}
}
}
if( exitflag==1 )//exitflag在程序其他線程中改變
{
printf("exit!\n");
break;
}
}
pthread_exit( NULL );
return0;
}
intmain(intargc,char* argv[])
{
intfd;
inti = 0;
exitflag = 0;
fd =open("/dev/em9280_wiegand",O_RDONLY | O_NONBLOCK);
if(fd < 0)
{
printf("ERROR:open failed!\n");
return-1;
}
pthread_attr_t attr;
pthread_t m_thread;
int res;
res = pthread_attr_init(&attr);
if( res!=0 )
{
printf("Create attribute failed\n" );
}
// 設(shè)置線程綁定屬性
res = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
// 設(shè)置線程分離屬性
res += pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
if( res!=0 )
{
printf( "Setting attribute failed\n" );
}
// 創(chuàng)建select線程,在此線程中讀韋根數(shù)據(jù)
res = pthread_create( &m_thread, &attr, (void*(*) (void*))&readWiegandThreadFunc, &fd );
if( res!=0 )
{
return-1;
}
pthread_attr_destroy( &attr );
while(1)
{
//執(zhí)行其他任務(wù)
printf("%d\n",i++);
sleep(1);
if(i==50)
{
exitflag = 1;
printf("over\n");
break;
}
}
close(fd);
return0;
}
-
Linux
+關(guān)注
關(guān)注
87文章
11213瀏覽量
208736 -
嵌入式主板
+關(guān)注
關(guān)注
7文章
6084瀏覽量
35162
發(fā)布評論請先 登錄
相關(guān)推薦
評論