stm32收发 wiegand 韦根协议开发详解

韦根协议原理与C51单片机实现详解 韦根(Wiegand)协议是一种半双工、异步串行通信协议,广泛用于门禁系统、考勤机和身份识别领域。它具有简单、可靠、抗干扰强的特点,采用两条数据线(DATA0/DATA1)进行通信。c/* wg_config.h - 韦根协议配置头文件 *//* 系统时钟频率 *//* 韦根接口引脚定义 *//* DATA0,外部中断0 *//* DATA1,外部中断1 *//* 指示灯引脚 *//* 成功指示灯 *//* 错误指示灯 *//* 接收指示灯 *//* 韦根数据格式配置 */ 阅读详情

1 引言     

在刚开始接触到韦根接口时,知道这是一种门禁相关的传输协议。其中有两种比较常用的韦根数据格式,韦根26和韦根34,其中韦根26是开放的,韦根34开不开放我不知道(看样子不开放),但是在网上还是能看到韦根34的代码协议,下面介绍一下韦根26以及韦根34的相关内容。

2 Wiegand 26格式

各数据位的含义:

第 1   位: 为输出数据2—13位的偶校验位

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

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

第 26 位: 为输出数据14-25位的奇校验位

检验位1为偶校验位:对于WG26来说,如果前1-8位有偶数个1,那么检验位1=0,反之为1

检验位2为奇校验位:对于WG26来说,如果后14-25位有奇数个1,那么检验位2=0,反之为1

数据输出顺序:HID码和PID码均为高位在前,低位在后

例:一张ID卡内容为:

HID:32769   PID:34953      ( 卡面印:2147584137   001, 34953 )

相应的二进制为:

HID:1000 0000 0000 0001       ( 只输出低8位 )

PID:1000 1000 1000 1001

输出如下:

1  0 0 0 0 0 0 0 1   1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1    0

    |   HID_L        |   |       PID                      |

3 Wiegand 34格式

各数据位的含义:

第 1   位: 为输出第2—17位的偶校验位

第 2-17 位:  ID卡的HID码

第18-33位:  ID卡的PID号码

第 34 位: 为输出第18-33位的奇校验位

检验位1为偶校验位:对于WG34来说,如果前16位有偶数个1,那么检验位1=0,反之为1

检验位2为奇校验位:对于WG34来说,如果前16位有奇数个1,那么检验位2=0,反之为1

数据输出顺序:HID码和PID码均为高位在前,低位在后

例:一张ID卡内容为:

HID:32769   PID:34953       ( 卡面印:2147584137   001, 34953 )

相应的二进制为:

HID:1000 0000 0000 0001

PID:1000 1000 1000 1001

输出如下:

0  1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1      1 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1   0

   |       HID_L                    |                 |        PID                     |

        在空闲时间,两个线保持的是高电平+5V,两根线分别为DATA0和DATA1。其中,DATA0用来传输‘0’,DATA1用来传输‘1’,原本处于高电平状态的DATA0拉低一个脉冲宽度W,便发出了‘0’,DATA1原本处于高电平状态拉低一个脉冲宽度W,便发出了一个‘1’。上述脉冲宽度W=100us-200us较为合适,两输出之间间隔T=1ms-3ms较为合适。

        韦根连续发送两张卡的电平最小时间间隔T为0.25s,因此如果要连续接收多张电子卡数据时,可判断脉冲间隔T是否大于240ms,以此判断前一张卡片数据是否已经接收完成,韦根的接收程序一般是用中断方式完成,然后使用定时器进行计数以判断是否接受完一帧数据。

下图所示为,韦根时序图。

3.1 韦根34波形图与对应数据

3.2 韦根26波形图与对应数据

4 韦根代码实现

以下为韦根26和韦根34发送代码:

wiegand.h文件

#define WG_DATA0(x) {if(0==(x))	HAL_GPIO_WritePin(WGD0_GPIO_Port, WGD0_Pin,GPIO_PIN_RESET); else HAL_GPIO_WritePin(WGD0_GPIO_Port, WGD0_Pin,GPIO_PIN_SET);} 
#define WG_DATA1(x) {if(0==(x))	HAL_GPIO_WritePin(WGD1_GPIO_Port, WGD1_Pin,GPIO_PIN_RESET); else HAL_GPIO_WritePin(WGD1_GPIO_Port, WGD1_Pin,GPIO_PIN_SET);} 


typedef struct
{
	INT8U ucRxRingBuffer[WG_RX_BUFFERSIZE];//接收环形缓冲区
	INT16U usReadPos;					//环形接收缓冲区读位置
	INT16U usWritePos;					//环形接收缓冲区写位置
	INT8S usFrameCount;					//帧数
}WieGand_MSG_ST;						//韦根数据接收结构

wiegand.c 

int WG_Send26(unsigned char *str)
{
	unsigned char one_num	= 0;
	unsigned char even 		= 0;
	unsigned char odd 		= 0;
	unsigned char check_temp,i;

	if(NULL == str)
		return -1;

	/*首先计算2-13位共12位的奇偶*/
	check_temp = *str;
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	
	check_temp = *(str + 1);
	for(i = 0;i < 4;i++)
	{
		if(check_temp & 0x80)
			one_num++;
		check_temp <<= 1;
	}
	if(one_num % 2 )
		even = 0;
	else
		even = 1;

	
	/*然后计算14-25位共12位的奇偶*/
	one_num = 0;
	check_temp = *(str + 1);
	for(i = 0;i < 4;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	check_temp = *(str + 2);
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	if(one_num % 2 )
		odd = 1;
	else
		odd = 0;

	/*保持高电平准备发送数据*/
	WG_DATA0(1);
	WG_DATA1(1);
	HAL_Delay(5);

	/*发送第一位校验位*/
	if(even)
	{
		WG_DATA1(0);					
		myDelay_us(300);
		WG_DATA1(1);
	}
	else
	{			
		WG_DATA0(0);				   
		myDelay_us(300);
		WG_DATA0(1);
	}
	HAL_Delay(2);

	/*发送24位数据*/
	for(i = 0;i < 24;i++)
	{
		WG_DATA0(1);
		WG_DATA1(1);
		if(str[0] & 0x80)
		{
			WG_DATA1(0);
			myDelay_us(300);
			WG_DATA1(1);
		}
		else
		{
			WG_DATA0(0);
			myDelay_us(300);
			WG_DATA0(1);
		}
		(*(long*)&str[0]) <<= 1;
		HAL_Delay(2);			   
	}
	WG_DATA0(1); //拉高两条数据线电平
	WG_DATA1(1);

	/*发送最后一位校验位*/
	if(odd)
	{
		WG_DATA1(0);
		myDelay_us(300);
		WG_DATA1(1);
	}
	else
	{			
		WG_DATA0(0);
		myDelay_us(300);
		WG_DATA0(1);
	}
	WG_DATA0(1); //拉高两条数据线电平
	WG_DATA1(1);

	return 0;
}
int WG_Send34(unsigned char *str)
{
	unsigned char one_num 	= 0;
	unsigned char even 		= 0;
	unsigned char odd 		= 0;
	unsigned char check_temp,i;

	if(NULL == str)
		return -1;
	
	check_temp = *str; //第一个字节
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	
	check_temp = *(str + 1);//第二个字节
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	
	if(one_num % 2 )
		even = 0;
	else
		even = 1;
	
	one_num = 0;
	check_temp = *(str + 2);//第三个字节
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	check_temp = *(str + 3);//第三个字节
	for(i = 0;i < 8;i++)
	{
		if(check_temp & 0x01)
			one_num++;
		check_temp >>= 1;
	}
	if(one_num % 2 )
		odd = 1;
	else
		odd = 0;
	
	WG_DATA0(1); //拉高两条数据线电平
	WG_DATA1(1);
	HAL_Delay(5);

	/*发送第一位*/
	if(even)
	{
		WG_DATA1(0);
		myDelay_us(300);
		WG_DATA1(1);
	}
	else
	{
		WG_DATA0(0);
		myDelay_us(300);
		WG_DATA0(1);
	}
	HAL_Delay(2);

	/*发送32字节数据*/
	for(i = 0;i < 32;i++)
	{
		WG_DATA0(1);
		WG_DATA1(1);
		if(str[0] & 0x80)
		{
			WG_DATA1(0);
			myDelay_us(300);
			WG_DATA1(1);
		}
		else
		{
			WG_DATA0(0);
			myDelay_us(300);
			WG_DATA0(1);
		}
		(*(long*)&str[0]) <<= 1;
		HAL_Delay(2);
	}
	WG_DATA0(1); //拉高两条数据线电平
	WG_DATA1(1);

	/*发送最后一位校验位*/
	if(odd)
	{
		WG_DATA1(0);
		myDelay_us(300);
		WG_DATA1(1);
	}
	else
	{
		WG_DATA0(0);
		myDelay_us(300);
		WG_DATA0(1);
	}
	WG_DATA0(1); //拉高两条数据线电平
	WG_DATA1(1);

	return 0;
}

在韦根信号接收方面,我使用了一个循环缓冲数组进行接收,在接收代码编写过程中,之前有一个疑问是,似乎采用中断接收时,是不用判断脉冲宽度的,然后只增加了对于一帧数据是否接收完的超时判断,这个超时计数是通过定时器做的,判断是否大于240ms还没有接收到脉冲,如果超过,则认为一帧接收完成了。

WieGand_MSG_ST stWG_Receive;		//韦根数据接收结构
INT8U u_DataBits 		= 0;		//当前接收数据位数
INT16S us_FirstBitPos	= 0;		//记录存放帧格式的位置
extern	TIMER_WG_ST st_Timer_WG;	//韦根接收定时结构


void WG_Receive(unsigned char dataLineType)
{		
	//Data0-> 低电平表示1位0
	if(WG_DATA0_LINE == dataLineType)
	{
		/*接收的第一位*/
		if (st_Timer_WG.usTIM_WgRxTimeCount == 0xffff)
		{
			/*接收位数清零*/
			u_DataBits = 0;
			
			st_Timer_WG.usTIM_WgRxTimeCount = 0;/*开始计时*/
			/*记录存放本次接收位数的位置*/
			us_FirstBitPos = stWG_Receive.usWritePos;
			/*更新保存的位置*/
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
			
			/*增加--若写指针赶上了读指针,需要处理*/
			if(stWG_Receive.usWritePos == stWG_Receive.usReadPos)
			{
				/*读指针往后偏移一位*/
				if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34)
				{
					stWG_Receive.usReadPos++;
					if(stWG_Receive.usReadPos == WG_RX_BUFFERSIZE)
					{
						stWG_Receive.usReadPos = 0;
					}
				}
				else /*读指针往后偏移一帧*/
				{
					if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1))
					{
						stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1;
					}
					else
					{
						stWG_Receive.usReadPos = (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) - (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos);
					}
					if(stWG_Receive.usFrameCount > 0) 
						stWG_Receive.usFrameCount--;
				}
			}
			
			/*保存接收到的0*/
			stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 0;
			
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
		}
		else/*不是接收第一位*/
		{
			/*增加--若写指针赶上了读指针,需要处理*/
			if(stWG_Receive.usWritePos == stWG_Receive.usReadPos)
			{
				/*读指针往后偏移一位*/
				if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34)
				{
					stWG_Receive.usReadPos++;
				}
				else /*读指针往后偏移一帧*/
				{
					if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1)
						stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1;
					else
					{
						stWG_Receive.usReadPos = (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos) +1;
					}
					if(stWG_Receive.usFrameCount > 0) 
						stWG_Receive.usFrameCount--;
				}
			}
			/*保存接收到的0*/
			stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 0;
			
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
		}

		/*累计接收到的位数*/
		u_DataBits++;
		st_Timer_WG.usTIM_WgRxTimeCount = 0;
		stWG_Receive.ucRxRingBuffer[us_FirstBitPos] = u_DataBits; //存放接收到WG的位数
		
	}
	//Data1 -> 低电平表示1位1
	else if(WG_DATA1_LINE == dataLineType)
	{
		/*接收的第一位*/
		if (st_Timer_WG.usTIM_WgRxTimeCount == 0xffff)
		{
			/*接收位数清零*/
			u_DataBits = 0;
			/*开始计时*/
			st_Timer_WG.usTIM_WgRxTimeCount = 0;
			/*记录存放本次接收位数的位置*/
			us_FirstBitPos = stWG_Receive.usWritePos;
			/*更新保存的位置*/
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
			
			/*增加--若写指针赶上了读指针,需要处理*/
			if(stWG_Receive.usWritePos == stWG_Receive.usReadPos)
			{
				/*读指针往后偏移一位*/
				if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26 || stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34)
				{
					stWG_Receive.usReadPos++;
					if(stWG_Receive.usReadPos == WG_RX_BUFFERSIZE)
					{
						stWG_Receive.usReadPos = 0;
					}
				}
				else /*读指针往后偏移一帧*/
				{
					if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1))
					{
						stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1;
					}
					else
					{
						stWG_Receive.usReadPos = (stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1) - (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos);
					}
					if(stWG_Receive.usFrameCount > 0) 
						stWG_Receive.usFrameCount--;
				}
			}
			
			/*保存接收到的值*/
			stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 1;
			
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
		}
		else/*不是接收第一位*/
		{
			

			/*增加--若写指针赶上了读指针,需要处理*/
			if(stWG_Receive.usWritePos == stWG_Receive.usReadPos)
			{
				/*读指针往后偏移一位*/
				if(stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE26|| stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] != WG_TYPE34)
				{
					stWG_Receive.usReadPos++;
				}
				else /*读指针往后偏移一帧*/
				{
					if((WG_RX_BUFFERSIZE - stWG_Receive.usReadPos)> stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos]+1)
						stWG_Receive.usReadPos +=stWG_Receive.ucRxRingBuffer[stWG_Receive.usReadPos] +1;
					else
					{
						stWG_Receive.usReadPos = (WG_RX_BUFFERSIZE - stWG_Receive.usReadPos) +1;
					}
					if(stWG_Receive.usFrameCount > 0) 
						stWG_Receive.usFrameCount--;
				}
			}
			/*保存接收到的值*/
			stWG_Receive.ucRxRingBuffer[stWG_Receive.usWritePos] = 1;
			
			stWG_Receive.usWritePos++;
			if(stWG_Receive.usWritePos == WG_RX_BUFFERSIZE)
			{
				stWG_Receive.usWritePos = 0;
			}
		}

		/*累计接收到的位数*/
		u_DataBits++;
		st_Timer_WG.usTIM_WgRxTimeCount = 0;
		stWG_Receive.ucRxRingBuffer[us_FirstBitPos] = u_DataBits; //存放接收到WG的位数
		
	}	 
}

定时器计时代码timer.c

typedef struct
{
	INT16U		usTIM_WgRxTimeCount;	//接收韦根超时的信息结构体
}TIMER_WG_ST;

TIMER_WG_ST st_Timer_WG;

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	/*韦根接收计时*/
	if (htim->Instance == htim3.Instance)
	{
		if(st_Timer_WG.usTIM_WgRxTimeCount != 0xffff)
		{
			st_Timer_WG.usTIM_WgRxTimeCount++;
			if(st_Timer_WG.usTIM_WgRxTimeCount == WG_RXTIMEOUT)
			{
				//到达20ms延时,读取按键状态
				st_Timer_WG.usTIM_WgRxTimeCount = 0xffff;
				stWG_Receive.usFrameCount++; //接收到帧数+1
			}
		}
	}
}

125Khz RFID模块UART接口应用全解析:从通信协议到实战开发 UART(通用异步收发传输器)作为一种基础的串行通信接口,因其接线简单、协议通用,被广泛应用于单片机与外围模块的数据交换。其工作原理基于异步传输,通过起始位、数据位和停止位的组合实现设备间的可靠通信。在物联网和嵌入式系统中,UART的价值在于极大降低了硬件集成的复杂度,是连接传感器、执行器和无线模块的常见桥梁。典型的应用场景包括智能门禁、资产管理和工业自动化控制。本文聚焦于125Khz RFID读卡器模块,深入探讨其如何通过UART接口输出卡号数据,并详细解析其通信协议中的帧结构、校验机制以及抗干扰设计,为 阅读详情

相关推荐

韦根协议及IO模拟韦根34接口

1.写在前面 韦根(Wiegand)协议是国际上统一的标准,是由摩托罗拉公司制定的一种通讯协议。它适用于涉及门禁控制系统的读卡器和卡片的许多特性。 韦根有许多种类格式,常见有26-bit 、34-bit、37-bit格式,其中26-bit格式是最常用的格式。而标准26-bit 格式是一个开放式的格式,这就意味着任何人都可以购买某一特定格式的HID卡,并且这些特定格式的种类是公开可选的。26-Bi...

只要思想不滑坡,想法总比问题多。 2万+

WG协议韦根

这里设置了一个超时检测,就是接收到的两位数据之间的时间间隔如果大于5ms就认为数据超时,(因为读头发来的数据每位之间的间隔是2ms)。这样,如果有意外的脉冲干扰,引起计数数据位的count值错误,也只会产生一次数据接收错误,将各种标志和变量全部清零后,不会影响下一次的数据接收。无符号长整型是四个字节32位,装入26位的数据,则最前面的6位是无效的,循环移位6次,把无效数据移除。拉低数据线,等待404us到时,之后抬高数据线,再等待2ms的时间,一位数据就发送完成了。//如果最高位为1,发送1。

leiwei77的博客 1427

STM32F1微控制器实现Wiegand 26位协议中断接收实战

微控制器(Microcontroller Unit, MCU)是一种集成电路芯片,它将CPU、存储器、I/O端口和其他功能集成到一个单一芯片上。随着电子技术的发展,微控制器已经广泛应用于嵌入式系统、家用电器、工业控制等领域,因其体积小巧、成本低廉、功能强大而受到欢迎。Wiegand协议是一种广泛应用于门禁系统中的通信协议,由HID公司开发,最初用于其门禁卡技术。该协议的核心在于使用特殊的物理编码格式进行数据传输,其设计初衷是为了实现一种远距离、非接触式的ID卡识别技术。

weixin_34725745的博客 1013

韦根w34是多少位_韦根(Wiegand)数据传输格式

韦根数据传输使用TTL电平,有两条数据线,分别称为DATA0和DATA1。无数据传输时,两条线都是高电平,当传输“1”时,DATA0为高,DATA1为低;当传输“0”时,DATA0为低,DATA1为高;也就是说无论传输“0”还是“1”,两条数据线上的电平都是“异或”关系,每一位数据的持续时间50-100微秒,数据间隔1-2毫秒,如下图所示:韦根数据最常见的两种形式是一次传输26位数据和一次传输34...

weixin_39603492的博客 2831

STM32实战:韦根协议收发与门禁读卡器数据解析

韦根协议是门禁、考勤等嵌入式系统中读卡器与主控通信的经典标准,通过DATA0和DATA1两根线传输位数据。其原理基于下降沿触发和位间隔超时判断,在STM32上需结合GPIO中断、定时器及数据帧解析实现。掌握韦根26/34的字段切分与校验逻辑,能有效解决中断丢失、数据截断等工程问题,广泛应用于门禁读卡、梯控等场景。本文围绕STM32平台,详细讲解韦根协议从硬件配置到二次开发的完整实现链路。

weixin_29190573的博客 141

STM32搞定韦根协议:门禁读卡器接入与模拟发送实战

在门禁系统、考勤机和电梯控制等嵌入式应用中,读卡器与控制器之间的通信往往依赖一种简单而特殊的串行协议——韦根(Wiegand)。它没有时钟线,也没有帧起始标识,仅用D0和D1两根线上的脉冲拉低动作就能完成二进制数据的传输。理解韦根的数据帧结构、校验位规则以及脉冲时序,是接收端正确解析卡号和发送端精确构造数据的基础。对于STM32开发者而言,借助外部中断捕捉下降沿、配合定时器实现超时判帧,可以稳定实现26位乃至34位、50位韦根帧的处理。无论是开发门禁控制器、考勤机固件,还是用开发板模拟卡片调试后端逻辑,掌握

weixin_29189373的博客 298

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

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

STM89C56的博客 2927

STM32韦根协议接收实战:中断、定时器与状态机避坑指南

在嵌入式系统开发中,外部中断与定时器输入捕获是处理异步信号的核心技术,其原理在于通过硬件或软件捕获边沿事件,恢复时序信息。合理运用这些机制,能显著提升信号接收的稳定性与实时性,广泛应用于门禁、考勤等身份识别场景。韦根协议作为一种无时钟线的经典接口,依赖两根数据线传输卡号,对STM32的时序恢复能力提出挑战。本文将结合中断响应、抖动过滤与状态机设计,深入解析如何从脉冲流中可靠提取韦根26/34卡号,并分享电气隔离与校验避坑经验。

weixin_29183637的博客 131

韦根(Wiegand协议)

一、概述 韦根(Wiegand协议)是国际上统一的标准,是由摩托罗拉公司制定的一种通讯协议。 韦根(Wiegand)协议又称韦根码,通俗来说是一种通信工具,用于读卡器(读头)到门禁控制器。当读卡器识别到有效卡后,将卡片的钥匙信息以韦根协议的方式传输,再而转换成数据发送给控制器,控制器验证钥匙信息有效后打开门。 简而言之,韦根协议相当于一种“传声筒”,控制器无法直接读取读头发送的信息,所以需要韦根协议进行通信,才能完成读头到控制器数据的完整传输。 值得注意的是,韦根协议只...

yangguoyu8023的博客 4万+

STM32F103韦根协议解析 (韦根数据接收实例)

STM32F103韦根协议解析 (韦根数据接收实例)

Kafka延迟队列实现方案全解析

$ \text{时间轮} = \text{环形数组} + \text{分层设计} $$需要补充代码实例或特定场景的优化方案可进一步细化,此大纲已覆盖核心技术路径。

lz989796的博客 817

韦根协议——STM32收发

最近,工作上用到了韦根,所以特此记录一下以免下次还需要查资料。

Fengziwen1的博客 4687

告别卡顿!OBS Studio最佳录制参数设置指南(适合游戏/网课/会议场景)

本文提供OBS Studio录制参数优化指南,针对游戏、网课及会议三大场景,详细解析帧率、码率与编码器设置。重点推荐利用硬件编码器(如NVENC)实现游戏录制零卡顿,并分享清晰稳定的网课录制与长时间会议录制配置方案,助你告别视频卡顿与音画不同步问题。

e4f5g6h7的博客 1335

Wiegand26协议对接安防系统报警机制

本文详解如何利用Wiegand26协议实现高效、低误报的门禁报警机制,涵盖信号采集、数据校验、报警联动及实际应用场景,展现老旧协议在现代安防中的可靠价值。

weixin_29323977的博客 753

稀疏数据分析:马蹄估计量及其理论性质

稀疏数据分析:马蹄估计量及其理论性质基本框架half-Cauchy分布为什么它叫马蹄估计量后验均值、shrinkage与κ\kappaκθ\thetaθ的边缘先验分布的阶马蹄估计的一致性收敛速率Clarke-Barron(1990)引理马蹄估计的最优收敛速率 这是对The horseshoe estimator for sparse signal这篇论文的回顾,这篇论文在Modern Bayesian statistics与Bayesian Machine Learning领域比较重要,它提出了一种新的先验

一个不愿透露姓名的博客 3799

RFSoC全面解析(八)—— ZCU111 RFSoC评估工具的上位机界面

下面的内容的参考文献为:XILINX公司文档UG1287。 XILINX公司提供了一个RFSoC的ADC/DAC性能的评估工具或者叫评估系统,这个文档就是讲如何使用这个评估工具的。 整个评估系统总的框图如上图所示,评估系统由上位机、ZCU111开发板、子卡以及网线、射频线缆组成。 ZCU111开发板内主要使用的RFSoC外设为时钟驱动和DDR4,RFSoC的PS部分和PL部分都使用了。 PS部分发挥的功能为通过网口与上位机通信,通过IIC总线控制时钟驱动芯片以及数据流控制等;PL部分发挥的功能为

4381

韦根协议

Wiegand26以及Wiegand34协议, 是由美国工业安全委员会SIA的隶属组织制定的一个关于存取控制的标准协议。非接触式IC卡读写器接口和输出,也采用了该协议标准。

headwind的博客 8329

如何免费快速的部署一个自用免VIP的自动追剧工具!NAS新玩法!豆瓣与迅雷结合,轻松实现自动下载电影自动追剧功能(支持Windows,群晖nas,飞牛nas,软路由,服务器等Docker快速部署)

追剧党狂喜!豆瓣追剧神器,自动添加云盘,自动下载,微信通知,一键搞定!

XiaoqiangClub的博客 4582

韦根协议内核驱动开发

Wiegan协议驱动开发

u014415274的博客 1582

DSPy 入门: 再见提示,你好编程

DSPy("Declarative Self-improving Language Programs (in Python)",发音为 "dee-es-pie")[1] 是斯坦福大学 NLP 研究人员开发的 "基础模型编程 "框架。它强调编程而非提示,并将构建基于 LM 的管道从操作提示转向编程。因此,它旨在解决构建基于 LM 应用程序时的脆弱性问题。DSPy 还将程序的信息流与每一步的参数(提示和 LM 权重)分离开来,为构建基于 LM 的应用程序提供了更系统的方法。

具身机器人和通用AI 3486

基于卷积神经网络的遥感图像地物分类

AI:89-基于卷积神经网络的遥感图像地物分类 基于卷积神经网络的遥感图像地物分类是一个令人兴奋的领域,它在环境监测、城市规划、农业、国防等领域具有广泛的应用。深度学习技术为我们提供了更准确、高效的工具,有望在未来进一步提高分类性能。在本文中,我们探讨了卷积神经网络的工作原理、数据准备、模型构建、训练和评估过程,并提供了多个代码示例。此外,我们讨论了地物分类的应用和挑战,以及未来的发展趋势。

一键难忘的博客 2717

ID卡和韦根协议

原文地址::http://blog.chinaunix.net/uid-26849197-id-3302874.html 相关文章 1、韦根协议----http://www.cnblogs.com/shootingstars/archive/2009/12/14/1623952.html 2、韦根协议----http://baike.baidu.com/link?url=CDbODX

xqhrs232的专栏 1万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

韦根协议简介

1.简介 Wiegand(韦根)协议是由摩托罗拉公司制定的一种通讯协议,它适用于涉及门禁控制系统的读卡器和卡片的许多特性,其协议并没有定义通讯的波特率、也没有定义数据长度韦根格式主要定义是数据传输方式:Data0和Data1两根数据线分别传输0和1,现在应用最多的是26bit,34bit,36bit,44bit等等,其中标准26-bit 格式是一个开放式的格式,任何人都可以购买某一特定格式的HI

j182010的专栏 1万+

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

韦根26和34格式怎么算数据,和开发相关知识。

韦根wiegand的算法,根据示波器去算数据位,以及韦根的相关知识

pawnxi的博客 3160

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

韦根接口,韦根34,韦根26原理介绍

1韦根接口 Wiegand接口通常由3根线组成,它们分别是:数据0(Data0),数据1(Data1)和 Data return。这3条线负责传输Wiegand信号。D0,D1在没有数据输出时都保持+5V高电平。若输出为0,则D0拉低一段时间,若输出为1,则D1拉低一段时间。两个电子卡韦根输出之间的最小间隔为0.25秒。 2、韦根34协议 Wiegand 34各数据位的含义如下: 第 1 位: 为输出第2—17位的偶校验位 第 2-17 位: ID卡的HID码 第18-33位: ID卡的PI

hktkfly6的专栏 2万+
上一篇: ARM Linux 手写实现栈回溯
下一篇: Linux iptables IP映射 跨网段访问
Chasing_Chasing
博客等级 码龄10年 233粉丝 87原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值