问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

用单片机与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&lt;&lt;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单片机串口通信。

单片机与单片机通讯 51单片机无线通信模块 单片机怎样与4G模块传递信息 nrf24l01模块和51单片机 单片机gsm模块的使用 手机和单片机通信 51单片机无线通信 单片机怎么和其他模块 无线通信单片机
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
...做梦,不过我当时觉得我神智很清晰,我感觉呼吸困难,身体不能动,根本... 肯帝亚实木地板怎么样肯帝亚地板特点 怎么打开华为p40的设备信息 华为p40怎么打开无障碍服务? 佳能IR-2018怎么查已打印量和剩余打印量,谢谢! 梦见在别人地里检红薯而且又吃了点,还问己故的老娘要不要是什么证兆... 在二进制中位权是什么 在二进制中位权 揭秘为何说宁在坟头过夜 不从空宅老屋过 梦到坟头特小,每个上面一颗红薯苗旁边一张百元人民币,然后捡钱是什么意... ps怎么把照片大小改成80kbps怎么把照片大小改成10kb RC522模块怎么进入管理员模式添加其他卡 MFRC522 对Mifare1 S50卡控制块的读写操作 MF RC522的概述 mfrc500与mfrc522有何区别 RC522读卡芯片怎么用? 怎么设计平面广告,才能达到最佳效果? 成都平面广告设计学校? 平面广告的类型有哪些?求答案 平面广告设计专业的就业前景怎么样 平面广告设计 一幅成功的平面广告设计作品应该注意哪几方面 一幅平面广告的设计应该有哪些要点? 平面广告设计是做什么 微信退出群聊有提示吗? 平面广告创意有哪些具体的要求? 求平面广告设计电脑配置清单,价格:5000-6000元左右。做PS、X4、AI的时候要快,打开大文件不会卡。 生活中的平面广告有哪些? 求平面广告设计配置的电脑6000以内+32寸曲面显示屏,主要是做设计工作用能玩的起守望者先锋类型游戏。 怎样做一个平面广告设计 广告平面设计的几大要素,你了解多少?(一) rc522可以读什么型号的ic卡芯片? mfrc522读卡怎么把数据传入pc端 社保断缴会有什么影响吗? MF RC522的特性 MFRC522可以同时读取多个RFID标签吗 mf rc522读写器,arduino2560,做rfid,现在能够读写白卡,但是怎么能读写其他卡 社保断缴有啥影响? 社保断缴有什么影响?会清零吗? RC522芯片怎么读CPU卡 mfrc522怎么同时操作两张卡 社保断缴你知道会有什么影响吗? stc单片机+rc522的读卡电路,只能读写首个扇区内的数据块。是怎么回事 MFRC522这款射频芯片用于售饭机怎么样,会不会停产 关于MFRC522引脚选择 可选单片机任意引脚吗 社保断缴过一个月有什么影响 求STC单片机的RC522读卡程序,通过串口发送卡号即可。 社保断交有什么后果? vivoy71A(3+32)是全面屏手机吗? rc522读卡模块怎么链接上位机 MFRC522是什么