rc522作为使用非常多的读写卡芯片,使用SPI芯片读写应用已经非常广了。但有些时候我们只有串口可以使用,或者我们觉得串口使用更加方便,那么就必须要编写串口的驱动程序。不过很难找到可以直接使用的串口程序。所以在此将我这边写好的串口驱动写好如下:
直接上代码
下面是RC522.C的驱动文件。支持读写卡号8位数据。rc522用的是stm32 的串口3,调试显示是串口1;
- <font face="微软雅黑" size="3">#include "rc522.h"
- #include "delay.h"
- /
- //MF522命令字
- /
- #define PCD_IDLE 0x00 //取消当前命令
- #define PCD_CALCCRC 0x03 //CRC计算
- #define PCD_TRANSMIT 0x04 //发送数据
- #define PCD_RECEIVE 0x08 //接收数据
- #define PCD_TRANSCEIVE 0x0C //发送并接收数据
- #define PCD_AUTHENT 0x0E //验证密钥
- #define PCD_RESETPHASE 0x0F //复位
- /
- //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 //休眠
- /
- //MF522 FIFO长度定义
- /
- #define DEF_FIFO_LENGTH 64 //FIFO size=64byte
- #define MAXRLEN 18
- /
- //MF522寄存器定义
- /
- // PAGE 0
- #define RFU00 0x00
- #define CommandReg 0x01
- #define ComIEnReg 0x02
- #define DivlEnReg 0x03
- #define ComIrqReg 0x04
- #define DivIrqReg 0x05
- #define ErrorReg 0x06
- #define Status1Reg 0x07
- #define Status2Reg 0x08
- #define FIFODataReg 0x09
- #define FIFOLevelReg 0x0A
- #define WaterLevelReg 0x0B
- #define ControlReg 0x0C
- #define BitFramingReg 0x0D
- #define CollReg 0x0E
- #define RFU0F 0x0F
- // PAGE 1
- #define RFU10 0x10
- #define ModeReg 0x11
- #define TxModeReg 0x12
- #define RxModeReg 0x13
- #define TxControlReg 0x14
- #define TxAutoReg 0x15
- #define TxSelReg 0x16
- #define RxSelReg 0x17
- #define RxThresholdReg 0x18
- #define DemodReg 0x19
- #define RFU1A 0x1A
- #define RFU1B 0x1B
- #define MifareReg 0x1C
- #define RFU1D 0x1D
- #define RFU1E 0x1E
- #define SerialSpeedReg 0x1F
- // PAGE 2
- #define RFU20 0x20
- #define CRCResultRegM 0x21
- #define CRCResultRegL 0x22
- #define RFU23 0x23
- #define ModWidthReg 0x24
- #define RFU25 0x25
- #define RFCfgReg 0x26
- #define GsNReg 0x27
- #define CWGsCfgReg 0x28
- #define ModGsCfgReg 0x29
- #define TModeReg 0x2A
- #define TPrescalerReg 0x2B
- #define TReloadRegH 0x2C
- #define TReloadRegL 0x2D
- #define TCounterValueRegH 0x2E
- #define TCounterValueRegL 0x2F
- // PAGE 3
- #define RFU30 0x30
- #define TestSel1Reg 0x31
- #define TestSel2Reg 0x32
- #define TestPinEnReg 0x33
- #define TestPinValueReg 0x34
- #define TestBusReg 0x35
- #define AutoTestReg 0x36
- #define VersionReg 0x37
- #define AnalogTestReg 0x38
- #define TestDAC1Reg 0x39
- #define TestDAC2Reg 0x3A
- #define TestADCReg 0x3B
- #define RFU3C 0x3C
- #define RFU3D 0x3D
- #define RFU3E 0x3E
- #define RFU3F 0x3F
- /
- //和MF522通讯时返回的错误代码
- /
- #define MI_OK 0
- #define MI_NOTAGERR (1)
- #define MI_ERR (2)
- #define SHAQU1 0X01
- #define KUAI4 0X04
- #define KUAI7 0X07
- #define REGCARD 0xa1
- #define CONSUME 0xa2
- #define READCARD 0xa3
- #define ADDMONEY 0xa4
- //==============================================================================================
- void UART3_init(void)/*串口3MC20通信*/
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
- USART_DeInit(USART3); //复位串口3
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 ;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- USART_InitStructure.USART_BaudRate = 9600;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
-
- USART_Init(USART3, &USART_InitStructure);
- USART_Cmd(USART3, ENABLE);
- }
- /***********************RC522 函数宏定义**********************/
- u8 UART3_ReadWriteByte(u8 TxData)
- {
- while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET||USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET) {}
- USART_SendData(USART3,TxData);
- delay_ms(5);
- return USART_ReceiveData(USART3);
- }
- //==============================================================================================
- void M500PcdConfigISOType( u8 type ); //工作方式
- void PcdReset( void ); //复位
- char PcdRequest( u8 req_code, u8 * pTagType ); //寻卡
- char PcdAnticoll( u8 * pSnr); //读卡号
- char PcdSelect( u8 * pSnr );
- char PcdAuthState( u8 ucAuth_mode, u8 ucAddr, u8 * pKey, u8 * pSnr );
- char PcdWrite( u8 ucAddr, u8 * pData );
- char PcdRead( u8 ucAddr, u8 * pData );
- void PcdAntennaOn ( void );
- void PcdAntennaOff ( void );
- void RC522_Init(void)
- {
- UART3_init();//初始化spi3
- delay_ms(1000);
- PcdReset();
- M500PcdConfigISOType ( 'A' );//设置工作方式
- }
- //
- // M1卡分为16个扇区,每个扇区由四个块(块0、块1、块2、块3)组成
- // 将16个扇区的64个块按绝对地址编号为:0~63
- // 第0个扇区的块0(即绝对地址0块),用于存放厂商代码,已经固化不可更改
- // 每个扇区的块0、块1、块2为数据块,可用于存放数据
- // 每个扇区的块3为控制块(绝对地址为:块3、块7、块11.....)包括密码A,存取控制、密码B等
- /*全局变量*/
- unsigned char CT[2];//卡类型
- unsigned char SN[4]; //卡号
- unsigned char RFID[16]; //存放RFID
- unsigned char total=0;
- u8 KEY[6]={0xff,0xff,0xff,0xff,0xff,0xff};
- u8 AUDIO_OPEN[6] = {0xAA, 0x07, 0x02, 0x00, 0x09, 0xBC};
- unsigned char RFID1[16]={0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x80,0x29,0xff,0xff,0xff,0xff,0xff,0xff};
- /*函数声明*/
- unsigned char status;
- unsigned char s=0x08;
- /**************************************************************************************
- * 函数名:WriteRawRC 描述 :写RC522寄存器输入 :ucAddress,寄存器地址 ucValue,写入寄存器的值
- */
- void WriteRawRC ( u8 ucAddress, u8 ucValue )
- {
- u8 ch = UART3_ReadWriteByte (ucAddress& 0x3F); // 写入寄存器地址(最低6位为实际地址,次高为保留为0,最高位为1)
- if(ch != ucAddress) printf("not equal!!\r\n");
- UART3_ReadWriteByte (ucValue);
- }
- /**************************************************************************************
- * 函数名:ReadRawRC 读取寄存器的当前值
- */
- u8 ReadRawRC ( u8 ucAddress )
- {
- return UART3_ReadWriteByte((ucAddress&0x3F) | 0x80);
- }
- /**************************************************************************************
- * 函数名:ClearBitMask 对RC522寄存器清位
- */
- void ClearBitMask ( u8 ucReg, u8 ucMask )
- {
- u8 ucTemp;
- ucTemp = ReadRawRC ( ucReg );
- WriteRawRC ( ucReg, ucTemp & ( ~ ucMask) ); // clear bit mask
- }
- /**************************************************************************************
- * 函数名:SetBitMask 对RC522寄存器置位
- */
- void SetBitMask ( u8 ucReg, u8 ucMask )
- {
- u8 ucTemp;
- ucTemp = ReadRawRC ( ucReg );
- WriteRawRC ( ucReg, ucTemp | ucMask ); // set bit mask
- }
- /**************************************************************************************
- * 函数名:PcdAntennaOn 开启天线
- */
- void PcdAntennaOn ( void )
- {
- u8 uc;
- uc = ReadRawRC ( TxControlReg );
- if ( ! ( uc & 0x03 ) )
- SetBitMask(TxControlReg, 0x03);
- }
- /**************************************************************************************
- * 函数名:PcdAntennaOff 关闭天线
- */
- void PcdAntennaOff ( void )
- {
- ClearBitMask ( TxControlReg, 0x03 );
- }
- /**************************************************************************************
- * 描述 :设置RC522的工作方式 ucType,工作方式
- */
- void M500PcdConfigISOType ( u8 ucType )
- {
- if ( ucType == 'A') //ISO14443_A
- {
- ClearBitMask ( Status2Reg, 0x08 );
- WriteRawRC ( ModeReg, 0x3D );//3F
- WriteRawRC ( RxSelReg, 0x86 );//84
- WriteRawRC( RFCfgReg, 0x7F ); //4F
- WriteRawRC( TReloadRegL, 30 );//tmoLength);// TReloadVal = 'h6a =tmoLength(dec)
- WriteRawRC ( TReloadRegH, 0 );
- WriteRawRC ( TModeReg, 0x8D );
- WriteRawRC ( TPrescalerReg, 0x3E );
- delay_us ( 2 );
- PcdAntennaOn ();//开天线
- }
- }
- /**************************************************************************************
- * 函数名:PcdComMF522
- * 描述 :通过RC522和ISO14443卡通讯
- * 输入 :ucCommand,RC522命令字
- * pInData,通过RC522发送到卡片的数据
- * ucInLenByte,发送数据的字节长度
- * pOutData,接收到的卡片返回数据
- * pOutLenBit,返回数据的位长度
- * 返回 : 状态值 MI_OK,成功
- */
- char PcdComMF522 ( u8 ucCommand, u8 * pInData, u8 ucInLenByte, u8 * pOutData, u32 * pOutLenBit )
- {
- char cStatus = MI_ERR;
- u8 ucIrqEn = 0x00;
- u8 ucWaitFor = 0x00;
- u8 ucLastBits;
- u8 ucN;
- u32 ul;
- switch ( ucCommand )
- {
- case PCD_AUTHENT: //Mifare认证
- ucIrqEn = 0x12; //允许错误中断请求ErrIEn 允许空闲中断IdleIEn
- ucWaitFor = 0x10; //认证寻卡等待时候 查询空闲中断标志位
- break;
-
- case PCD_TRANSCEIVE: //接收发送 发送接收
- ucIrqEn = 0x77; //允许TxIEn RxIEn IdleIEn LoAlertIEn ErrIEn TimerIEn
- ucWaitFor = 0x30; //寻卡等待时候 查询接收中断标志位与 空闲中断标志位
- break;
-
- default:
- break;
- }
- WriteRawRC ( ComIEnReg, ucIrqEn | 0x80 ); //IRqInv置位管脚IRQ与Status1Reg的IRq位的值相反
- ClearBitMask ( ComIrqReg, 0x80 ); //Set1该位清零时,CommIRqReg的屏蔽位清零
- WriteRawRC ( CommandReg, PCD_IDLE ); //写空闲命令
- SetBitMask ( FIFOLevelReg, 0x80 ); //置位FlushBuffer清除内部FIFO的读和写指针以及ErrReg的BufferOvfl标志位被清除
-
- for ( ul = 0; ul < ucInLenByte; ul ++ )
- WriteRawRC ( FIFODataReg, pInData [ ul ] ); //写数据进FIFOdata
-
- WriteRawRC ( CommandReg, ucCommand ); //写命令
-
- if ( ucCommand == PCD_TRANSCEIVE )
- SetBitMask(BitFramingReg,0x80); //StartSend置位启动数据发送 该位与收发命令使用时才有效
-
- ul = 1000;//根据时钟频率调整,操作M1卡最大等待时间25ms
-
- do //认证 与寻卡等待时间
- {
- ucN = ReadRawRC ( ComIrqReg ); //查询事件中断
- ul --;
- }
- while ( ( ul != 0 ) && ( ! ( ucN & 0x01 ) ) && ( ! ( ucN & ucWaitFor ) ) ); //退出条件i=0,定时器中断,与写空闲命令
-
- ClearBitMask ( BitFramingReg, 0x80 ); //清理允许StartSend位
-
- if ( ul != 0 )
- {
- if ( ! (( ReadRawRC ( ErrorReg ) & 0x1B )) ) //读错误标志寄存器BufferOfI CollErr ParityErr ProtocolErr
- {
- cStatus = MI_OK;
- if ( ucN & ucIrqEn & 0x01 ) //是否发生定时器中断
- cStatus = MI_NOTAGERR;
- if ( ucCommand == PCD_TRANSCEIVE )
- {
- ucN = ReadRawRC ( FIFOLevelReg ); //读FIFO中保存的字节数
- ucLastBits = ReadRawRC ( ControlReg ) & 0x07; //最后接收到得字节的有效位数
- if ( ucLastBits )
- * pOutLenBit = ( ucN - 1 ) * 8 + ucLastBits; //N个字节数减去1(最后一个字节)+最后一位的位数 读取到的数据总位数
- else
- * pOutLenBit = ucN * 8; //最后接收到的字节整个字节有效
- if ( ucN == 0 )
- ucN = 1;
- if ( ucN > MAXRLEN )
- ucN = MAXRLEN;
- for ( ul = 0; ul < ucN; ul ++ )
- pOutData [ ul ] = ReadRawRC ( FIFODataReg );
- }
- }
- else
- cStatus = MI_ERR;
- //printf("ErrorReg=%d\r\n",ErrorReg);
- }
- SetBitMask ( ControlReg, 0x80 ); // stop timer now
- WriteRawRC ( CommandReg, PCD_IDLE );
- return cStatus;
- }
- //=========================================RC522_Handel================================================//
- bool RC522_READ(u8 * str)
- {
- status = PcdRequest(PICC_REQALL,CT);//寻卡
- if(status==MI_OK)//寻卡成功
- {
- status=MI_ERR;
- status = PcdAnticoll(SN);//防冲撞
- }
- if (status==MI_OK)//防衝撞成功
- {
- status=MI_ERR;
- status =PcdSelect(SN);
- }
- if(status==MI_OK)//選卡成功
- {
- status=MI_ERR;
- status =PcdAuthState(0x60,0x09,KEY,SN);
- }
- if(status==MI_OK)//驗證成功
- {
- status=MI_ERR;
- status=PcdRead(s,RFID);
- }
- if(status==MI_OK)//讀卡成功
- {
- status=MI_ERR;
- memset(str,0,10);
- memcpy(str,RFID,9); //显示卡的ID号
- return 1;
- }
-
- return 0;
- }
- //=========================================RC522_Handel================================================//
- bool RC522_WRITE(u8 * msg)
- {
- if(msg == NULL)return false;
- status = PcdRequest(PICC_REQALL,CT);//寻卡
- if(status==MI_OK)//寻卡成功
- {
- status=MI_ERR;
- status = PcdAnticoll(SN);//防冲撞
- }
- if (status==MI_OK)//防衝撞成功
- {
- status=MI_ERR;
- status =PcdSelect(SN);
- }
- if(status==MI_OK)//選卡成功
- {
- status=MI_ERR;
- status =PcdAuthState(0x60,0x09,KEY,SN);
- }
- if(status==MI_OK)//驗證成功
- {
- status=MI_ERR;
- status=PcdWrite(s,msg);
- }
- if(status==MI_OK)//写卡成功
- return true;
- return false;
- }
- /*********************************************************************************************************************
- * 函数名:PcdRequest 寻卡
- * 输入 :ucReq_code,寻卡方式
- * = 0x52,寻感应区内所有符合14443A标准的卡
- * = 0x26,寻未进入休眠状态的卡
- * pTagType,卡片类型代码
- * = 0x4400,Mifare_UltraLight
- * = 0x0400,Mifare_One(S50)
- * = 0x0200,Mifare_One(S70)
- * = 0x0800,Mifare_Pro(X))
- * = 0x4403,Mifare_DESFire
- * 返回 : 状态值 MI_OK,成功
- */
- char PcdRequest ( u8 ucReq_code, u8 * pTagType )
- {
- char cStatus;
- u8 ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
- ClearBitMask ( Status2Reg, 0x08 ); //清理指示MIFARECyptol单元接通以及所有卡的数据通信被加密的情况
- WriteRawRC ( BitFramingReg, 0x07 ); // 发送的最后一个字节的 七位
- SetBitMask ( TxControlReg, 0x03 ); //TX1,TX2管脚的输出信号传递经发送调制的13.56的能量载波信号
- ucComMF522Buf [ 0 ] = ucReq_code; //存入 卡片命令字
- cStatus = PcdComMF522( PCD_TRANSCEIVE,ucComMF522Buf, 1, ucComMF522Buf, & ulLen ); //寻卡
- if ( ( cStatus == MI_OK ) && ( ulLen == 0x10 ) ) //寻卡成功返回卡类型
- {
- * pTagType = ucComMF522Buf [ 0 ];
- * ( pTagType + 1 ) = ucComMF522Buf [ 1 ];
- }
- else
- cStatus = MI_ERR;
- return cStatus;
- }
- /************************************************************************************************************
- * 函数名:PcdAnticoll 防冲撞:pSnr,卡片序列号,4字节
- * 返回 : 状态值 MI_OK,成功
- */
- char PcdAnticoll ( u8 * pSnr )
- {
- char cStatus;
- u8 uc, ucSnr_check = 0;
- u8 ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
- ClearBitMask ( Status2Reg, 0x08 ); //清MFCryptol On位 只有成功执行MFAuthent命令后,该位才能置位
- WriteRawRC ( BitFramingReg, 0x00); //清理寄存器 停止收发
- ClearBitMask ( CollReg, 0x80 ); //清ValuesAfterColl所有接收的位在冲突后被清除
- ucComMF522Buf [ 0 ] = 0x93; //卡片防冲突命令
- ucComMF522Buf [ 1 ] = 0x20;
- cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 2, ucComMF522Buf, & ulLen);//与卡片通信
- if ( cStatus == MI_OK) //通信成功
- {
- for ( uc = 0; uc < 4; uc ++ )
- {
- * ( pSnr + uc ) = ucComMF522Buf [ uc ]; //读出UID
- ucSnr_check ^= ucComMF522Buf [ uc ];
- }
- if ( ucSnr_check != ucComMF522Buf [ uc ] )
- cStatus = MI_ERR;
- }
- SetBitMask ( CollReg, 0x80 );
- return cStatus;
- }
- /************************************************************************************************************
- * 函数名:CalulateCRC
- * 描述 :用RC522计算CRC16
- * 输入 :pIndata,计算CRC16的数组
- * ucLen,计算CRC16的数组字节长度
- * pOutData,存放计算结果存放的首地址
- */
- void CalulateCRC ( u8 * pIndata, u8 ucLen, u8 * pOutData )
- {
- u8 uc, ucN;
- ClearBitMask(DivIrqReg,0x04);
- WriteRawRC(CommandReg,PCD_IDLE);
- SetBitMask(FIFOLevelReg,0x80);
- for ( uc = 0; uc < ucLen; uc ++)
- WriteRawRC ( FIFODataReg, * ( pIndata + uc ) );
- WriteRawRC ( CommandReg, PCD_CALCCRC );
- uc = 0xFF;
- do
- {
- ucN = ReadRawRC ( DivIrqReg );
- uc --;
- } while ( ( uc != 0 ) && ! ( ucN & 0x04 ) );
-
- pOutData [ 0 ] = ReadRawRC ( CRCResultRegL );
- pOutData [ 1 ] = ReadRawRC ( CRCResultRegM );
- }
- /************************************************************************************************************
- * 函数名:PcdSelect
- * 描述 :选定卡片
- * 输入 :pSnr,卡片序列号,4字节
- * 返回 : 状态值
- * = MI_OK,成功
- * 调用 :外部调用
- */
- char PcdSelect ( u8 * pSnr )
- {
- char ucN;
- u8 uc;
- u8 ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
- ucComMF522Buf [ 0 ] = PICC_ANTICOLL1;
- ucComMF522Buf [ 1 ] = 0x70;
- ucComMF522Buf [ 6 ] = 0;
- for ( uc = 0; uc < 4; uc ++ )
- {
- ucComMF522Buf [ uc + 2 ] = * ( pSnr + uc );
- ucComMF522Buf [ 6 ] ^= * ( pSnr + uc );
- }
- CalulateCRC ( ucComMF522Buf, 7, & ucComMF522Buf [ 7 ] );
- ClearBitMask ( Status2Reg, 0x08 );
- ucN = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 9, ucComMF522Buf, & ulLen );
- if ( ( ucN == MI_OK ) && ( ulLen == 0x18 ) )
- ucN = MI_OK;
- else
- ucN = MI_ERR;
- return ucN;
- }
- /************************************************************************************************************
- * 函数名:PcdAuthState 验证卡片密码
- * 输入 :ucAuth_mode,密码验证模式
- * = 0x60,验证A密钥
- * = 0x61,验证B密钥
- * u8 ucAddr,块地址
- * pKey,密码
- * pSnr,卡片序列号,4字节
- * 返回 : 状态值MI_OK,成功
- */
- char PcdAuthState ( u8 ucAuth_mode, u8 ucAddr, u8 * pKey, u8 * pSnr )
- {
- char cStatus;
- u8 uc, ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
- ucComMF522Buf [ 0 ] = ucAuth_mode;
- ucComMF522Buf [ 1 ] = ucAddr;
- for ( uc = 0; uc < 6; uc ++ )
- ucComMF522Buf [ uc + 2 ] = * ( pKey + uc );
- for ( uc = 0; uc < 6; uc ++ )
- ucComMF522Buf [ uc + 8 ] = * ( pSnr + uc );
- cStatus = PcdComMF522 ( PCD_AUTHENT, ucComMF522Buf, 12, ucComMF522Buf, & ulLen );
- if ( ( cStatus != MI_OK ) || ( ! ( ReadRawRC ( Status2Reg ) & 0x08 ) ) )
- {
- if(cStatus != MI_OK)
- printf("666");
- else
- printf("888");
- cStatus = MI_ERR;
- }
- return cStatus;
- }
- /**********************************************************************************************
- * 函数名:PcdWrite B写数据到M1卡一块 NpData,写入的数据,16字节
- * 返回 : 状态值MI_OK,成功
- */
- char PcdWrite ( u8 ucAddr, u8 * pData )
- {
- char cStatus;
- u8 uc, ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
-
- ucComMF522Buf [ 0 ] = PICC_WRITE;
- ucComMF522Buf [ 1 ] = ucAddr;
- CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );
- cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen );
- if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )
- cStatus = MI_ERR;
- if ( cStatus == MI_OK )
- {
- memcpy(ucComMF522Buf, pData, 16);
- for ( uc = 0; uc < 16; uc ++ )
- ucComMF522Buf [ uc ] = * ( pData + uc );
- CalulateCRC ( ucComMF522Buf, 16, & ucComMF522Buf [ 16 ] );
- cStatus = PcdComMF522 ( PCD_TRANSCEIVE, ucComMF522Buf, 18, ucComMF522Buf, & ulLen );
- if ( ( cStatus != MI_OK ) || ( ulLen != 4 ) || ( ( ucComMF522Buf [ 0 ] & 0x0F ) != 0x0A ) )
- cStatus = MI_ERR;
- }
- return cStatus;
- }
- /**********************************************************************************************
- * 函数名:PcdRead读取M1卡一块数据 pData,读出的数据,16字节
- * 返回 : 状态值 MI_OK,成功
- */
- char PcdRead ( u8 ucAddr, u8 * pData )
- {
- char cStatus;
- u8 uc, ucComMF522Buf [ MAXRLEN ];
- u32 ulLen;
- ucComMF522Buf [ 0 ] = PICC_READ;
- ucComMF522Buf [ 1 ] = ucAddr;
- CalulateCRC ( ucComMF522Buf, 2, & ucComMF522Buf [ 2 ] );
- cStatus = PcdComMF522 (PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, & ulLen);
- if ( ( cStatus == MI_OK ) && ( ulLen == 0x90 ) )
- {
- for ( uc = 0; uc < 16; uc ++ )
- * ( pData + uc ) = ucComMF522Buf [ uc ];
- }
- else
- cStatus = MI_ERR;
- return cStatus;
- }
- /**********************************************************************************************
- */
- /*
- * 函数名:PcdRese
- * 描述 :复位RC522
- */
- void PcdReset ( void )
- {
- delay_us ( 4 );
- WriteRawRC ( CommandReg, 0x0f );
- while( ReadRawRC ( CommandReg ) & 0x10 );
- ReadRawRC ( CommandReg );
- delay_us ( 5 );
- WriteRawRC ( ModeReg, 0x3D ); //定义发送和接收常用模式 和Mifare卡通讯,CRC初始值0x6363
- WriteRawRC ( TReloadRegL, 30 ); //16位定时器低位
- WriteRawRC ( TReloadRegH, 0 ); //16位定时器高位
- WriteRawRC ( TModeReg, 0x8D ); //定义内部定时器的设置
- WriteRawRC ( TPrescalerReg, 0x3E ); //设置定时器分频系数
- WriteRawRC ( TxAutoReg, 0x40 ); //调制发送信号为100%ASK
- }
- /* 该测试用例测试中 */
- void test(void){
- while(1){
- printf("================================\r\n");
- delay_ms(1000);
- u32 i = 0;
- while(i<0x40){
- u8 ch = ReadRawRC(i);
- printf("%02x ",ch);
- i++;
- delay_ms(10);
- if(i%16 == 0)
- printf("\r\n");
- }
-
- static u32 t = 0;
- if(t++ == 5){
- WriteRawRC(WaterLevelReg,0x01);
- u8 ch = ReadRawRC(WaterLevelReg);
- printf("%02x\r\n",ch);
- }else if(t == 8){
- WriteRawRC(WaterLevelReg,0x02);
- u8 ch = ReadRawRC(WaterLevelReg);
- printf("%02x\r\n",ch);
- }else if(t == 12){
- WriteRawRC(WaterLevelReg,0x03);
- u8 ch = ReadRawRC(WaterLevelReg);
- printf("%02x\r\n",ch);
- }
- }
- }</font>
复制代码 下发是头文件rc522.h- <font face="微软雅黑" size="3">#ifndef _RC522_H_
- #define _RC522_H_
- #include "sys.h"
- bool RC522_READ(u8 * str); //读卡
- bool RC522_WRITE(u8 * msg); //写卡
- void RC522_Init(void); //初始化
- void test(void);
- #endif
- </font>
复制代码 最后是我用来测试的main文件
包含写卡,和读卡测试。亲测可以使用。
- <font face="微软雅黑" size="3">#include "stm32f10x.h"
- #include "uart.h"
- #include "sys.h"
- #include "rc522.h"
- int main(void)
- {
- u8 IC[50] = {0};
- delay_init();
- UART1_init();
- delay_ms(2000);
- RC522_Init();
- printf("RC522_UART_TEST...\r\n");
-
- printf(" 写卡开始...\r\n");
- while(!RC522_WRITE((u8 *)"12121212")){};
- printf(" 写卡成功...\r\n");
-
- while(1){
- if(RC522_READ(IC)){
- printf("%s\r\n",IC);
- delay_ms(500);
- }
- delay_ms(100);
- printf("waitting...\r\n");
- }
- }</font>
复制代码
|