51单片机rfid-rc522读卡器
时间: 2023-09-04 07:15:55 浏览: 211
51单片机可以通过SPI接口与RFID-RC522读卡器进行通信,实现读取RFID卡片信息的功能。以下是一个简单的代码示例:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit SDA = P1^0; //SDA引脚
sbit SCK = P1^1; //SCK引脚
sbit CS = P1^2; //CS引脚
uchar Read_MFRC522(uchar addr)
{
uchar val;
CS = 0; //拉低片选信号
SCK = 0; //拉低时钟信号
SDA = ((addr<<1)&0x7E)|0x80; //发送地址+读命令
SCK = 1; //拉高时钟信号
val = SDA; //读取数据
SCK = 0; //拉低时钟信号
CS = 1; //拉高片选信号
return val;
}
void Write_MFRC522(uchar addr, uchar val)
{
CS = 0; //拉低片选信号
SCK = 0; //拉低时钟信号
SDA = (addr<<1)&0x7E; //发送地址+写命令
SCK = 1; //拉高时钟信号
SDA = val; //发送数据
SCK = 0; //拉低时钟信号
CS = 1; //拉高片选信号
}
void Init_MFRC522()
{
Write_MFRC522(0x01, 0x0F); //复位RC522
Write_MFRC522(0x2A, 0x8D); //开启天线
Write_MFRC522(0x2B, 0x3E); //调节天线增益
Write_MFRC522(0x2D, 0x30); //调节信号充放电时间
Write_MFRC522(0x2C, 0); //清空内部缓冲区
}
uchar Request_MFRC522(uchar reqMode, uchar *TagType)
{
uchar status;
uint backBits;
Write_MFRC522(0x0D, 0x01); //将CRC计算器初始值设为0x01
TagType[0] = reqMode;
status = RC522_ToCard(0x0C, TagType, 1, TagType, &backBits);
if ((status != 0) || (backBits != 0x10))
status = 1;
return status;
}
uchar RC522_ToCard(uchar cmd, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
{
uchar status = 0;
uchar irqEn = 0x00;
uchar waitIRq = 0x00;
uchar lastBits;
uchar n;
uint i;
switch (cmd)
{
case 0x0C:
irqEn = 0x77;
waitIRq = 0x30;
break;
}
Write_MFRC522(0x02, irqEn | 0x80);
Write_MFRC522(0x04, waitIRq | 0x80);
Write_MFRC522(0x01, 0x00);
Write_MFRC522(0x0D, 0x00);
if (sendData != NULL)
{
Write_MFRC522(0x09, sendLen);
Write_MFRC522(0x08, 0x02);
for (i = 0; i < sendLen; i++)
Write_MFRC522(0x09, sendData[i]);
}
Write_MFRC522(0x01, cmd);
if (cmd == 0x0C)
Write_MFRC522(0x0E, 0x80);
i = 2000;
while (1)
{
n = Read_MFRC522(0x04);
i--;
if ((i == 0) || (n & 0x01))
break;
}
if (i == 0)
return 1;
n = Read_MFRC522(0x06);
if (n & 0x30)
return 2;
if (cmd == 0x0C)
{
lastBits = Read_MFRC522(0x05) & 0x07;
if (lastBits != 0)
*backLen = (backBits - 1) * 8 + lastBits;
else
*backLen = backBits * 8;
if (backBits == 0)
backBits = 1;
if (backBits > 16)
backBits = 16;
for (i = 0; i < backBits; i++)
backData[i] = Read_MFRC522(0x09);
}
return status;
}
uchar Anticoll_MFRC522(uchar *serNum)
{
uchar status;
uchar i;
uchar serNumCheck = 0;
uint unLen;
Write_MFRC522(0x0D, 0x00);
serNum[0] = 0x93;
serNum[1] = 0x20;
status = RC522_ToCard(0x93, serNum, 2, serNum, &unLen);
if (status == 0)
{
for (i = 0; i < 4; i++)
serNumCheck ^= serNum[i];
if (serNumCheck != serNum[i])
status = 1;
}
return status;
}
void main()
{
uchar i;
uchar status;
uchar str[MAX_LEN];
uchar RC_size;
uchar RC_data[MAX_LEN];
Init_MFRC522();
while (1)
{
status = Request_MFRC522(0x52, str);
if (status == 0)
status = Anticoll_MFRC522(str);
if (status == 0)
{
for (i = 0; i < 4; i++)
printf("%02X", str[i]);
printf("\n");
}
}
}
```
该代码中定义了一些常用的宏和变量,如SDA、SCK和CS引脚的定义,以及读取和写入数据的函数。在主函数中,首先初始化RC522读卡器,然后在循环中不断尝试读取RFID卡片的信息,如果成功读取到卡片信息,则将卡片ID输出到串口。需要注意的是,这里只演示了读取RFID卡片ID的功能,如果需要读取更多的卡片信息(如卡片类型、卡片数据等),需要根据RC522读卡器的数据手册进行相应的配置和操作。
阅读全文