51单片机+rc522实现简单的读卡功能
时间: 2023-05-16 08:01:16 浏览: 347
51单片机是一种常用的微控制器,RC522则是一种低功率的射频接口芯片,主要用于RFID(Radio Frequency Identification,射频识别)读写操作。利用51单片机和RC522可以实现简单的读卡功能。
读卡功能即将RFID读头接近卡片,通过射频信号与卡片进行通讯,读取卡片内储存的信息。实现该功能的步骤如下:
1. 初始化RC522模块:将51单片机与RC522进行串口通讯,初始化RC522,包括寻卡、选卡等操作。
2. 寻卡:通过RC522模块向周围发射射频信号,寻找附近的RFID卡片。
3. 选卡:找到附近的卡片后,RC522会自动进行选卡操作,将工作频率与卡片频率进行匹配。如果匹配成功,则可以进行数据传输。
4. 读取数据:读取卡片内储存的信息,并将其解析为可读性的数据。读取的数据可以用于控制设备的开关,实现门禁系统、电子钱包等功能。
需要注意的是,在进行读卡操作时需要保证射频接口与卡片之间的距离不要过远,否则会影响读取效果。此外还需要对读卡信息的安全性进行保护,避免遭遇信息泄露的风险。
总之,51单片机rc522实现简单的读卡功能并不困难,只需要按照上述步骤进行操作即可。但是对于复杂的读卡系统,还需要进一步的研究和安全保护措施。
相关问题
51单片机使用rc522的rfid读卡程序
以下是51单片机通过RC522读取RFID卡片的示例代码:
```c
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit led = P1^0; //定义LED灯引脚
sbit beep = P1^5; //定义蜂鸣器引脚
sbit SDA = P1^6; //连接RC522模块的SDA引脚
sbit SCK = P1^5; //连接RC522模块的SCK引脚
sbit MOSI = P1^7; //连接RC522模块的MOSI引脚
sbit MISO = P1^4; //连接RC522模块的MISO引脚
sbit RST = P1^3; //连接RC522模块的RST引脚
uchar cardid[5]; //存放读到的卡号
//延时函数
void delay(uint i)
{
while (i--);
}
//写RC522寄存器
void Write_MFRC522(uchar addr, uchar val)
{
SDA = 0;
SCK = 0;
for (int i=0;i<8;i++)
{
SDA = (addr<<1)&0x80;
SCK = 1;
SCK = 0;
addr <<= 1;
}
for (int i=0;i<8;i++)
{
SDA = (val<<1)&0x80;
SCK = 1;
SCK = 0;
val <<= 1;
}
SDA = 1;
}
//读RC522寄存器
uchar Read_MFRC522(uchar addr)
{
uchar val = 0;
SDA = 0;
SCK = 0;
for (int i=0;i<8;i++)
{
SDA = (addr<<1)&0x80;
SCK = 1;
SCK = 0;
addr <<= 1;
}
SDA = 1;
for (int i=0;i<8;i++)
{
val <<= 1;
SCK = 1;
SCK = 0;
if (MISO)
val |= 0x01;
}
return val;
}
//复位RC522
void MFRC522_Init()
{
Write_MFRC522(0x01, 0x0F); //复位
Write_MFRC522(0x2A, 0x8D); //开启天线
Write_MFRC522(0x2B, 0x3E); //天线增益
Write_MFRC522(0x2D, 0x30); //信号强度调节
Write_MFRC522(0x2C, 0); //关闭M1卡片检测
}
//寻卡
uchar MFRC522_Request(uchar reqMode, uchar *TagType)
{
uchar status;
uint backBits;
Write_MFRC522(0x0D, 0x07); //寻卡
TagType[0] = reqMode;
status = MFRC522_ToCard(0x0E, TagType, 1, TagType, &backBits);
if ((status != 0) || (backBits != 0x10))
status = 1;
return status;
}
//防冲突
uchar MFRC522_Anticoll(uchar *serNum)
{
uchar status;
uchar i;
uchar serNumCheck = 0;
uint unLen;
Write_MFRC522(0x0D, 0x0C); //防冲突
Write_MFRC522(0x0E, 0x80);
status = MFRC522_ToCard(0x0F, serNum, 1, serNum, &unLen);
if (status == 0)
{
for (i=0;i<4;i++)
serNumCheck ^= serNum[i];
if (serNumCheck != serNum[i])
status = 1;
}
return status;
}
//选择卡片
uchar MFRC522_SelectTag(uchar *serNum)
{
uchar i;
uchar status;
uchar size;
uint recvBits;
uchar buffer[9];
buffer[0] = 0x93;
buffer[1] = 0x70;
for (i=0;i<5;i++)
{
buffer[i+2] = serNum[i];
buffer[7] ^= buffer[i+2];
}
MFRC522_CalculateCRC(buffer, 8, &buffer[8]);
status = MFRC522_ToCard(0x0C, buffer, 9, buffer, &recvBits);
if ((status == 0) && (recvBits == 0x18))
size = buffer[0];
else
size = 0;
return size;
}
//验证卡片密码
uchar MFRC522_Auth(uchar authMode, uchar addr, uchar *key, uchar *serNum)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[12];
buff[0] = authMode;
buff[1] = addr;
for (i=0;i<6;i++)
buff[i+2] = key[i];
for (i=0;i<4;i++)
buff[i+8] = serNum[i];
status = MFRC522_ToCard(0x0E, buff, 12, buff, &recvBits);
if ((status != 0) || (!(Read_MFRC522(0x09) & 0x08)))
status = 1;
return status;
}
//读取数据
uchar MFRC522_Read(uchar addr, uchar *data)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[6];
buff[0] = 0x30;
buff[1] = addr;
MFRC522_CalculateCRC(buff, 2, &buff[2]);
status = MFRC522_ToCard(0x0C, buff, 4, buff, &recvBits);
if ((status == 0) && (recvBits == 0x90))
{
for (i=0;i<16;i++)
data[i] = Read_MFRC522(0x01);
}
else
status = 1;
return status;
}
//写入数据
uchar MFRC522_Write(uchar addr, uchar *data)
{
uchar status;
uint recvBits;
uchar i;
uchar buff[18];
buff[0] = 0xA0;
buff[1] = addr;
MFRC522_CalculateCRC(buff, 2, &buff[2]);
status = MFRC522_ToCard(0x0C, buff, 4, buff, &recvBits);
if ((status == 0) && (recvBits == 0x90))
{
for (i=0;i<16;i++)
Write_MFRC522(0x01, data[i]);
}
else
status = 1;
return status;
}
//计算CRC16
void MFRC522_CalculateCRC(uchar *data, uchar length, uchar *result)
{
uchar i;
Write_MFRC522(0x22, 0x21);
Write_MFRC522(0x23, length);
MFRC522_ToCard(0x25, data, length, result, &i);
}
//与卡片通信
uchar MFRC522_ToCard(uchar cmd, uchar *sendData, uchar sendLen, uchar *backData, uint *backLen)
{
uchar status = 1;
uchar irqEn = 0x00;
uchar waitIRq = 0x00;
uchar lastBits;
uint i;
switch (cmd)
{
case 0x0C:
irqEn = 0x12;
waitIRq = 0x10;
break;
case 0x0E:
irqEn = 0x77;
waitIRq = 0x30;
break;
case 0x0D:
irqEn = 0x77;
waitIRq = 0x30;
break;
default:
break;
}
Write_MFRC522(0x02, irqEn|0x80);
ClearBitMask(0x04, 0x80);
Write_MFRC522(0x01, 0x00);
Write_MFRC522(0x09, 0x00);
if (sendData != 0)
Write_MFRC522(0x09, sendLen);
Write_MFRC522(0x1D, waitIRq);
SetBitMask(0x01, 0x80);
for (i=0;i<sendLen;i++)
Write_MFRC522(0x01, sendData[i]);
Write_MFRC522(0x01, cmd);
if (cmd == 0x0C)
SetBitMask(0x0D, 0x80);
i = 2000; //等待时间
while (1)
{
lastBits = Read_MFRC522(0x0C);
if ((lastBits & 0x07) != 0)
break;
if (i == 0)
break;
i--;
}
if (i != 0)
{
if ((Read_MFRC522(0x06) & 0x1B) == 0x00)
{
status = 0;
if (backData != 0)
{
*backLen = Read_MFRC522(0x07);
if (*backLen > 0)
{
for (i=0;i<*backLen;i++)
backData[i] = Read_MFRC522(0x09);
}
}
if ((lastBits & 0x08) == 0)
status = 1;
}
}
ClearBitMask(0x01, 0x80);
Write_MFRC522(0x0D, 0x00);
return status;
}
//清除某位
void ClearBitMask(uchar addr, uchar mask)
{
uchar tmp = Read_MFRC522(addr);
Write_MFRC522(addr, tmp & (~mask));
}
//设置某位
void
51单片机rc522rfid读卡程序
以下是基于51单片机和RC522模块的RFID读卡程序:
```c
#include<reg52.h>
#include<rc522.h>
#define uchar unsigned char
#define uint unsigned int
uchar code tabel[16] = {0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
uchar cardid[5];
uchar i;
init_rc522();
while(1)
{
if(search_card(0x01,cardid)==0)
{
if(antiblock(cardid)==0)
{
for(i=0;i<4;i++) write_data(0x08+i,cardid[i]); //将卡号写入扇区0
write_data(0x3,0x40); //将扇区0设置为密码验证模式
write_data(0x7,0xff); //将密码设置为全F
while(search_card(0x01,cardid)==0); //等待卡离开
}
}
}
}
```
说明:
- `init_rc522()`:初始化RC522模块。
- `search_card(0x01,cardid)`:搜索并读取RFID卡,返回值为0表示成功。
- `antiblock(cardid)`:检查卡是否已被写入卡号,返回值为0表示未被写入卡号。
- `write_data(0x08+i,cardid[i])`:将卡号写入扇区0。
- `write_data(0x3,0x40)`:将扇区0设置为密码验证模式。
- `write_data(0x7,0xff)`:将密码设置为全F。
注意:以上代码仅供参考,具体实现还需要根据自己的需求进行修改。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)