奇偶校验方法(韦根协议)

最近在了解维根协议方面的内容,ID刷卡现在应用已经非常的普遍了。这里稍微总结下维根协议的知识。


韦根协议是国际上同意的标准,由摩托罗拉公司制定的一种通信协议。

标准的26bit应该是最常用的一种格式。还有34bit,37bit等


韦根协议的数据输出,必须接在MCU的两个可中断GPIO上,这样能及时相应DATA0和DATA1的数据流变化。

ID卡模组输出‘0’时,DATA0 线上出现负脉冲。  ID卡模组输出‘1’时,DATA1 线上出现负脉冲。 平时两根线都是出于高电平上拉。

负脉冲宽度 = 100 us, T = 1600 us  。例如,数据0x01000的时序如下图所示,数据从高位开始传输。。

奇偶校验方法(韦根协议)_第1张图片

标准维根协议是有26位二进制数组成的,韦根26位输出格式:E XXXX XXXX XXXX XXXX XXXX XXXX O

其中。第1位为2~13位的偶校验位,第26位为14到25位的奇校验位。2到9位对应于电子卡HID码的低8位。10到25位对应于电子卡的PID号码。

以上数据从左至右顺序发送。高位在前。

软件编程方面:

初始化这两个 DATA0 DATA1  GPIO口的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 == 0)           //gpio0 int data0
        {
                wiegand_data &= ~(BIT25 >> rx_bit_cnt);       
        }
        else if (data1 == 0)      data1
        {
                wiegand_data |= BIT25 >> rx_bit_cnt;
        }

        //可能出错的地方;

        if (data == 0 && data1 ==0)
        {
                mpDebugPrint("----ERROR-data0 and data1 have data simultaneously ---check the data sequence --- ");
        }
        else if (data == 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 = wiegand_data & 0x1fff;            //lower 13bit,奇校验
        WORD even_check_data = (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);

你可能感兴趣的:(编程语言--c)