韦根协议——STM32收发

  • 韦根26位STM32收发

简介:Wiegand(韦根)协议是由摩托罗拉公司制定的一种通讯协议,门禁系统的读卡器、IC卡常用到这种协议。此协议没有规定数据传输的波特率和长度。目前市场上常用的数据长度是26bit,34bit,36bit,44bit等。由于34bit与26bit原理相同的,代码仅仅是一点点区别,在这里主要讲述的是26bit

Wiegand 26格式:

校验位1 HID PID 校验位2
1bit 2~9bit 10~25bit 26bit

第2~9位:ID卡HID码的低8位

第10~25位:ID卡的PID号码

第1位:2~13位的偶校验位

第26位:14~25位的奇校验位

校验位1: 2~13位中,如果有偶数个1,则校验位1 = 0,反之为1

校验位2:14~25位中,如果有奇数个个1,则校验位2 = 0,反之为1

通信:

​ 韦根的发送主要是依赖于两根数据线,一根是DATA0,另外一根是DATA1。由名字不难看出出,DATA0主要是发数据“0”的,而DATA1主要是发送数据“1”的。

发送:

​ 在空闲的时候,两根数据线的电平都是为高的。当想发送“0”的时候,DATA0数据线由高电平被拉低并保持100us-300us的持续时间,就会将数据“0”发送出去。而发送数据“1”的方法也是类似的,但要注意的是在发送完一位数据后,要有1ms~3ms的时间间隔才去发送下一位数据。
韦根协议——STM32收发_第1张图片
上图是我用逻辑分析以抓取出来的数据,由图可知低电平持续的时间大概是200us,而下个信号再发出的时间是2ms左右。

接收:

​ 韦根的接收由于是不用判断脉冲宽度的,速度很快,仅仅是一个电平就可以了的。所以通常采用的是中断的方式去进行接收。两张卡的电平最小时间间隔是250ms,所以当要接收多张卡片时,可以用这个时间去判断这一张卡片的数据是否完全接收完成。

整体介绍完了,下面看看代码实现。

韦根26的发送:

int WG_Send26(unsigned char *str)
{
	unsigned char i, j, one_num	= 0;
	unsigned char even 		= 0;
	unsigned char odd 		= 0;
	unsigned short check_temp;
	unsigned short wgdata = 0;
	
	if(NULL == str)
		return -1;
 //偶校验
	check_temp = str[0];
	for(i = 0;i < 8;i++)
	{
		if(check_temp<>i & 0x01)
			one_num+=1;
	}
	check_temp = str[2];
	for(i = 0;i < 8;i++)
	{
		if(check_temp<

韦根26的接收:

int WG_Recv26(unsigned char *str)
{
		if(WG_State){
			if(WG_Count == 26){
				str[0] = WG_Data>>17 & 0xFF;
				str[1] = WG_Data>>9 & 0xFF;
				str[2] = WG_Data>>1 & 0xFF;
				check_even_odd(str);
				if(EVEN == (WG_Data>>25 & 0x01) && ODD == (WG_Data & 0x01)){
						WG_State = 0;
						WG_Data = 0;
						WG_Count = 0;
						return 1;
				}	
				else {
						WG_State = 0;
						WG_Data = 0;
						WG_Count = 0;
						return 0;
				}
			}
			WG_State = 0;
			WG_Data = 0;
			WG_Count = 0;
			return -1;
		}
		return -2;		
}

中断:

//外部中断3服务程序
void EXTI0_IRQHandler(void)
{

	if( EXTI_GetITStatus(EXTI_Line0) != RESET ) 
	{
		TIM_SetCounter(TIM3,0); 
    TIM_Cmd(TIM3, ENABLE);
		if(DATA_IN0 == 0){

				WG_Data <<= 1;
				WG_Count++;
		}			
		EXTI_ClearITPendingBit(EXTI_Line0);  //清除LINE2上的中断标志位  
		}
}

//外部中断4服务程序
void EXTI1_IRQHandler(void)
{

	if( EXTI_GetITStatus(EXTI_Line1) != RESET ) 
	{
	 TIM_SetCounter(TIM3,0); 
   TIM_Cmd(TIM3, ENABLE);
			if(DATA_IN1 == 0){
					WG_Data = (WG_Data<<1) | 0x01;
					WG_Count++;
		}
		EXTI_ClearITPendingBit(EXTI_Line1);  //清除LINE3上的中断标志位  
	}
}

//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
		WG_State = 1;
		TIM_Cmd(TIM3, DISABLE);
	}
}

韦根26收发的步骤跟程序也都记录下来了,可能有些地方描述的不清晰或者有错误,希望找到错误的朋友能在下面提醒我一下,我好做更改。
整体测试工程是下面链接可下载,要是没积分的话可留邮箱,我见到就会发。单片机用的是STM32f103系列的(好像是…)
工程下载

你可能感兴趣的:(单片机)