mfrc522程序注释
更新时间:2024-06-12 15:40:01 阅读量: 综合文库 文档下载
#include
#define MAXRLEN 18
/******* RxModeReg默认为106kbit/s的通信速率 ******************/
/*********************************************************************** * 功 能:寻卡
* 参数说明: 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(unsigned char req_code,unsigned char *pTagType) {
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN]; // unsigned char xTest ;
ClearBitMask(Status2Reg,0x08); // 清MFCrypto1On,只能通过软件清零,该位用来指示Crypto1的接通情况,MFAuthent(验证密钥)命令成功执行后置1
WriteRawRC(BitFramingReg,0x07); // TxLastBits([2-0])表示发送的最后一个字节7位发送
// xTest = ReadRawRC(BitFramingReg); // if(xTest == 0x07 ) // { LED_GREEN =0 ;}
// else {LED_GREEN =1 ;while(1){}} SetBitMask(TxControlReg,0x03); // TxControlReg低2位(Tx2RFEn和Tx1RFEn)置1,Tx2和Tx1管脚输出信号调制在13.56MHz的载波上
ucComMF522Buf[0] = req_code;
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen); // PCD_TRANSCEIVE == 0x0c发送并接收数据
// if(status == MI_OK ) // { LED_GREEN =0 ;} // else {LED_GREEN =1 ;}
if ((status == MI_OK) && (unLen == 0x10)) // 发送成功并且接收16位数据 {
*pTagType = ucComMF522Buf[0];
*(pTagType+1) = ucComMF522Buf[1]; // 接收的卡片类型保存在pTagType中 } else
{ status = MI_ERR; }
return status; }
/********************************************************************** * 功 能:防冲撞
* 参数说明: pSnr[OUT]:卡片序列号,4字节 * 返 回: 成功返回MI_OK
**********************************************************************/ char PcdAnticoll(unsigned char *pSnr) {
char status;
unsigned char i,snr_check=0; unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ClearBitMask(Status2Reg,0x08); // 清MFCrypto1On,只能通过软件清零,该位用来指示Crypto1的接通情况,MFAuthent(验证密钥)命令成功执行后置1
WriteRawRC(BitFramingReg,0x00); // TxLastBits([2-0])表示发送的最后一个字节的所有位都发送
ClearBitMask(CollReg,0x80); // 高位置0,所有接收的位在冲突后清除
ucComMF522Buf[0] = PICC_ANTICOLL1; // 防冲撞(0x93) 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); // 置1,回归正常 return status; }
/********************************************************************** * 功 能:选定卡片
* 参数说明: pSnr[IN]:卡片序列号,4字节 * 返 回: 成功返回MI_OK
**********************************************************************/ char PcdSelect(unsigned char *pSnr) {
char status; unsigned char i; unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_ANTICOLL1; // 防冲撞 ucComMF522Buf[1] = 0x70; ucComMF522Buf[6] = 0; for (i=0; i<4; i++) {
ucComMF522Buf[i+2] = *(pSnr+i); // 将卡片序列号写进去 ucComMF522Buf[6] ^= *(pSnr+i); }
CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]); // CRC校验卡片序列号
ClearBitMask(Status2Reg,0x08); // 清MFCrypto1On,只能通过软件清零,该位用来指示Crypto1的接通情况,MFAuthent(验证密钥)命令成功执行后置1
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen); // 发送卡片的序列号及其校验码
if ((status == MI_OK) && (unLen == 0x18)) // 接收24位 { status = MI_OK; } else
{ status = MI_ERR; }
return status; }
/********************************************************************** * 功 能:验证卡片密码
* 参数说明: auth_mode[IN]: 密码验证模式 * 0x60 = 验证A密钥 * 0x61 = 验证B密钥 * addr[IN]:块地址 * pKey[IN]:密码
* pSnr[IN]:卡片序列号,4字节 * 返 回: 成功返回MI_OK
**********************************************************************/ char PcdAuthState(unsigned char auth_mode,unsigned char addr,unsigned char *pKey,unsigned char *pSnr) {
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = auth_mode; // 验证模式 ucComMF522Buf[1] = addr; // 块地址 for (i=0; i<6; i++)
{ ucComMF522Buf[i+2] = *(pKey+i); } // 密码
for (i=0; i<4; i++) /*源代码是6,不知道正不正确*/
{ ucComMF522Buf[i+8] = *(pSnr+i); } // 防冲撞卡号 // memcpy(&ucComMF522Buf[2], pKey, 6); // memcpy(&ucComMF522Buf[8], pSnr, 4);
status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen); if ((status != MI_OK) || (!(ReadRawRC(Status2Reg) & 0x08))) { status = MI_ERR; }
return status; }
/********************************************************************** * 功 能:读取M1卡一块数据 * 参数说明: addr[IN]:块地址
* pData[OUT]:读出的数据,16字节 * 返 回: 成功返回MI_OK
***********************************************************************/ char PcdRead(unsigned char addr,unsigned char *pData) {
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_READ; // 0x30,读块 ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // 计算CRC,存放在ucComMF522Buf[2]和ucComMF522Buf[3]中
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // 将4个字节放松出去,并接收数据
if ((status == MI_OK) && (unLen == 0x90)) // 接收144位(18字节) // { memcpy(pData, ucComMF522Buf, 16); } {
for (i=0; i<16; i++)
{ *(pData+i) = ucComMF522Buf[i]; } // 将前16字节读出 } else
{ status = MI_ERR; }
return status; }
/******************************************************************** * 功 能:写数据到M1卡一块 * 参数说明: addr[IN]:块地址
* pData[IN]:写入的数据,16字节 * 返 回: 成功返回MI_OK
********************************************************************/ char PcdWrite(unsigned char addr,unsigned char *pData) {
char status;
unsigned int unLen;
unsigned char i,ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_WRITE; // 0xa0 写块 ucComMF522Buf[1] = addr;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // 计算CRC
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // 发送写命令和地址
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // 接收低四位为1010
{ status = MI_ERR; }
if (status == MI_OK) {
//memcpy(ucComMF522Buf, pData, 16); for (i=0; i<16; i++)
{ ucComMF522Buf[i] = *(pData+i); } // 16字节数据
CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]); // 两位CRC计算字节
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen); // 发送18字节
if ((status != MI_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)) // 返回低四位为1010
{ status = MI_ERR; } }
return status; }
/********************************************************************* * 功 能:命令卡片进入休眠状态 * 返 回: 成功返回MI_OK
*********************************************************************/ char PcdHalt(void) {
char status;
unsigned int unLen;
unsigned char ucComMF522Buf[MAXRLEN];
ucComMF522Buf[0] = PICC_HALT; // 0x50,休眠 ucComMF522Buf[1] = 0;
CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // 计算校验位
status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen); // 发送
return MI_OK; }
/********************************************************************* * 用MF522计算CRC16函数
*********************************************************************/
void CalulateCRC(unsigned char *pIndata,unsigned char len,unsigned char *pOutData) {
unsigned char i,n;
ClearBitMask(DivIrqReg,0x04); // CRCIRQ清零 WriteRawRC(CommandReg,PCD_IDLE); // 空闲命令
SetBitMask(FIFOLevelReg,0x80); // FIFOLevelReg中FlushBuffer位置1,表示缓冲区读和写指针清除,即缓冲区无数据,用来存放一下批数据,ErrReg的BufferOvfl清楚 for (i=0; i { WriteRawRC(FIFODataReg, *(pIndata+i)); } // 将数据写入缓冲区 WriteRawRC(CommandReg, PCD_CALCCRC); // 启动CRC计算,结果存于CRCResultReg中 i = 0xFF; do { n = ReadRawRC(DivIrqReg); i--; } while ((i!=0) && !(n&0x04)); // CRCIRQ置位,当CRC有效且所有数据被处理则需要置1,退出循环,或者是执行了127次读取认为完成CRC也退出循环 pOutData[0] = ReadRawRC(CRCResultRegL); pOutData[1] = ReadRawRC(CRCResultRegM); // 计算结果输出到pOutData中 } /********************************************************************* * 功 能:复位RC522 * 返 回: 成功返回MI_OK *********************************************************************/ char PcdReset(void) { MF522_RST=1; _nop_(); MF522_RST=0; // 复位 _nop_(); MF522_RST=1; _nop_(); WriteRawRC(CommandReg,PCD_RESETPHASE); // 0x0F,软件复位 _nop_(); WriteRawRC(ModeReg,0x3D); // 和Mifare卡通讯,CRC初始值0x6363 WriteRawRC(TReloadRegL,30); // 48 WriteRawRC(TReloadRegH,0); WriteRawRC(TModeReg,0x8D); // 10001101(141):发送完开始计时,接收时停止计时,自动重装 WriteRawRC(TPrescalerReg,0x3E); // 00111110(62),3390 定时时间: 3391*49/6.78=24.5ms WriteRawRC(TxAutoReg,0x40); // 控制驱动天线 return MI_OK; } /********************************************************************* * 设置RC632的工作方式 *********************************************************************/ char M500PcdConfigISOType(unsigned char type) { if (type == 'A') //ISO14443_A { ClearBitMask(Status2Reg,0x08); /* WriteRawRC(CommandReg,0x20); //as default WriteRawRC(ComIEnReg,0x80); //as default WriteRawRC(DivlEnReg,0x0); //as default WriteRawRC(ComIrqReg,0x04); //as default WriteRawRC(DivIrqReg,0x0); //as default WriteRawRC(Status2Reg,0x0);//80 //trun off temperature sensor WriteRawRC(WaterLevelReg,0x08); //as default WriteRawRC(ControlReg,0x20); //as default WriteRawRC(CollReg,0x80); //as default */ WriteRawRC(ModeReg,0x3D);//3F /* WriteRawRC(TxModeReg,0x0); //as default??? WriteRawRC(RxModeReg,0x0); //as default??? WriteRawRC(TxControlReg,0x80); //as default??? WriteRawRC(TxSelReg,0x10); //as default??? */ WriteRawRC(RxSelReg,0x86);//84 // 内部模拟部分的调制信号作为非接触式UART输入,发送后接收器启动延时6个位时钟 // WriteRawRC(RxThresholdReg,0x84);//as default // WriteRawRC(DemodReg,0x4D); //as default // WriteRawRC(ModWidthReg,0x13);//26 WriteRawRC(RFCfgReg,0x7F); //4F // 接收信号电压增益23dB /* WriteRawRC(GsNReg,0x88); //as default??? WriteRawRC(CWGsCfgReg,0x20); //as default??? WriteRawRC(ModGsCfgReg,0x20); //as default??? */ WriteRawRC(TReloadRegL,30);//tmoLength);// TReloadVal = 'h6a =tmoLength(dec) WriteRawRC(TReloadRegH,0); WriteRawRC(TModeReg,0x8D); WriteRawRC(TPrescalerReg,0x3E); // PcdSetTmo(106); delay(10); PcdAntennaOn(); } else{ return -1; } return MI_OK; } /******************************************************************** * 功 能:读RC632寄存器 SPI方式 * 参数说明:Address[IN]:寄存器地址 * 返 回:读出的值 *********************************************************************/ unsigned char ReadRawRC(unsigned char Address) { unsigned char i, ucAddr; unsigned char 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(unsigned char Address, unsigned char value) { unsigned char i, ucAddr; MF522_SCK = 0; MF522_NSS = 0; ucAddr = ((Address<<1)&0x7E); // 地址高位为0表示写,地位必须为0 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(unsigned char reg,unsigned char mask) { char tmp = 0x0; tmp = ReadRawRC(reg); { 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; } /* /////////////////////////////////////////////////////////////////////// // Delay 10ms /////////////////////////////////////////////////////////////////////// void delay_10ms(unsigned int _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 } */
正在阅读:
mfrc522程序注释06-12
汉语语法分析问题:吕叔湘05-05
当代中国政治制度辨析题与解答09-27
项目管理课程结课报告03-09
振动物理力学答案11-17
光荣啊,中国共青团01-01
探讨火电厂经济运行优化管理08-21
《仪器分析》总练习题01-05
2017-2022年中国石油和天然气开采产品行业发展深度研究与投资战04-26
篮球基本技术动作要领05-20
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- 注释
- mfrc522
- 程序
- 中考复习:课内外文言文比较阅读
- 肖像权在新闻活动中的合理使用
- 关于浙江沿海居民抗台的若干探究 - 以温州苍南为例 - 图文
- 创新教育人才工作机制-2019年精选文档
- 走在生本路上
- 中考圆压轴题训练精选
- 中国贝雕产品行业市场前景分析预测年度报告(目录) - 图文
- 理论力学静力学复习题答案
- 2014电大《创业管理》形成性考核册题目与答案
- 《英美概况》试题(附答案)
- 阴宅风水绝断秘法
- 助剂化学知识整理
- 高三生物复习计划
- 身份证阅读器主要的品牌以及参数
- 陈洋--长通物流营销策划书
- 学习纳路特捍甲、捍丝混凝土密封固化剂和的施工方法
- 桌面运维工程师能力试卷试卷题库(面试版本)
- 五年级上册每日一题
- 2018年阀门行业产销需求预测及投资咨询报告(目录)
- 施工安全技术答案