用单片机与RC522模块通信读卡
发布网友
发布时间:2022-04-23 07:29
我来回答
共1个回答
热心网友
时间:2022-06-17 16:53
/////////////////////////////////////////////////////////////////////
//功 能:通过RC522和ISO14443卡通讯
//参数说明:Command[IN]:RC522命令字
// pInData[IN]:通过RC522发送到卡片的数据
// InLenByte[IN]:发送数据的字节长度
// pOutData[OUT]:接收到的卡片返回数据
// *pOutLenBit[OUT]:返回数据的位长度
/////////////////////////////////////////////////////////////////////
char PcdComMF522(unsigned char Command,unsigned char *pInData,unsigned char InLenByte,
unsigned char *pOutData, unsigned int *pOutLenBit)
{
char status = MI_ERR;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char lastBits;
unsigned char n;
unsigned int i;
switch (Command)
{
case PCD_AUTHENT:
irqEn = 0x12;
waitFor = 0x10;
break;
case PCD_TRANSCEIVE: //发送并接收数据?
irqEn = 0x77;
waitFor = 0x30;
break;
default:
break;
}
WriteRawRC(ComIEnReg,irqEn|0x80); //容许除定时器中断请求以为得所有中断请求
ClearBitMask(ComIrqReg,0x80); //屏蔽位清除
WriteRawRC(CommandReg,PCD_IDLE); //取消当前命令?
SetBitMask(FIFOLevelReg,0x80); //清除FIFO中的读写指针
for (i=0; i<InLenByte; i++)
{ WriteRawRC(FIFODataReg, pInData[i]); } //写寻卡命令?
WriteRawRC(CommandReg, Command);//发送并接收数据
if (Command == PCD_TRANSCEIVE)
{ SetBitMask(BitFramingReg,0x80); } //相当于启动发送STARTSENG
//i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms
i = 2000;
do
{
n = ReadRawRC(ComIrqReg);
i--;
}
while ((i!=0) && !(n&0x01) && !(n&waitFor));
ClearBitMask(BitFramingReg,0x80); //相当于清除发送STARTSENG
if (i!=0) //定时时间到,i,没有递减到0?
{
if(!(ReadRawRC(ErrorReg)&0x1B))
{
status = MI_OK;
if (n & irqEn & 0x01)
{ status = MI_NOTAGERR; }
if (Command == PCD_TRANSCEIVE)
{
n = ReadRawRC(FIFOLevelReg);
lastBits = ReadRawRC(ControlReg) & 0x07;
if (lastBits)
{ *pOutLenBit = (n-1)*8 + lastBits; }
else
{ *pOutLenBit = n*8; }
if (n == 0)
{ n = 1; }
if (n > MAXRLEN)
{ n = MAXRLEN; }
for (i=0; i<n; i++)
{ pOutData[i] = ReadRawRC(FIFODataReg); }
}
}
else
{ status = MI_ERR; }
}
SetBitMask(ControlReg,0x80); // stop timer now
WriteRawRC(CommandReg,PCD_IDLE);
return status;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData)
{
unsigned char i,n;
ClearBitMask(DivIrqReg,0x04);
WriteRawRC(CommandReg,PCD_IDLE); //取消当前命令
SetBitMask(FIFOLevelReg,0x80); //FlushBuffer?清除ErrReg?的标志位
for (i=0; i<len; i++)
{ WriteRawRC(FIFODataReg, *(pIndata+i)); }
WriteRawRC(CommandReg, PCD_CALCCRC);
i = 0xFF;
do
{
n = ReadRawRC(DivIrqReg);
i--;
}
while ((i!=0) && !(n&0x04)); //当CRCIRq 所有数据被处理完毕该位置位
pOutData[0] = ReadRawRC(CRCResultRegL); //显示计算出来的CRC值
pOutData[1] = ReadRawRC(CRCResultRegM);
}
/////////////////////////////////////////////////////////////////////
//功 能:复位RC522
//返 回: 成功返回MI_OK
/////////////////////////////////////////////////////////////////////
char PcdReset(void)
{
// SPI_PORT_REG|=(1<<RC522RST);
// SPI_PORT|=(1<<RC522RST);
// SET_RC522_RST;
Delaynms(2);
// SPI_PORT&=~(1<<RC522RST);
CLR_RC522_RST;
Delaynms(2);
// SPI_PORT|=(1<<RC522RST);
SET_RC522_RST;
Delaynms(2);
WriteRawRC(CommandReg,PCD_RESETPHASE);// #define PCD_RESETPHASE 0x0F //复位
Delaynms(2);
WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363
WriteRawRC(TReloadRegL,30); //定时器的低8位数据
WriteRawRC(TReloadRegH,0); //定时器的高8位数据
WriteRawRC(TModeReg,0x8D); //定时器模式寄存器,定时器减值计数
WriteRawRC(TPrescalerReg,0x3E); //ftimer 2000 //实际值是OXD3E 这部分主要是设置定时器寄存器,
WriteRawRC(TxAutoReg,0x40);//必须要 //必须要 ,设置逻辑1,强制100%ASK调制
return MI_OK;
}
/******************************************************************************/
void InitRc522(void)
{
PcdReset();
PcdAntennaOff();
PcdAntennaOn();
M500PcdConfigISOType( 'A' );
}
//////////////////////////////////////////////////////////////////////
//设置RC632的工作方式
//////////////////////////////////////////////////////////////////////
char M500PcdConfigISOType(unsigned char type)
{
if (type == 'A') //ISO14443_A
{
ClearBitMask(Status2Reg,0x08); //状态2寄存器
WriteRawRC(ModeReg,0x3D);//3F //和Mifare卡通讯,CRC初始值0x6363
WriteRawRC(RxSelReg,0x86);//84
//选择内部接收器设置,内部模拟部分调制信号,发送数据后,延迟6个位时钟,接收
WriteRawRC(RFCfgReg,0x7F); //4F 配置接收器 48dB最大增益
WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
WriteRawRC(TReloadRegH,0);
WriteRawRC(TModeReg,0x8D);
WriteRawRC(TPrescalerReg,0x3E); //ftimer 2000
Delaynms(100);
PcdAntennaOn();
}
else{ return -1; }
return MI_OK;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//关闭天线
/////////////////////////////////////////////////////////////////////
void PcdAntennaOff(void)
{
ClearBitMask(TxControlReg, 0x03); //tx12RFEN==00;?,禁止发射管脚
}
/////////////////////////////////////////////////////////////////////
//开启天线
//每次启动或关闭天险发射之间应至少有1ms的间隔
/////////////////////////////////////////////////////////////////////
void PcdAntennaOn(void)
{
unsigned char i;
i = ReadRawRC(TxControlReg);
if (!(i & 0x03))
{
SetBitMask(TxControlReg, 0x03); //tx12RFEN==11;?,打开发射管脚
}
}
/////////////////////////////////////////////////////////////////////
//功 能:清RC522寄存器位
//参数说明:reg[IN]:寄存器地址
// mask[IN]:清位值
/////////////////////////////////////////////////////////////////////
void ClearBitMask(unsigned char reg,unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg, tmp & ~mask); // clear bit mask
}
/////////////////////////////////////////////////////////////////////
//功 能:置RC522寄存器位
//参数说明:reg[IN]:寄存器地址
// mask[IN]:置位值
/////////////////////////////////////////////////////////////////////
void SetBitMask(unsigned char reg,unsigned char mask)
{
char tmp = 0x0;
tmp = ReadRawRC(reg);
WriteRawRC(reg,tmp | mask); // set bit mask
}
/////////////////////////////////////////////////////////////////////
//功 能:读RC522寄存器
//参数说明:Address[IN]:寄存器地址
//返 回:读出的值
/////////////////////////////////////////////////////////////////////
unsigned char ReadRawRC(unsigned char Address)
{
unsigned char ucAddr;
unsigned char ucResult=0;
CLR_SPI_CS;
ucAddr = ((Address<<1)&0x7E)|0x80; //读数据
//变化成有效的地址形式,最低位为0,最高位为1时候是,从MFRC522读出数据,参考39页
SPI_MasterTransmit(ucAddr);
SPI_MasterTransmit(ucResult);
ucResult=SPDR;
SET_SPI_CS;
return ucResult;
}
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
//功 能:写RC522寄存器
//参数说明:Address[IN]:寄存器地址
// value[IN]:写入的值
/////////////////////////////////////////////////////////////////////
void WriteRawRC(unsigned char Address, unsigned char value)
//void WriteRawRC(Address,value)
{
unsigned char ucAddr;
CLR_SPI_CS; //启动SPI
ucAddr = ((Address<<1)&0x7E); //写数据
//变化成有效的地址形式,最低为为0,最高位为1时候是,写入MFRC522数据
SPI_MasterTransmit(ucAddr);
SPI_MasterTransmit(value);
SET_SPI_CS; //停止SPI
}
/******************************************************************************/
void Delaynms(unsigned int di) //延时
{
unsigned int i,j;
for(i=0;i<di;i++)
for(j=0;j<10;j++)
;
}
追问void WriteRawRC(unsigned char Address, unsigned char value)
{
}中为什么是这样ucAddr = ((Address<<1)&0x7E); //写数据 ?
追答
RC522写数据是有一定要求的。具体的你看下面这图。
写数据就要把位7置0和位0置0。
我的理解就到这了。
RC522芯片与单片机通信
单片机 与 上位机串口通信,需要单片机的串口波特率 与 上位机串口波特率 要一致,单片机与RC522 IC卡读卡芯片是用SPI通信的,也就是上位机 向 单片机 发送 读卡指令 单片机 通过 读卡程序控制 RC522,读取 接近读卡芯片的 IC卡数据,通过串口上传给 上位机。
单片机是什么
单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转...
用单片机与RC522模块通信读卡
CLR_RC522_RST; Delaynms(2);// SPI_PORT|=(1<<RC522RST); SET_RC522_RST; Delaynms(2); WriteRawRC(CommandReg,PCD_RESETPHASE);// #define PCD_RESETPHASE 0x0F //复位 Delaynms(2); WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30); //定时器...
stc单片机+rc522的读卡电路,只能读写首个扇区内的数据块。是怎么回事...
非接触IC卡,需要进行 初始化、寻卡 、先卡操作,在读写卡操作时 多必须 完成 加载密匙、三重认证 后才可以 对 该扇区内 的 读写卡操作, 要操作其它 扇区 需要 重新 加载密匙、三重认证。
基于STM32+RC522设计的门禁系统
硬件选择上,STM32F103C8T6单片机以其高效性能被选用,RFID-RC522模块以其高效读写能力应用于门禁。而SG90舵机的轻便和精确性为门锁控制提供了便利。0.96寸OLED显示屏则为用户提供了友好的交互界面。此外,使用IIC接口的键盘模块提升了输入体验。实验结果证实了系统设计的稳健性,无论是卡片管理还是门锁控制...
求STC单片机的RC522读卡程序,通过串口发送卡号即可。
我有stc11f32xe读取RC522的上位机程序,你看看能用吗。通过串口发送卡号什么意思,可以通过串口读取卡号。如果需要下载到单片机中的程序也可以提供。
RC522 ic卡模块怎么与单片机连接
用单片机的5个I/O口接模块的 RST、、SS、SCLK、MOSI、MISO,连接VCC、GND就可以了,接下来就是编程了。
RFID RC522射频模块和51单片机连接,加一个LCD显示,程序怎么写_百度知 ...
RFID RC522射频模块;直接用单片机串口控制,读取射频卡的信息,那些串口命令很重要过的。以前做过一个 RC522读射频卡的课题
RC522读卡芯片怎么用?
MFRC522内部有64个寄存器,共分4页:PAGE0:COMMANDANDSTATUS;PAGE1:COMMAND;PAGE2:CFG;PAGE3:TEST。MFRC522通过内部寄存器的读写控制与Mifare1IC卡数据通信。怎么用单片机来控... MF RC522内部有64个寄存器,共分4页:PAGE0:COMMAND AND STATUS;PAGE1:COMMAND;PAGE2:CFG;PAGE3:TEST。MF RC522通过内部寄存器的读...
请教51单片机,rc522读卡器怎么实现刷卡与存储的卡进行对比然后在12864...
你这个首先要找到12864液晶的显示代码。就是往什么端口送数据你要知道,一般店铺卖的时候有送代码的。然后就是读卡模块,分步走就可以了
射频模块RC522和51单片机怎么通信
RC522有UART接口,可以通过RS232接口和51单片机串口通信。