基于RC522的非接触式IC卡读卡器设计(含程序) 下载本文

}

unsigned char exchange(unsigned char n) { unsigned char a; if(n<10) {a=n+48; } else {a=n+55; }

return a; }

//RFID开发板模式下处理程序 void board_process( void ) {

INT8U CardReadBuf[16]; INT8U CardWriteBuf[16]; INT8U CardUid[16];

unsigned char i,n,j=0;//寻天线区内未进入休眠状态的卡,返回卡片类型 2字节,从&FromCardRevBuf地址开始存储

if( PcdRequest( PICC_REQIDL, &FromCardRevBuf[0] ) != MI_OK ) {

//display_no_id();//可以在这里显示调试信息

//bWarn = 1;这里不要添加此条,信息,这里也不要添加其他信息,否则程序一直执行。

//因为程序一直寻卡么,没卡肯定不OK,就执行这里的程序了么!!!

return; }

//防冲撞,返回卡的序列号 4字节,从&FromCardRevBuf地址开始存储 if( PcdAnticoll( &FromCardRevBuf[2] ) != MI_OK ) {

//display_no_id(); bWarn = 1; return; }

if( PcdSelect( &FromCardRevBuf[2] ) != MI_OK )//选卡

第 46 页 共 61 页

中北大学2016届毕业设计说明书

for( i = 0; i < 3; i++ ) {

BEEP_ON;

delay_ms(200); BEEP_OFF;

delay_ms(200); }

中北大学2016届毕业设计说明书

{

bWarn = 1; return; } if( PcdAuthState( PICC_AUTHENT1A, 1, DefaultKeyABuf, &FromCardRevBuf[2] ) != MI_OK )// 验证密码,可以更改块区 {

bWarn = 1; return; }

memcpy( CardWriteBuf, tangliankai, 16 );

if( PcdWrite( 1, CardWriteBuf ) != MI_OK )//写卡 {

memset( CardWriteBuf, 0x00, 16 ); bWarn = 1; return; }

if( PcdRead( 0, CardReadBuf ) != MI_OK )// 读块0 {

//display_error();//显示错误信息,方便查错 bWarn = 1; return; }

for(i=0;i<4;i++) {n=CardReadBuf[i]; n=n>>4;

CardUid[j]=exchange(n); j=j+1;

n=CardReadBuf[i]; n&=0x0f;

CardUid[j]=exchange(n); j=j+1;

CardUid[j]=0x20; j=j+1; }

send_bytes(&CardUid,12);//发送卡的序列号

if( PcdRead( 1, CardReadBuf ) != MI_OK )// 读数据,可以更改块区 {

//display_error();//显示错误信息,方便查错 bWarn = 1; return; }

send_bytes(&CardReadBuf,16);

第 47 页 共 61 页

中北大学2016届毕业设计说明书

bPass=1;

send_byte(0x0d);

send_byte(0x0a); //换行 PcdHalt(); }

void delay_ms( INT16U tms ) {

INT16U i;

while( tms-- ) {

for( i = 0; i < 300; i ++ ) {

nop(); nop(); nop(); nop(); nop(); nop(); } } }

//------------------------------------------ // 读SPI数据

// return SPIData

//------------------------------------------ unsigned char SPIReadByte(void) {

unsigned char SPICount; // Counter used to clock out the data unsigned char SPIData; SPIData = 0;

for (SPICount = 0; SPICount < 8; SPICount++) // Prepare to clock in the data to be read {

SPIData <<=1; // Rotate the data CLR_SPI_CK; //nop();//nop(); // Raise the clock to clock the data out of the MAX7456 if(STU_SPI_MISO) {

SPIData|=0x01; }

SET_SPI_CK; //nop();//nop(); // Drop the clock ready for the next bit

} // and loop back

第 48 页 共 61 页

中北大学2016届毕业设计说明书

return (SPIData); // Finally return the read data }

//------------------------------------------ // 写SPI数据

//------------------------------------------ void SPIWriteByte(unsigned char SPIData) {

unsigned char SPICount; // Counter used to clock out the data

for (SPICount = 0; SPICount < 8; SPICount++) {

if (SPIData & 0x80) {

SET_SPI_MOSI; } else {

CLR_SPI_MOSI; }

nop();nop();

CLR_SPI_CK;nop();nop(); SET_SPI_CK;nop();nop(); SPIData <<= 1; } }

///////////////////////////////////////////////////////////////////// //功 能:读RC522寄存器

//参数说明:Address[IN]:寄存器地址 //返 回:读出的值

///////////////////////////////////////////////////////////////////// unsigned char Read_Reg_RC(unsigned char Address) {

unsigned char ucAddr; unsigned char ucResult=0; CLR_SPI_CS;

ucAddr = ((Address<<1)&0x7E)|0x80;//地址格式 SPIWriteByte(ucAddr); ucResult=SPIReadByte(); SET_SPI_CS;

return ucResult; }

/////////////////////////////////////////////////////////////////////

第 49 页 共 61 页

中北大学2016届毕业设计说明书

//功 能:写RC522寄存器

//参数说明:Address[IN]:寄存器地址 // value[IN]:写入的值

///////////////////////////////////////////////////////////////////// void Write_Reg_RC(unsigned char Address, unsigned char value) {

unsigned char ucAddr;

CLR_SPI_CS; //启动SPI

//地址字节格式:第7位(1读/0写) 第6-1位(地址位) 位0(0保留、未用)

//MFRRC522 7.2.4地址字节

ucAddr = ((Address<<1)&0x7E); SPIWriteByte(ucAddr); SPIWriteByte(value); SET_SPI_CS; }

///////////////////////////////////////////////////////////////////// //功 能:清RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:清位值

///////////////////////////////////////////////////////////////////// void ClearBitMask(unsigned char reg,unsigned char mask) {

char tmp = 0x00;

tmp = Read_Reg_RC(reg);

Write_Reg_RC(reg, tmp & ~mask); // 若mask=0x01,则使寄存器REG的位0置0 }

///////////////////////////////////////////////////////////////////// //功 能:置RC522寄存器位 //参数说明:reg[IN]:寄存器地址 // mask[IN]:置位值

///////////////////////////////////////////////////////////////////// void SetBitMask(unsigned char reg,unsigned char mask) {

char tmp = 0x00;

tmp = Read_Reg_RC(reg);

Write_Reg_RC(reg,tmp | mask); // 若mask=0x01,位0置1 }

///////////////////////////////////////////////////////////////////// //用MF522计算CRC16函数(CRC预置在RC522的ModeReg中定义)

//长为len的pindata数据写入FIFO,再校验,其2个字节结果存入pOutData //校验由硬件完成,我们只需要写数据及读校验后的CRC结果

第 50 页 共 61 页