文章目录
- 一、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);//延时
}
}