韦根协议——STM32收发

韦根协议——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的时间间隔才去发送下一位数据。
韦根26的发送
上图是我用逻辑分析以抓取出来的数据,由图可知低电平持续的时间大概是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); } } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229748.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:58
下一篇 2026年3月16日 下午3:59


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号