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

一、韦根协议原理

韦根接口在门禁行业广泛使用,是一个门禁行业的通信标准,通过两条数据线 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/442139.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(C语言)字符分类函数

目录 字符分类函数 1. iscntrl 2. isspace 3. isdigit 4. isxdigit 5. islower 6. isupper 7. isalpha 8. isalnum 9. ispunct 10. isgraph 11. isprint 字符分类函数 C语言中有一系列的函数是专门做字符分类的 &#xff0c;也就是一个字符是属于什么类型的字符的。…

二维码门楼牌管理系统技术服务:构建智慧城市新标准

文章目录 前言一、二维码门楼牌管理系统的诞生背景二、标准地址编码的定义与作用三、二维码门楼牌管理系统的核心技术四、二维码门楼牌管理系统的应用优势五、二维码门楼牌管理系统在智慧城市建设中的作用六、结论与展望 前言 随着城市化的快速发展&#xff0c;传统的门楼牌管…

通过一篇文章带你玩转git和GitHub

Git和Github的基本用法 前言一、Git和Github的基本用法背景下载安装安装 git for windows安装 tortoise gitgit安装过程中的一些选项 tortoise git汉化教程下载tortoise git汉化安装包安装tortoise git汉化安装包 三、使用 Github 创建项目注册账号创建项目下载项目到本地 四、…

GitHub会员充值

GitHub是一个基于Web的代码托管平台&#xff0c;为开发者提供了协作、版本控制和代码管理的工具。它允许个人和团队共同协作开发软件项目&#xff0c;并提供了许多功能&#xff0c;使得代码的管理和维护更加容易 版本控制系统&#xff1a; GitHub使用Git作为其版本控制系统。Gi…

两天学会微服务网关Gateway-Gateway过滤器

锋哥原创的微服务网关Gateway视频教程&#xff1a; Gateway微服务网关视频教程&#xff08;无废话版&#xff09;_哔哩哔哩_bilibiliGateway微服务网关视频教程&#xff08;无废话版&#xff09;共计17条视频&#xff0c;包括&#xff1a;1_Gateway简介、2_Gateway工作原理、3…

python界面开发 - messagebox 提示框

文章目录 1. messagebox1.1. 示例 2. Tkinter 开发3. python图形界面开发3.1. Python图形界面开发——Tkinter3.2. Python图形界面开发——PyQt3.3. Python图形界面开发——wxPython3.4. Python图形界面开发—— PyGTK&#xff1a;基于GTK3.5. Python图形界面开发—— Kivy3.6.…

【ElasticSearch】es索引、映射、文档基本操作复杂查询

各位小伙伴们大家好&#xff0c;欢迎来到这个小扎扎的ElasticSearch专栏&#xff0c;本篇博客由B战尚硅谷的ElasticSearch视频总结而来&#xff0c;鉴于 看到就是学到、学到就是赚到 精神&#xff0c;这波依然是血赚 ┗|&#xff40;O′|┛ &#x1f306; 内容速览 1 es数据格…

金现代产品方案部部长王宁,将出席“ISIG-低代码/零代码技术与应用发展峰会”

3月16日&#xff0c;第四届「ISIG中国产业智能大会」将在上海中庚聚龙酒店拉开序幕。本届大会由苏州市金融科技协会指导&#xff0c;企智未来科技&#xff08;LowCode低码时代、RPA中国、AIGC开放社区&#xff09;主办。大会旨在聚合每一位产业成员的力量&#xff0c;深入探索低…

AD1102 小封装的3.7V锂电池转干电池使用的充放电管理芯片 替代传统干电池、镍氢电池

AD1102是一款锂电池充放电管理专用芯片。充电工作时&#xff0c;可以为 3.7V锂电池进行充电&#xff0c;电流最高可配置 1A。放电工作时&#xff0c;采用开关频率1MHz同步降压转换器进行放电&#xff0c;放电电流可以达到 3A。内部集成欠压保护、短路保护、过温保 护功能。 …

算法学习06:数组模拟:单/双链表,栈和队列,单调栈/队列

算法学习06&#xff1a;数组模拟&#xff1a;单/双链表&#xff0c;栈和队列&#xff0c;单调栈/队列 文章目录 算法学习06&#xff1a;数组模拟&#xff1a;单/双链表&#xff0c;栈和队列&#xff0c;单调栈/队列前言一、链表1.单链表2.双链表 二、栈和队列1.普通栈、队列2.单…

LeetCode Python - 42.接雨水

目录 题目答案运行结果 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组…

Maven基础简介

作者简介&#xff1a; zoro-1&#xff0c;目前大二&#xff0c;正在学习Java&#xff0c;数据结构&#xff0c;spring等 作者主页&#xff1a; zoro-1的主页 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f496; Maven简介 Maven是什么 Maven…

人工智能|机器学习——Canopy聚类算法(密度聚类)

1.简介 Canopy聚类算法是一个将对象分组到类的简单、快速、精确地方法。每个对象用多维特征空间里的一个点来表示。这个算法使用一个快速近似距离度量和两个距离阈值T1 > T2 处理。 Canopy聚类很少单独使用&#xff0c; 一般是作为k-means前不知道要指定k为何值的时候&#…

Java的Writer类详解

咦咦咦&#xff0c;各位小可爱&#xff0c;我是你们的好伙伴——bug菌&#xff0c;今天又来给大家普及Java SE相关知识点了&#xff0c;别躲起来啊&#xff0c;听我讲干货还不快点赞&#xff0c;赞多了我就有动力讲得更嗨啦&#xff01;所以呀&#xff0c;养成先点赞后阅读的好…

【xv6操作系统】Lec06 Isolation system call entry/exit

6.1 Trap机制 每当 1.程序执行系统调用 2.程序出现了类似page fault、运算时除以0的错误 3.一个设备触发了中断使得当前程序运行需要响应内核设备驱动 都会发生用户空间和内核空间的切换&#xff0c;通常被称为trap。trap机制要尽可能的简单。 Shell可能会执行系统调用&a…

多种方法解决Error: could not open `C:Program FilesJavajre1.8.0_311libamd64jvm.cfg‘

文章目录 1. 复现错误2. 分析错误3. 解决错误4. 补充说明1. 复现错误 今天春节后开工第一天,打开我的IDEA,却报出如下错误: 报错信息是找不到JRE,于是,通过Windows Powershell输入Java -version,如下图所示: 即Error: could not open C:\Program Files\Java\jre1.8.0_31…

外包干了5天,技术退步明显。。。。。

在湖南的一个安静角落&#xff0c;我&#xff0c;一个普通的大专生&#xff0c;开始了我的软件测试之旅。四年的外包生涯&#xff0c;让我在舒适区里逐渐失去了锐气&#xff0c;技术停滞不前&#xff0c;仿佛被时间遗忘。然而&#xff0c;生活的转机总是在不经意间降临。 与女…

7. 镜面网格

E . 镜面网格 E.镜面网格 E.镜面网格 每次测试时限&#xff1a; 2 秒 每次测试时限&#xff1a;2 秒 每次测试时限&#xff1a;2秒 每次测试的内存限制&#xff1a; 256 兆字节 每次测试的内存限制&#xff1a;256 兆字节 每次测试的内存限制&#xff1a;256兆字节 题目描述 给…

JavaScript极速入门-综合案例(3)

综合案例 猜数字 预期效果 代码实现 <button type"button" id"reset">重新开始一局游戏</button><br>请输入要猜的数字:<input type"text" id"number"><button type"button" id"button&q…

Swift SwiftUI 学习笔记 2024

Swift SwiftUI 学习笔记 2024 一、资源 视频资源 StanfordUnivercity 公开课 2023: https://cs193p.sites.stanford.edu/2023 教程 Swift 初识&#xff1a;基础语法&#xff1a;https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/…