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

一、韦根协议原理

韦根接口在门禁行业广泛使用,是一个门禁行业的通信标准,通过两条数据线 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)开始,如箭头所示。
在这里插入图片描述

标准韦根34格式与韦根26相同,由 32 位卡号和 1 位偶校验位、1 位奇校验位组成。卡号中的高 16 位进 行偶校验,低 16 位进行奇校验。发送顺序从高位(每字节的 bit7)开始。
韦根 66 与韦根 26 的结构相同,但发送的字节长度有所不同,刷 Mifare1 S50 卡时发送 4 字节卡号;刷 UltraLight 卡时发送 7 字节卡号;刷身份证时发送 8 字节物理卡号

二、代码实现

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

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/3686400 = 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;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值