RFID高频读写器在STM32中的应用

news2025/1/17 22:05:11

文章目录

  • 一、RFID简述
  • 二、产品参数及硬件连接
  • 三、模块测试
  • 四、RFID读写操作
  • 五、项目源码


一、RFID简述

在这里插入图片描述
RFID是Radio Frequency Identification的缩写,是一种无接触自动识别技术,利用射频信号及其空间耦合传输特性,实现对静止的或移动中的待识别物品的自动识别 。RFID系统则由两个部分组成,即电子标签和阅读器。

阅读器是将标签中的信息读出,或将标签所需要存储的信息写入标签的装置。根据使用的结构和技术不同,阅读器可以是读/写装置,是RFID系统信息控制和处理中心。阅读器 (问答器) 可放置在一固定地点,如:入口/出口,销售网点、仓库、货栈、大商场;阅读器同样可在移动的范围中使用。

电子标签由收发天线、AC/DC电路、解调电路、逻辑控制电路、存储器和调制电路组成。分为无源电子标签-passive tag,对应无源RFID系统;半无源电子标签-semi-passive tag,对应于半无源RFID系统;有源电子标签—active tag,对应于有源RFID系统;

工作原理
RFID技术的基本工作原理并不复杂:在标签进入磁场后,接收解读器发出的射频信号,凭借感应电流所获得的能量发送出存储在芯片中的产品信息,或者主动发送某一频率的信号;解读器读取信息并解码后,发送至中央信息系统进行有关数据处理。

一套完整的RFID系统,是由阅读器与电子标签也就是所谓的应答器及应用软件系统三个部份所组成,其工作原理是阅读器发射一特定频率的无线电波能量给应答器,用以驱动应答器电路将内部的数据送出,此时阅读器便依序接收解读数据,送给应用程序做相应的处理。

以RFID卡片阅读器及电子标签之间的通讯及能量感应方式来看大致上可以分成,感应偶合(InductiveCoupling)及后向散射偶合(BackscatterCoupling)两种,一般低频的RFID大都采用第一种式。

RFID主要应用领域:

  • 门禁、考勤控制
  • 现代物流
  • 交通领域
  • 产品装配线
  • 身份识别

二、产品参数及硬件连接

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
与单片机直接连接采用UART TTL接口,模块的TXD引脚接单片机RXD引脚,模块的RXD引脚接单片机TXD引脚,GND与单片机的GND相连形成共地,需3.3-5V电源给模块供电。
在这里插入图片描述

三、模块测试

在这里插入图片描述

四、RFID读写操作

本篇对RFID模块的应用为:通过串口俩者进行通信,由开发板通过串口发送指定指令读取到 卡片ID号,并将卡片号显示在oled显示屏上,然后通过向RFID模块发送 写入块命令,将指定数据写入缓存区中,再向RFID模块发送读块命令,将缓存区中的数据读出来,一并显示在液晶显示屏上。

读IC卡ID号(卡号)

//ReadId():读IC卡ID号(卡号)
//参数:*idout,读取的卡号保存到它所指向的存储空间
//返回值:0:成功读取卡号,1:读卡号失败
unsigned char ReadId(unsigned char *idout)
{
	unsigned char status;
	unsigned char i;
	Cmd_Read_Id[5] = 0x01;//开启蜂鸣器提示
	//Cmd_Read_Id[5] = 0x00;//关闭蜂鸣器提示
	TxCheckSum(Cmd_Read_Id,Cmd_Read_Id[1]);		//计算校验和
	Uart2_Send_Data(Cmd_Read_Id,Cmd_Read_Id[1]);		 //发送读卡号ID命令
	Delay(1600000);//等待模块返回数据,大于150MS
 	if(Rx2Flag == 1)
 	{	
		Rx2Flag = 0;
		status = RxCheckSum(Uart2RxBuf,Uart2RxBuf[1]);//对接收到的数据校验
		if(status != STATUS_OK)  //判断校验和是否正确
		{
			return STATUS_ERR;
		}
		
		status = Uart2RxBuf[4];
		if(status != STATUS_OK)	//判断是否正确的读到卡
		{
		 	return STATUS_ERR;
		}
		
		if((Uart2RxBuf[0] == 0x01)&&(Uart2RxBuf[2] == 0xa1))//判断是否为读卡号返回的数据包
		{
			
			for(i=0;i<6;i++)//获取卡号ID,6字节		 
			{
				idout[i] = Uart2RxBuf[i+5];//从数组的第5个字节开始为卡号,长度为6字节
				uint32_t Number=Uart2RxBuf[5+i];
				OLED_ShowHexNum(1,2+2*i,Number,2);
			}
			return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;			//失败返回1
}

读IC卡数据块

//ReadDataFromBlock():读IC卡数据块
//参数:*dataout,读取的数据保存到它所指向的存储空间
//参数:block,块号
//返回值:0:成功读取,1:读读取失败
unsigned char ReadDataFromBlock(unsigned char *dataout,unsigned char block)
{
	unsigned char status;
	unsigned char i;
	Cmd_Read_Block[4] = block;
	Cmd_Read_Block[5] = 0x01;//开启蜂鸣器提示
//	Cmd_Read_Block[5] = 0x00;//关闭蜂鸣器提示
	TxCheckSum(Cmd_Read_Block,Cmd_Read_Block[1]);	//数据校验
	Uart2_Send_Data(Cmd_Read_Block,Cmd_Read_Block[1]);		 //发送读数据块命令
	Delay(1600000);//等待模块返回数据,大于150MS
 	if(Rx2Flag == 1)
 	{	
		Rx2Flag = 0;
		status = RxCheckSum(Uart2RxBuf,Uart2RxBuf[1]);//对接收到的数据校验
		if(status != STATUS_OK)		 //判断校验和是否正确
		{
			return 	STATUS_ERR;
		}
		status = Uart2RxBuf[4];		//获取返回包状态
		if(status != STATUS_OK)	//判断是否正确的读到卡
		{
			return STATUS_ERR;
		}
		if((Uart2RxBuf[0] == 0x01)&&(Uart2RxBuf[2] == 0xa3))//判断是否为读块数据返回的数据包
		{
			for(i=0;i<16;i++)//获取块数据,16字节	,一个数据块的大小为16字节	 
			{
				dataout[i] = Uart2RxBuf[i+5];//从数组的第5个字节开始为数据,长度为16字节
			}
			return STATUS_OK;		 //成功返回0
		}
	}
	return STATUS_ERR;			//失败返回1
}

写数据到指定的数据块

//WriteDataToBlock():写数据到指定的数据块
//参数:*datain,指向要写入数据的缓冲区
//参数:block,块号
//返回值:0:写入成功,1:写入失败
unsigned char WriteDataToBlock(unsigned char *datain,unsigned char block)
{
	unsigned char status;
	unsigned char i;
	Cmd_Write_Block[4] = block;
	for(i=0;i<16;i++)
	{
		Cmd_Write_Block[6+i] = datain[i];
	}
	TxCheckSum(Cmd_Write_Block,Cmd_Write_Block[1]);	//数据校验
	Uart2_Send_Data(Cmd_Write_Block,Cmd_Write_Block[1]);		 //发送写命令
	Delay(1600000);//等待模块返回数据,大于150MS
 	if(Rx2Flag == 1)
 	{	
		Rx2Flag = 0;
		status = RxCheckSum(Uart2RxBuf,Uart2RxBuf[1]);//对返回的数据进行校验
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		status = Uart2RxBuf[4];
		if(status != STATUS_OK) //判断校验是否通过
		{
			return STATUS_ERR;
		}
		if((Uart2RxBuf[0] == 0x01)&&(Uart2RxBuf[2] == 0xa4))//判断是否为写块数据返回的数据包
		{
				return STATUS_OK;		 //成功返回0
		}
 	} 
	return STATUS_ERR;			//失败返回1
}

main()函数

int main(void)
{	
	OLED_Init();
	
	//串口2连接读卡器
	//串口1连接上位机
	unsigned char status;
	unsigned char id[6];
	unsigned char blockdata[16];
	LED_Init();
	SystemInit();					//初始化系统
	NVIC_Configuration(); //初始化相关中断
	COM1_2_Init();  //初始化UART1,UART2

	Rx1Flag = 1;
	Rx2Flag = 1;
	Uart1RxDataConut = 0;
	Uart2RxDataConut = 0;
	while(1)
	{
		
/*************调用读卡号函数ReadId()将卡号ID读入到指定的缓冲区id中************************************/	
		status = ReadId(id);  //读卡号
		if(status == STATUS_OK)	//判断读卡号是否成功,等于0成功
		{
			LED0=LED_ON;
			Uart1_Send_Data(id,6);	//从串口1把读取到的卡号发送出去
			
		}
		else
		{
			//OLED_ShowString(1, 2, "read error!");
			;//LED1=LED_ON;//错误处理
		}

/*********************************************************************************************************/
	//	Delay(20000000);//延时
/*************调用写函数WriteDataToBlock()将指定缓冲区WBlockData的数据写入到指定的块中*****************/
		status = WriteDataToBlock(WBlockData,2);  //把数组WBlockData[]中的数据写入指定块,这里写入到
	
		
		if(status == STATUS_OK)		 //判读是否写入正确	,等于0成功
		{
			OLED_ShowString(2, 2, "write ok!");//写入正确处理
		}
		else
		{
			//OLED_ShowString(2, 2, "write error!");//错误处理
		}
/*********************************************************************************************************/
		//Delay(20000000);//延时
/*************调用读块函数ReadDataFromBlock()将指定的块中的数据读入到指定的缓冲区blockdata中************/
		status = ReadDataFromBlock(blockdata,2);	 //读块2的数据到数组blockdata[]中
		if(status == STATUS_OK)	 //判断是否读取成功	,等于0成功
		{
					for(int i=0;i<5;i++)
				{
					uint32_t Number1=WBlockData[i];
					OLED_ShowHexNum(3,2+2*i,Number1,2);
				}	
			
			Uart1_Send_Data(blockdata,16);	 //从串口1把块2中读到的数据的数据发送出去
			OLED_ShowString(4, 2, "read ok!");
		}
		else
		{
			;//错误处理
		}
/*********************************************************************************************************/
		Delay(20000000);//延时
	}	 
}

在这里插入图片描述

五、项目源码

若需程序源码可在评论区留言QQ邮箱 或 直接私信即可。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

不懂命令, 如何将代码托管到Gitee上

1.注册码云注册地址 : https://gitee.com2. 新建仓库第一步 : 创建仓库第二步 : 给仓库起名字创建好仓库后, 我们就有了一个网络上的仓库 : 3. 将网络上的仓库克隆到本地在克隆仓库之前, 我们需要先在电脑上安装以下两个工具 >>这两个软件一定要按顺序安装, 先安装第一个…

Mybatis动态sql语句foreach中拼接正则表达式字符串注意事项

今天要说到的查询情况&#xff0c;平时项目里边其实用到的并不是很多&#xff0c;使用正则表达式无非是为了匹配结果比较灵活&#xff0c;最常见的&#xff0c;我们的查询条件一般一个参数仅仅只是一种情况的筛选&#xff0c;对于如何选择查询方式&#xff0c;主要还是要看前端…

博通仍然是美股市场最好的芯片半导体股

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 博通(AVGO)是一家快速增长的半导体公司&#xff0c;并且有很高的股息分红&#xff0c;目前其股息收益率已经高出了平均水平3.2%&#xff0c;而且估值非常合理&#xff0c;仅为预期净利润的14倍。 虽然博通也受到了经济衰退影…

One UI 5.1 更新来了

之前一直在关注One UI 5.0里提到的视频通话背景功能模块&#xff0c;结果5.0版本推送的时候没有引入&#xff0c;有先行者计划博主说是5.1里肯定会有的&#xff1b;前一两天One UI 5.1更新来了&#xff0c;然而该功能还是没有引入&#xff0c;表示很遗憾&#xff1b;本次更新新…

[媒体分流直播]媒体直播和传统直播的区别,以及媒体直播的特点

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 直播毋庸置疑已经融入到了我们生活的方方面面&#xff0c;小到才艺&#xff0c;游戏&#xff0c;大到政策的发布&#xff0c;许多企业和机构也越来越重视直播&#xff0c;那么一场活动怎…

「ABAP」OPEN SQL中FROM语句超详细解析(附案例源码解读)

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读&#xff0c;同时任汉硕云&#xff08;广东&#xff09;科技有限公司ABAP开发顾问。在学习工作中&#xff0c;我通常使用偏后…

剑指offer:在排序数组中查找数字I的个数

剑指offer&#xff1a;在排序数组中查找数字I的个数 LeetCode 2698题&#xff0c;剑指offer 53题。 击败100%的用户 题目描述 统计一个数字在排序数组中出现的次数。 示例 1: 输入: nums [5,7,7,8,8,10], target 8 输出: 2示例 2: 输入: nums [5,7,7,8,8,10], target…

模电基础(1) 半导体基础知识

基本内容&#xff1a; 1.本征半导体的基本介绍结构&#xff1b; 2.杂质半导体&#xff1b; 3.PN结的形成&#xff1b; 4.PN结的性质。 1.本征半导体 半导体&#xff1a;导电性能介于绝缘体和导体之间的物质。 本征半导体是纯净的晶体结构的半导体。 纯净→无杂质晶体结构→稳…

代码随想录中:回溯算法的基础

回溯算法是一种暴力的搜索方式&#xff1b;回溯法一般与递归同时存在。 回溯法&#xff0c;一般可以解决如下几种问题&#xff1a; 组合问题&#xff1a;N个数里面按一定规则找出k个数的集合切割问题&#xff1a;一个字符串按一定规则有几种切割方式子集问题&#xff1a;一个…

SpringBoot 集成 RabbitMQ

SpringBoot 集成 RabbitMQ 1.应用实例 需求说明/图解 -P : 消息的发送者/生产者 -C : 消息的接受者/消费者 -中间表示队列 完成步骤 添加依赖 <!--rabbitmq-需要的 AMQP 依赖--> <dependency><groupId>org.springframework.boot</groupId><art…

python判断控制语句和输出练习

作业2&#xff1a;判断一个数&#xff0c;是否是2的指数 2的指数 0000 0010 0000 0001 0000 0100 0000 0011 0000 1000 0000 0111 0001 0000 0000 1111 提示&#xff1a;所有2的指数&#xff1a;n&(n - 1) 0 作业3&#xff…

【spring】spring5特性

1、整个 Spring5 框架的代码基于 Java8&#xff0c;运行时兼容 JDK9&#xff0c;许多不建议使用的类和方 法在代码库中删除 日志框架 2、Spring 5.0 框架自带了通用的日志封装 &#xff08;1&#xff09;Spring5 已经移除 Log4jConfigListener&#xff0c;官方建议使用 Log4j…

Linux23 --- 三次握手四次挥手、客户端编程流程代码、命令netstat、 tcp协议是个面向链接的可靠的流式服务

tcp协议特点&#xff1a; 面向连接的&#xff0c;可靠的&#xff0c;流式服务。 一、三次握手 、四次挥手 链接的建立通过三次握手&#xff0c;链接的断开通过四次挥手 1、TCP固定头部结构 2、三次握手 3、四次挥手 二、命令 - netstat -natp n - 用数字来表示ip地址、端口…

【8】【用户操作日志】操作日志SpringBootStarter

操作日志 此版本操作日志主要就是通过AOP拦截器实现的&#xff0c;整体主要分为AOP拦截器、自定义函数、日志上下文、扩展接口&#xff1b;组件提供了6个扩展点&#xff0c;自定义函数、日志上下文、用户信息获取&#xff0c;日志保存&#xff0c;自定义异常获取&#xff0c;入…

2023王道考研数据结构笔记第四章串

第四章 串 4.1 串的定义 4.1.1 串的相关概念 串&#xff1a;即字符串&#xff08;String&#xff09;是由零个或多个字符组成的有限序列。一般记为S‘a1a2…an’ (n>0) 其中S是串名&#xff0c;单引号&#xff08;注&#xff1a;有的地方用双引号&#xff0c;如Java、C&am…

4. Unity之文件资源和其它杂项

1. 资源文件 unity中的Assets文件夹下的文件都可以称为时资源文件&#xff0c;包括模型文件、材质文件、纹理贴图文件、脚本文件、音频文件等&#xff0c;如果想查看某一个文件在电脑中的保存路径&#xff0c;可以选中指定文件后&#xff0c;单击鼠标右键选择show in Explorer…

研究生退税的详细流程

本文介绍在个人所得税软件中&#xff0c;进行退税操作的详细流程。 又到了一年一度的退税时间了。作为研究生&#xff0c;由于每个月都有固定的工资&#xff0c;有时还会有导师发放的补助、国家或院校等发放的奖学金等收入&#xff0c;所以其中有时需要缴纳一部分税款&#xff…

vue-template-admin的keep-alive缓存与移除缓存

一&#xff0c;场景 A页面是表单页面&#xff0c;填写后需要跳转B页面。如果B页面不操作返回的话&#xff0c;应该能还原A页面的内容&#xff0c;而如果B页面点击提交&#xff0c;再回到A页面的时候&#xff0c;应该清除缓存。 二&#xff0c;实现方法 A页面要缓存数据&…

网络互连模型:OSI 七层模型

OSI 七层模型 七层模型&#xff0c;亦称 OSI&#xff08;Open System Interconnection&#xff09;。OSI 七层参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间网络互联的标准体系&#xff0c;一般称为 OSI 参考模型或七层模型。OSI 七层…

询问new bing关于android开发的15个问题(前景、未来、发展方向)

前言&#xff1a;new bing是基于chat-gpt的新搜索工具&#xff0c;可以采用对话方式进行问题搜索&#xff0c;经过排队等候终于可以使用new bing&#xff0c;询问了目前我最关心的关于android开发几个问题 文章目录1.如何学好android开发&#xff1f;2.android开发能做什么?3.…