最近在了解维根协议方面的内容,ID刷卡现在应用已经非常的普遍了。这里稍微总结下维根协议的知识。
韦根协议是国际上同意的标准,由摩托罗拉公司制定的一种通信协议。
标准的26bit应该是最常用的一种格式。还有34bit,37bit等
韦根协议的数据输出,必须接在MCU的两个可中断GPIO上,这样能及时相应DATA0和DATA1的数据流变化。
ID卡模组输出‘0’时,DATA0 线上出现负脉冲。ID卡模组输出‘1’时,DATA1 线上出现负脉冲。 平时两根线都是出于高电平上拉。
负脉冲宽度 = 100 us, T = 1600 us。例如,数据0x01000的时序如下图所示,数据从高位开始传输。。
文章图片
标准维根协议是有26位二进制数组成的,韦根26位输出格式:E XXXX XXXX XXXX XXXX XXXX XXXX O
其中。第1位为2~13位的偶校验位,第26位为14到25位的奇校验位。2到9位对应于电子卡HID码的低8位。10到25位对应于电子卡的PID号码。
以上数据从左至右顺序发送。高位在前。
软件编程方面:
初始化这两个 DATA0 DATA1GPIO口的int config,int callback func,int enable。
static volatile BYTE rx_bit_cnt;
Gpio_DataGet(WIEGAND_DATA0, &data, 1);
Gpio_DataGet(WIEGAND_DATA1, &data1, 1);
if (data =https://www.it610.com/article/= 0)//gpio0 int data0
{
wiegand_data &= ~(BIT25 >> rx_bit_cnt);
}
else if (data1 == 0)data1
{
wiegand_data |= BIT25 >> rx_bit_cnt;
}
//可能出错的地方;
if (data =https://www.it610.com/article/= 0 && data1 ==0)
{
mpDebugPrint("----ERROR-data0 and data1 have data simultaneously ---check the data sequence --- ");
}
else if (data =https://www.it610.com/article/= 1 && data1 ==1)
{
mpDebugPrint("----ERROR-data0 and data1 data line no data ---check if interrupt --- ");
}
rx_bit_cnt++;
if (rx_bit_cnt >= WIEGAND_DATA_LENGTH)
{
rx_bit_cnt = 0;
if (wiegand_odd_even_check())
{
//wiegand_get_nr();
EventSet(UI_EVENT, EVENT_WIEGAND);
}
else
{
mpDebugPrint("---wiegand data odd and even check wrong---");
}
}
do
{
Gpio_DataGet(WIEGAND_DATA0, &data, 1);
Gpio_DataGet(WIEGAND_DATA1, &data1, 1);
}
while (!data || !data1);
【奇偶校验方法(韦根协议)】当rx_bit_cnt == 26时,则完成26bit数据的读取,然后就开始进行奇偶校验
(比如奇校验,人为找出一个特定位,在传输某个二进制数据时,如果“1”的个数为偶数,则该特定位就会填上‘1’,使‘1’的个数为奇数个。反之,填上‘0)
static BOOL wiegand_odd_even_check(void)
{
WORD odd_check_data = https://www.it610.com/article/wiegand_data & 0x1fff;
//lower 13bit,奇校验
WORD even_check_data = https://www.it610.com/article/(wiegand_data>>13) & 0x1fff;
//higher 13bit,偶校验
if (odd_or_even_noumber(bit_count(odd_check_data)) == 1\/*ODD CHECK奇校验*/
&& odd_or_even_noumber(bit_count(even_check_data) ) == 0 /*EVEN CHECK偶校验*/){
return TRUE;
}
else{//no pass
return FALSE;
}
}
bit_count(odd_check_data)函数为对参数的“1”进行计数。方法如下:
static BYTE bit_count(WORD ch)
{
register BYTE cnt=0;
do
{
ch&= ch-1;
//this can clear the last 1(lowwer bit)
cnt++;
}
while(ch);
return cnt;
}
odd_or_even_noumber(WORD value)函数则直接返回 return (value & 0x1);