51单片机使用rc522的rfid读卡程序
时间: 2023-09-29 07:09:50 浏览: 207
以下是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
阅读全文