资讯详情

51单片机RC522无线射频IC卡驱动教程

RC522驱动:

SDA——P2.0 SCK——P2.1 MISO——P2.3 MOSI——P2.2 RST——P2.4 IRQ——悬空

/* ********************************************************************** * 头文件包含 ********************************************************************** */ #include <intrins.h> #include <string.h>  #include "rc522.h" #include "delay.h"  /* ********************************************************************** * 本地全局变量 ********************************************************************** */ // 专用SFR sfr   RCAP2LH =   0xCA; sfr   T2LH    =   0xCC;                          // RC522 SPI接口定义 sbit     MF522_NSS  =    P2^0;  //这是SDA sbit     MF522_SCK  =    P2^1; sbit     MF522_SI   =    P2^2; sbit     MF522_SO   =    P2^3; sbit     MF522_RST  =    P2^4;  //  /****************RC522驱动源码**************************************/  / //功 能:寻卡 //参数说明: req_code[IN]:寻卡方式 // 0x52 = 14443A标准的卡 // 0x26 = 没有进入休眠状态的卡 // pTagType[OUT]:卡片类型代码 // 0x4400 = Mifare_UltraLight // 0x0400 = Mifare_One(S50) // 0x0200 = Mifare_One(S70) // 0x0800 = Mifare_Pro(X) // 0x4403 = Mifare_DESFire //返 回: 成功返回MI_OK / char PcdRequest(u8 req_code,u8 *pTagType){ 
            char status;      u32  unLen;    u8 ucComMF522Buf[MAXRLEN];     ClearBitMask(Status2Reg,0x08);    WriteRawRC(BitFramingReg,0x07; SetBitMask(TxControlReg,0x03); ucComMF522Buf[0] = req_code; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen); if ((status == MI_OK) && (unLen == 0x10)) { 
          *pTagType = ucComMF522Buf[0]; *(pTagType+1) = ucComMF522Buf[1]; } else { 
          status = MI_ERR; } return status; } / //功 能:防冲撞 //参数说明: pSnr[OUT]:卡片序列号,4字节 //返 回: 成功返回MI_OK /  char PcdAnticoll(u8 *pSnr) { 
          char status; u8 i,snr_check=0; u32 unLen; u8 ucComMF522Buf[MAXRLEN]; ClearBitMask(Status2Reg,0x08); WriteRawRC(BitFramingReg,0x00); ClearBitMask(CollReg,0x80); ucComMF522Buf[0] = PICC_ANTICOLL1; ucComMF522Buf[1] = 0x20; status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen); if (status == MI_OK) { 
          for (i=0; i<4; i++) { 
          *(pSnr+i) = ucComMF522Buf[i]; snr_check ^= ucComMF522Buf[i]; } if (snr_check != ucComMF522Buf[i]) { 
          status = MI_ERR; } } SetBitMask(CollReg,0x80); return status; } / //功 能:复位RC522 //返 回: 成功返回MI_OK / char PcdReset(void){ 
          MF522_RST=1; _nop_();//空机器指令 MF522_RST=0; _nop_(); MF522_RST=1; _nop_(); WriteRawRC(CommandReg,PCD_RESETPHASE); //往寄出去地址01,写0x0F _nop_(); WriteRawRC(ModeReg,0x3D); //和Mifare卡通讯,CRC初始值0x6363,CRCPreset=01 WriteRawRC(TReloadRegL,30); //定时器重装值,分为两个8位寄存器,初始值都为0x00  WriteRawRC(TReloadRegH,0); WriteRawRC(TModeReg,0x8D); //内部定时器的设置1000 1101,后四位为TPrescalerReg的高四位 WriteRawRC(TPrescalerReg,0x3E); //为TPregScaler低8位,Ftimer = 6.78MHZ/TPreScaler WriteRawRC(TxAutoReg,0x40); return MI_OK; } // //设置RC632的工作方式  // char M500PcdConfigISOType(u8 type){ 
          if (type == 'A') //ISO14443_A { 
          ClearBitMask(Status2Reg,0x08); WriteRawRC(ModeReg,0x3D);//3 WriteRawRC(RxSelReg,0x86);// WriteRawRC(RFCfgReg,0x7F); //4F WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)  WriteRawRC(TReloadRegH,0); WriteRawRC(TModeReg,0x8D); WriteRawRC(TPrescalerReg,0x3E); delay_n10ms(1); PcdAntennaOn(); } else{ 
          return -1; } return MI_OK; } / //功 能:读RC632寄存器 //参数说明:Address[IN]:寄存器地址 //返 回:读出的值 / u8 ReadRawRC(u8 Address){ 
          u8 i, ucAddr; u8 ucResult=0; MF522_SCK = 0; MF522_NSS = 0; ucAddr = ((Address<<1)&0x7E)|0x80; for(i=8;i>0;i--) { 
          MF522_SI = ((ucAddr&0x80)==0x80); MF522_SCK = 1; ucAddr <<= 1; MF522_SCK = 0; } for(i=8;i>0;i--) { 
          MF522_SCK = 1; ucResult <<= 1; ucResult|=(bit)MF522_SO; MF522_SCK = 0; } MF522_NSS = 1; MF522_SCK = 1; return ucResult; } / //功 能:写RC632寄存器 //参数说明:Address[IN]:寄存器地址 // value[IN]:写入的值 / void WriteRawRC(u8 Address, u8 value){ 
          u8 i, ucAddr; MF522_SCK = 0; MF522_NSS = 0; ucAddr = ((Address<<1)&0x7E); for(i=8;i>0;i--) { 
          MF522_SI = ((ucAddr&0x80)==0x80); MF522_SCK = 1; ucAddr <<= 1; MF522_SCK = 0; } for(i=8;i>0;i--) { 
          MF522_SI = ((value&0x80)==0x80); MF522_SCK = 1; value <<= 1; MF522_SCK = 0; } MF522_NSS = 1; MF522_SCK = 1; } / //功 能:置RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:置位值 / void SetBitMask(u8 reg,u8 mask) { 
          char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg,tmp | mask); // set bit mask } / //功 能:清RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:清位值 / void ClearBitMask(u8 reg,u8 mask) { 
          char tmp = 0x0; tmp = ReadRawRC(reg); WriteRawRC(reg, tmp & ~mask); // clear bit mask } / //功 能:通过RC522和ISO14443卡通讯 //参数说明:Command[IN]:RC522命令字 // pInData[IN]:通过RC522发送到卡片的数据 // InLenByte[IN]:发送数据的字节长度 // pOutData[OUT]:接收到的卡片返回数据 // *pOutLenBit[OUT]:返回数据的位长度 / char PcdComMF522(u8 Command, u8 *pInData, u8 InLenByte, u8 *pOutData, u32 *pOutLenBit) { 
          char status = MI_ERR; u8 irqEn = 0x00; u8 waitFor = 0x00; u8 lastBits; u8 n; u32 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); for (i=0; i<InLenByte; i++) { 
          WriteRawRC(FIFODataReg, pInData[i]); } WriteRawRC(CommandReg, Command); if (Command == PCD_TRANSCEIVE) { 
          SetBitMask(BitFramingReg,0x80); } // i = 600;//根据时钟频率调整,操作M1卡最大等待时间25ms i = 2000;//900,1100,1700,2000,2700 do { 
          n = ReadRawRC(ComIrqReg); i--; } while ((i!=0) && !(n&0x01) && !(n&waitFor)); ClearBitMask(BitFramingReg,0x80); if (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; } / //开启天线  //每次启动或关闭天险发射之间应至少有1ms的间隔 / void PcdAntennaOn(){ 
          u8 i; i = ReadRawRC(TxControlReg); if (!(i & 0x03)) { 
          SetBitMask(TxControlReg, 0x03); } } / //关闭天线 / void PcdAntennaOff() { 
          ClearBitMask(TxControlReg, 0x03); } / //功 能:扣款和充值 //参数说明: dd_mode[IN]:命令字 // 0xC0 = 扣款 // 0xC1 = 充值 // addr[IN]:钱包地址 // pValue[IN]:4字节增(减)值,低位在前 //返 回: 成功返回MI_OK /  //char PcdValue(u8 dd_mode,u8 addr,u8 *pValue) //{ 
          // char status; // u32 unLen; // u8 i,ucComMF522Buf[MAXRLEN];  //  // ucComMF522Buf[0] = dd_mode; // ucComMF522Buf[1] = addr; // CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); //  // status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // // if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // { status = MI_ERR; } //  // if (status == MI_OK) // { 
          // // memcpy(ucComMF522Buf, pValue, 4); // for (i=0; i<16; i++) // { ucComMF522Buf[i] = *(pValue+i); } // CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]); // unLen = 0; // status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen); // if (status != MI_ERR) // { status = MI_OK; } // } //  // if (status == MI_OK) // { 
          // ucComMF522Buf[0] = PICC_TRANSFER; // ucComMF522Buf[1] = addr; // CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);  //  // status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // // if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // { status = MI_ERR; } // } // return status; //} /* / //功 能:备份钱包 //参数说明: sourceaddr[IN]:源地址 // goaladdr[IN]:目标地址 //返 回: 成功返回MI_OK / char PcdBakValue(u8 sourceaddr, u8 goaladdr) { char status; u32 unLen; u8 ucComMF522Buf[MAXRLEN]; ucComMF522Buf[0] = PICC_RESTORE; ucComMF522Buf[1] = sourceaddr; CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; } if (status == MI_OK) { ucComMF522Buf[0] = 0; ucComMF522Buf[1] = 0; ucComMF522Buf[2] = 0; ucComMF522Buf[3] = 0; CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]); status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen); if (status != MI_ERR) { status = MI_OK; } } if (status != MI_OK) { return MI_ERR; } ucComMF522Buf[0] = PICC_TRANSFER; ucComMF522Buf[1] = goaladdr; CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) { status = MI_ERR; } return status; } */ #if 0 /// // Delay 10ms /// void delay_n10ms(u32 _10ms) { 
          #ifndef NO_TIMER2 RCAP2LH = RCAP2_10ms; T2LH = RCAP2_10ms; TR2 = TRUE; while (_10ms--) { 
          while (!TF2); TF2 = FALSE; } TR2 = FALSE; #else while (_10ms--) { 
          delay_50us(19); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid ) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(20); if (CmdValid) return; delay_50us(19); if (CmdValid) return; } #endif } #endif 

#ifndef RC522_H__
#define RC522_H__
/* ********************************************************************** * 头文件包含 ********************************************************************** */
#include "main.h"

typedef enum
{ 
        
	false,
	true,
}bool;

#define OSC_FREQ (22118400L)
#define RCAP2_50us (65536L - OSC_FREQ/40417L)
#define RCAP2_1ms (65536L - OSC_FREQ/2000L)
#define RCAP2_10ms (65536L - OSC_FREQ/1200L)
#define TIME0_500us (65536L - OSC_FREQ/8000L)
#define TIME0_10ms (65536L - OSC_FREQ/200)
/* ********************************************************************** * 本地宏定义 ********************************************************************** */
#define MAXRLEN 18

/
//Mifare_One卡片命令字
/
#define PICC_REQIDL 0x26 //寻天线区内未进入休眠状态
#define PICC_REQALL 0x52 //寻天线区内全部卡
#define PICC_ANTICOLL1 0x93 //选卡
#define PICC_ANTICOLL2 0x95 //防冲撞
#define PICC_AUTHENT1A 0x60 //验证A密钥
#define PICC_AUTHENT1B 0x61 //验证B密钥
#define PICC_READ 0x30 //读块
#define PICC_WRITE 0xA0 //写块
#define PICC_DECREMENT 0xC0 //扣款
#define PICC_INCREMENT 0xC1 //充值
#define PICC_RESTORE 0xC2 //调块数据到缓冲区
#define PICC_TRANSFER 0xB0 //保存缓冲区中数据
#define PICC_HALT 0x50 //休眠


        标签: 单片机应如何正确驱动继电器继电器3e4

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台