韦根协议刷卡原理及代码实现

韦根协议刷卡原理及代码实现讲解韦根协议的基本原理 并通过引脚电平变化中断实现韦根协议刷卡

一、韦根协议原理

韦根接口在门禁行业广泛使用,是一个门禁行业的通信标准,通过两条数据线 DATA0(D0)和 DATA1 (D1)发送数据。目前用的最多的是韦根 34 和韦根 26,二者数据格式相同,只是发送的位数的不同。

DATA0 和DATA1 在无信号时同时保持高电平
若发送数据为0,则DATA0 数据线上出现一个 200us(可定义)的低电平,DATA1 数据线上信号保持不变
若发送数据为 1,则DATA1 数据线上出现一个 200us(可定义)的低电平,DATA0 数据线上信号保持不变
在 200us 低电平之外,DATA0 和DATA1 始终保持高电平。

标准韦根26 格式如图所示,由 24 位卡号和 1 位偶校验位、1 位奇校验位组成。卡号中的高 12 位进 行偶校验,低 12 位进行奇校验。发送顺序从高位(每字节的 bit7)开始,如箭头所示。
在这里插入图片描述

二、代码实现

本代码使用引脚电平变化中断实现韦根协议刷卡

1、韦根引脚初始化

/* 名称:void WGInit(void) 功能:韦根协议引脚设置为输入,并开启对应的引脚电平变化中断 入口参数:无 出口参数:无 使用说明: */ void WGInit(void) { 
    WG0_IN; //设置DATA0引脚为输入 WG1_IN; //设置DATA1引脚为输入 PCIFR|=1<<PCIF2; //清除PCINT23-16的引脚电平变化中断标志位 PCICR|=1<<PCIE2; //开启PCINT23-16上的的引脚电平变化中断 PCMSK2|=1<<PCINT22; //选择PCINT22-PD6的引脚电平变化中断 PCMSK2|=1<<PCINT23; //选择PCINT23-PD7的引脚电平变化中断 PCMSK2&=~(1<<PCINT16); //取消PCINT22-PD6的引脚电平变化中断 } //引脚电平变化中断 ISR(PCINT2_vect) { 
    global *gv = &global_struct; //全局结构体 T4_INIT(); //定时器4初始化,这里设置如果引脚电平变化中断触发后连续200ms无触发/数据,则认为接受完成 。  if((PIND&(1<<PIND7))==0x00) { 
    gv->WG_Data[gv->WG_Count] = 0; gv->WG_Count++; } if ((PIND&(1<<PIND6))==0x00) { 
    gv->WG_Data[gv->WG_Count] = 1; gv->WG_Count++; } if (gv->WG_Count>34) { 
    gv->WG_Count=0; } } 

2、定时器4初始化代码

/* 名称:void T4_INIT(void) 功能:定时器T4初始化 16位定时器 入口参数:无 出口参数:无 使用说明: */ void T4_INIT(void) { 
    PRR1 &= ~((1<<PRTIM4)); //启用USART2模块 //关闭T1 选择无时钟源,关闭系统时钟 T1-CS10 T2-CS20 T0-CS00 TCCR4B = (TMR_CLK_STOP<<CS40); //36864/ = 10ms TCNT4 = 65535-36864; //16位 65535 //sei(); //T1定时器普通模式、无分频,并开启定时器 TCCR4A = 0X00; TCCR4B |= (TMR_CLK_NO_PRESCALE << CS40); //开定时器T2溢出中断 TIMSK4 |= (1 << TOIE4); } /* 名称:ISR(TIMER4_OVF_vect) 功能:定时器T4 10ms溢出中断 入口参数:无 出口参数:无 使用说明: */ extern u8 wgdate[34]; ISR(TIMER4_OVF_vect) { 
    global *gv = &global_struct; TCNT4 = 65535-36864; TIME_BASE.time3++; if (TIME_BASE.time3>=20) //定时时间到200ms { 
    TIME_BASE.time3=0; if (gv->WG_Count==34) { 
    gv->WG_Count=0; memcpy(wgdate,gv->WG_Data,34); gv->WG_State=1; //连续200ms无数据接收,韦根接收完成标志位置位 } else { 
    gv->WG_Count=0; } TCCR4B &= ~(TMR_CLK_STOP<<CS40); //无时钟源,关闭系统时钟 TIMSK4 &= ~(1 << TOIE4); //关闭时器T1溢出中断 } } 

3、韦根协议奇偶检验代码

/* 名称:void check_even_odd(u8 *str) 功能:计算接受到的韦根数据的奇偶校验 入口参数:接受到的韦根数据 出口参数:无 使用说明: */ void check_even_odd(u8 *str) { 
    u8 i=0; u8 one_num=0; //偶校验计算:有偶数个1,那么检验位1=0,反之为1 for(i = 1;i < 17;i++) { 
    if(str[i] & 0x01) one_num++; } if((one_num % 2)==0) odd = 0; else odd = 1; one_num=0; //奇校验计算:有奇数个1,那么检验位2=0,反之为1 for(i = 17;i < 33;i++) { 
    if(str[i] & 0x01) one_num++; } if((one_num % 2)==1) even = 0; else even = 1; } 

4、韦根协议最终卡号获取代码

int WG_Recv34(unsigned char *str) { 
    global *gv = &global_struct; if(gv->WG_State) { 
    check_even_odd(wgdate); //韦根数据奇偶校验 if((even == wgdate[33]) && (odd == wgdate[0])) //判断韦根数据奇偶校验是否正确 { 
    gv->WG_State = 0; for(char m=0; m<(34/8); m++) //获取通过校验的韦根卡号对应的16进制数据gv->WG_ID { 
    for(char n=0; n<8; n++) { 
    gv->WG_ID[m] += wgdate[8*m+1+n]<<(7-n); wgdate[8*m+1+n]=0; } } memset(wgdate,0,34); even=0; odd=0; return 1; } else //韦根数据奇偶校验错误舍去该次数据 { 
    even=0; odd=0; gv->WG_State = 0; memset(wgdate,0,34); memset(gv->WG_ID,0,4); return 0; } } return -2; } 
今天的文章 韦根协议刷卡原理及代码实现分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2025-01-02 11:06
下一篇 2025-01-02 11:01

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/99740.html