?? rc500.c
字號(hào):
//ICC-AVR application builder : 2008-04-18 08:36:23
//Target : M64
//Crystal: 8.0000Mhz
#include <iom64v.h>
#include <macros.h>
#include "RC500.h"
#include "uart.h"
/*****************************變量定義*****************************************/
MfCmdInfo Info;
/*****************************延時(shí)程序*****************************************/
void Delay_1us(void)
{
asm("nop");
}
void Delay_us(uint16 n)
{
uint16 i;
for(i=0; i<n; i++)Delay_1us();
}
void Delay_1ms(void)
{
uint16 i;
for(i=0; i<1142; i++);
}
void Delay_ms(uint16 n)
{
uint16 i;
for(i=0; i<n; i++)Delay_1ms();
}
/*********************************硬件驅(qū)動(dòng)程序*********************************/
void WriteIO(BYTE Address,BYTE value)
{
WORD addr;
addr = 0x2000 | Address;
(*(volatile unsigned char *)0x2000) = (Address>>3) | 0x80; //選擇寄存器頁(yè)
(*(volatile unsigned char *)addr) = value; //寫入一個(gè)字節(jié)
}
BYTE ReadIO(BYTE Address)
{
WORD addr;
addr = 0x2000 | Address;
(*(volatile unsigned char *)0x2000) = (Address>>3) | 0x80; //選擇寄存器頁(yè)
return (*(volatile unsigned char *)addr); //讀取一個(gè)字節(jié)
}
/*****************************RC500功能程序************************************/
BYTE M500PcdReset(void)
{
uint16 timecnt;
CLR_RC500RST();
Delay_ms(25);
SET_RC500RST();
Delay_ms(20);
CLR_RC500RST();
Delay_ms(10);
timecnt=1000;
while((ReadIO(RegCommand)&0x3F) & timecnt--);
if(!timecnt)return 1;
if(ReadIO(RegCommand)!=0x00)return 1;
return 0;
}
//配置RC500內(nèi)部寄存器函數(shù)
BYTE M500PcdConfig(void)
{
if (!M500PcdReset())
{
WriteIO(RegClockQControl,0x00); //Q時(shí)鐘復(fù)位
WriteIO(RegClockQControl,0x40); //Q時(shí)鐘寫入0x40
Delay_us(150); //延時(shí)100us以上
WriteIO(RegClockQControl,0x00); //Q時(shí)鐘清零
WriteIO(RegBitPhase,0xAD); //寫B(tài)itPhase寄存器
WriteIO(RegRxThreshold,0xFF); //RxThreshold寄存器寫入0FFH
WriteIO(RegRxControl2,0x01); //RxControl2寄存器寫入01H
WriteIO(RegFIFOLevel,0x1A); //設(shè)置FIFO上溢和下溢的界限
WriteIO(RegTimerControl,0x02); //設(shè)置數(shù)據(jù)發(fā)送完成后停止定時(shí)器
WriteIO(RegIRqPinConfig,0x03); //配置IRQ管腳的輸出狀態(tài)
M500PcdRfReset(1); //打開(kāi)天線
WriteIO(RegMfOutSelect,0x02); //選擇輸出到管腳MFOUT的信號(hào)為來(lái)自內(nèi)部編碼的調(diào)制信號(hào)
return 0;
}
else
return 1;
}
BYTE M500PcdRfReset(BYTE val)
{
if(val)
{
ClearBitMask(RegTxControl,0x03);
Delay_ms(2);
SetBitMask(RegTxControl,0x03);
}
else
{
ClearBitMask(RegTxControl,0x03);
}
return 0;
}
//置一位
BYTE SetBitMask(BYTE reg,BYTE mask)
{
BYTE tmp = 0x00;
tmp = ReadIO(reg);
WriteIO(reg,tmp | mask); // set bit mask
return 0x00;
}
//清一位
BYTE ClearBitMask(BYTE reg,BYTE mask)
{
BYTE tmp = 0x00;
tmp = ReadIO(reg);
WriteIO(reg,tmp & ~mask); // clear bit mask
return 0x00;
}
//發(fā)送命令
BYTE M500PcdCmd(void)
{
BYTE i,n;
BYTE lastBits;
BYTE irqEn = 0x00;
BYTE waitFor = 0x00;
WORD timecnt = 0;
switch(Info.cmd)
{
case PCD_IDLE:
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2:
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG:
case PCD_LOADKEYE2:
case PCD_AUTHENT1:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2:
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE:
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE:
irqEn = 0x3D;
waitFor = 0x04;
break;
default: return 1;
}
WriteIO(RegInterruptEn,0x7F); //清除中斷使能
WriteIO(RegInterruptRq,0x7F); //清除中斷標(biāo)志
WriteIO(RegCommand,PCD_IDLE); //清除Command寄存器
SetBitMask(RegControl,0x01); //清除FIFO指針
for(i=0; i<Info.nBytesToSend; i++)
WriteIO(RegFIFOData,Info.SerBuffer[i]); //將數(shù)據(jù)寫入FIFO
irqEn |= 0x20;
waitFor |= 0x20;
WriteIO(RegInterruptEn,irqEn | 0x80); //打開(kāi)中斷
WriteIO(RegCommand,Info.cmd); //將命令寫入命令寄存器
timecnt=1000;
while(!(ReadIO(RegInterruptRq) & waitFor || !(timecnt--)));
WriteIO(RegInterruptEn,0x7F); //清除中斷使能
WriteIO(RegInterruptRq,0x7F); //清除中斷標(biāo)志寄存器
SetBitMask(RegControl,0x04); //停止定時(shí)器
WriteIO(RegCommand,PCD_IDLE); //清除命令寄存器
if(!timecnt)
{ USART_String("timeout!\n");return 1; } //超時(shí)退出,返回1
if(ReadIO(RegErrorFlag)&0x17)
{ USART_Hex(ReadIO(RegErrorFlag)&0x3F);USART_String("ERRor!\n");return 1; } //如果產(chǎn)生錯(cuò)誤則返回1
if(Info.cmd == PCD_TRANSCEIVE)
{
n = ReadIO(RegFIFOLength); //讀取FIFO中數(shù)據(jù)的總字節(jié)數(shù)
lastBits = ReadIO(RegSecondaryStatus) & 0x07;
Info.nBytesReceived = n;
if(lastBits)
Info.nBitsReceived = (n-1) * 8 + lastBits;
else
Info.nBitsReceived = n * 8;
if(n==0)n=1;
for(i=0; i<n; i++)
Info.SerBuffer[i]=ReadIO(RegFIFOData);
/*USART_Hex(n);
USART_Hex(lastBits);
for(i=0; i<n; i++)
USART_Hex(Info.SerBuffer[i]);*/
}
return 0;
}
//尋卡
BYTE M500PiccCommonRequest(void)
{
WriteIO(RegTimerClock,0x09); //設(shè)置定時(shí)器分頻
WriteIO(RegTimerReload,0xA0); //設(shè)置定時(shí)器初值
ClearBitMask(RegControl,0x08); //寄存器Control清0
WriteIO(RegBitFraming,0x07); //寄存器BitFramming寫入07H
WriteIO(RegChannelRedundancy,0x03); //選擇RF信道上數(shù)據(jù)完整性檢測(cè)的類型和模式
SetBitMask(RegTxControl,0x03); //打開(kāi)天線
//ResetInfo(Info);
Info.cmd = PCD_TRANSCEIVE; //命令為發(fā)送命令
Info.nBytesToSend = 1; //發(fā)送字節(jié)長(zhǎng)度為1
Info.nBytesReceived = 2; //接收字節(jié)長(zhǎng)度為2
Info.SerBuffer[0] = PICC_REQIDL; //數(shù)據(jù)為尋卡命令
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(Info.nBitsReceived != 16) return 1;//判斷接收到是不是16位,否則是錯(cuò)誤的
if(Info.SerBuffer[0]==0x04) return 0; //如果第一個(gè)字節(jié)是0x04,則是One卡,尋卡成功
else return 1; //否則返回錯(cuò)誤狀態(tài)
}
//防沖突
BYTE M500PiccCascAnticoll(void)
{
BYTE i;
BYTE snr_check=0;
BYTE status=0;
WriteIO(RegTimerClock,0x07); //設(shè)置定時(shí)器分頻
WriteIO(RegTimerReload,0X6A); //設(shè)置定時(shí)器初值
WriteIO(RegDecoderControl,0x28); //防沖突處理
ClearBitMask(RegControl,0x08); //
WriteIO(RegChannelRedundancy,0x03); //
Info.cmd = PCD_TRANSCEIVE; //命令為發(fā)送命令
Info.nBytesToSend = 2; //發(fā)送字節(jié)長(zhǎng)度為1
Info.nBytesReceived = 5; //接收字節(jié)長(zhǎng)度為2
Info.SerBuffer[0] = PICC_ANTICOLL1; //數(shù)據(jù)0為防沖突命令
Info.SerBuffer[1] = 0x20;
if(M500PcdCmd())status = 1;
else
{
for(i=0;i<4;i++)
snr_check^=Info.SerBuffer[i]; //生成校驗(yàn)數(shù)據(jù)
if(snr_check!=Info.SerBuffer[i]) //對(duì)比校驗(yàn)數(shù)據(jù)是否正確
status = 1;
else
{
for(i=0;i<5;i++)
Info.CardNumber[i] = Info.SerBuffer[i]; //將卡號(hào)和CRC裝到卡號(hào)緩存
}
}
ClearBitMask(RegDecoderControl,0x20); //結(jié)束防沖突處理
return status;
}
//選卡
BYTE M500PiccCascSelect(void)
{
BYTE i;
WriteIO(RegTimerClock,0x07); //設(shè)置定時(shí)器分頻
WriteIO(RegTimerReload,0X6A); //設(shè)置定時(shí)器初值
WriteIO(RegChannelRedundancy,0x0F); //
ClearBitMask(RegControl,0x08); //
Info.cmd = PCD_TRANSCEIVE; //命令為發(fā)送命令
Info.nBytesToSend = 7; //發(fā)送字節(jié)長(zhǎng)度為1
Info.nBytesReceived = 1; //接收字節(jié)長(zhǎng)度為2
Info.SerBuffer[0] = PICC_ANTICOLL1; //數(shù)據(jù)0為選卡命令
Info.SerBuffer[1] = 0x70;
for(i=0; i<5; i++)
Info.SerBuffer[i+2] = Info.CardNumber[i];
if(M500PcdCmd())return 1;
if(Info.SerBuffer[0] != 0x08)return 1;
return 0;
}
//直接驗(yàn)證密碼
BYTE M500PiccAuthKey(BYTE *KEY,BYTE Sector,BYTE Block)
{
Info.cmd = PCD_LOADKEY; //命令為發(fā)送命令
Info.nBytesToSend = 0x0C; //發(fā)送字節(jié)長(zhǎng)度為1
Info.nBytesReceived = 0; //接收字節(jié)長(zhǎng)度為2
M500HostCodeKey(KEY,Info.SerBuffer);//將密碼轉(zhuǎn)換成固定格式
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(M500PiccAuthState(Sector*4+Block))
return 1;//Crytol卡驗(yàn)證子程序
return 0;
}
//密碼格式轉(zhuǎn)換
void M500HostCodeKey(BYTE *uncoded,BYTE *coded)
{
BYTE cnt = 0;
BYTE ln = 0;
BYTE hn = 0;
for (cnt=0; cnt<6; cnt++)
{
ln = uncoded[cnt] & 0x0F;
hn = uncoded[cnt] >> 4;
coded[cnt * 2 + 1] = (~ln << 4) | ln;
coded[cnt * 2 ] = (~hn << 4) | hn;
}
}
//Crystol卡驗(yàn)證
BYTE M500PiccAuthState(BYTE Block)
{
BYTE i;
Info.cmd = PCD_AUTHENT1; //命令為發(fā)送命令
Info.nBytesToSend = 0x06; //發(fā)送字節(jié)長(zhǎng)度為1
Info.nBytesReceived = 0; //接收字節(jié)長(zhǎng)度為2
Info.SerBuffer[0] = PICC_AUTHENT1A; //Authen1命令
Info.SerBuffer[1] = Block; //塊號(hào)
for(i=0; i<4; i++) //卡號(hào)
Info.SerBuffer[i+2] = Info.CardNumber[i];
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(ReadIO(RegSecondaryStatus)&0x07)return 1;
Info.cmd = PCD_AUTHENT2; //Authen2命令
Info.nBytesToSend = 0; //發(fā)送數(shù)據(jù)為0字節(jié)
Info.nBytesReceived = 0; //接收數(shù)據(jù)為0字節(jié)
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(ReadIO(RegControl)==0x08)return 0;//值是否為0x08
else return 1;
}
//讀數(shù)據(jù)
BYTE M500PiccRead(BYTE Sector,BYTE Block)
{
BYTE tmp = 0;
WriteIO(RegTimerClock,0x09); //設(shè)置定時(shí)器分頻
WriteIO(RegTimerReload,0xA0); //設(shè)置定時(shí)器初值
WriteIO(RegChannelRedundancy,0x0F);
ResetInfo(Info);
Info.cmd = PCD_TRANSCEIVE;
Info.SerBuffer[0] = PICC_READ;
Info.SerBuffer[1] = Sector*4+Block;
Info.nBytesToSend = 2;
Info.nBytesReceived = 0x10; //接收字節(jié)長(zhǎng)度為
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(Info.nBytesReceived != 16) return 1;
for(tmp=0;tmp<0x10;tmp++)
USART_Hex(Info.SerBuffer[tmp]);
return 0;
}
//寫數(shù)據(jù)
BYTE M500PiccWrite(BYTE Sector,BYTE Block)
{
Info.cmd = PCD_TRANSCEIVE;
Info.SerBuffer[0] = PICC_WRITE;
Info.SerBuffer[1] = Sector*4+Block;
Info.nBytesToSend = 2;
Info.nBytesReceived = 0; //接收字節(jié)長(zhǎng)度為
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
WriteIO(RegTimerClock,0x09); //設(shè)置定時(shí)器分頻
WriteIO(RegTimerReload,0xA0); //設(shè)置定時(shí)器初值
WriteIO(RegChannelRedundancy,0x0F);
Info.cmd = PCD_TRANSCEIVE;
Info.nBytesToSend = 0x10;
Info.nBytesReceived = 0; //接收字節(jié)長(zhǎng)度為
if(M500PcdCmd())return 1; //調(diào)用發(fā)送命令子函數(shù)
if(Info.SerBuffer[0]==0x0A)return 0;
return 1;
}
/*
//裝載密碼到EEPORM
BYTE M500PcdLoadKeyE2(WORD StartAddr)
{
BYTE key[6];
Info.cmd = PCD_LOADKEYE2; //命令為發(fā)送命令
Info.nBytesToSend = 2; //發(fā)送字節(jié)長(zhǎng)度為1
Info.SerBuffer[0] = StartAddr & 0x0FF; //數(shù)據(jù)0為防沖突命令
Info.SerBuffer[1] = StartAddr >> 8;
M500HostCodeKey(key,&Info.SerBuffer[2]);
if(M500PcdCmd())return 1;
return 0;
}
//終止卡操作
BYTE M500PiccHalt(void)
{
ResetInfo(Info);
Info.SerBuffer[0] = PICC_HALT ; // Halt command code
Info.SerBuffer[1] = 0x00; // dummy address
Info.nBytesToSend = 2;
if(M500PcdCmd()) return 0;
WriteIO(RegCommand,PCD_IDLE);
return 1;
}
*/
/******************************************************************************/
void Device_Init(void)
{
MCUCR |= (1<<SRE); //使能總線
XMCRA = 0x00;
XMCRB = 0x00;
DDR_RC500RST();
DDR_RC500IRQ();
//LED
DDRB |= (1<<3);
PORTB &= ~(1<<3);
//A0,A1,A2
DDRE |= (1<<3) | (1<<4) | (1<<5);
PORTE |= (1<<3) | (1<<4) & ~(1<<5);
/*EICRA = 0x20; //下降沿觸發(fā)
EICRB = 0x00;
EIMSK = 0x04; //外部中斷2
SEI();*/
}
void main(void)
{
BYTE KEY[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Device_Init();
USART_Init();
USART_String("Start to test RC500!\n");
//初始化并配置寄存器
if(M500PcdConfig())USART_String("Test error!\n");
else USART_String("Test OK!\n");
//尋卡
if(!M500PiccCommonRequest())USART_String("Card has found!\n");
else USART_String("Card has not found!\n");
//防沖突
if(!M500PiccCascAnticoll())USART_String("CascAnticoll success!\n");
else USART_String("CascAnticoll failure!\n");
//選卡
if(!M500PiccCascSelect())USART_String("Card Select success!\n");
else USART_String("Card Select failure!\n");
//直接驗(yàn)證密碼
if(!M500PiccAuthKey(KEY,1,1))USART_String("Password validate success!\n");
else USART_String("Password validate failure!\n");
//讀數(shù)據(jù)
M500PiccRead(1,1);
//寫數(shù)據(jù)
if(!M500PiccWrite(1,1))USART_String("Write success!\n");
else USART_String("Write Failure!\n");
while(1);
}
/*
#pragma interrupt_handler int2_isr:iv_INT2
void int2_isr(void)
{
BYTE i,temp;
BYTE irqMask;
BYTE irqBits;
irqMask = ReadIO(RegInterruptEn);
irqBits = ReadIO(RegInterruptRq) & irqMask;
Info.irqSource |= irqBits;
USART_Hex(temp = ReadIO(RegInterruptRq));
if(temp&0x01)
{
for(i=0; i<Info.nBytesToSend; i++)
WriteIO(RegFIFOData,Info.SerBuffer[i]); //將數(shù)據(jù)寫入FIFO
WriteIO(RegInterruptRq,0x01);
}
}
*/
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -