//************************************************************************* #include //------------------------------------------------------------------------------------------------------ extern void SPI1_Config(void); extern unsigned char SPI1_ReadWriteByte(unsigned char TxData); extern unsigned char Read_RC531_IRQ(void); /* RC531RST 引脚 */ //#define RC531RST 0x00008000 //#define RC531RST_GPIO() PINSEL0 &= ~((unsigned int)0x03 nBytesReceived-1) * 8 + lastBits; else info->nBitsReceived += info->nBytesReceived * 8; } }else{ info->collPos = 0x00; } } MpIsrInfo = 0; MpIsrOut = 0; return status; } /**************************************************************************** * 名 称:M500PcdConfig * 功 能:复位rc500 * 入口参数:无 * 出口参数:0正常,其它错误码 ****************************************************************************/ char M500PcdReset(){ char status = MI_OK; unsigned int timecnt=0; RC531RST_CLR(); delay_1ms(25); RC531RST_SET(); delay_50us(200); RC531RST_CLR(); delay_50us(50); timecnt = 50000; // a = (ReadIO(RegCommand) & 0x3F); while ( (ReadIO(RegCommand) & 0x3F) && timecnt){ timecnt--; } if(!timecnt){ status = MI_RESETERR; }else{ if (ReadIO(RegCommand) != 0x00) { status = MI_INTERFACEERR; } } return status; } |
RE:发一个读写RC531的STM32F2XX的DEMO
* 名 称:M500PcdRfReset
* 功 能:复位RF卡
* 入口参数:MS 时间 毫秒
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdRfReset(unsigned char ms){
char status = MI_OK;
if(ms){
ClearBitMask(RegTxControl,0x03); //0x11
delay_1ms(2);
SetBitMask(RegTxControl,0x03); //输出信号将传递由发送数据调制的13 56MHz 能量载波
}else{
ClearBitMask(RegTxControl,0x03);
}
WriteIO(RegCwConductance, 0x3f); //0x3f, 设置输出驱动的电导系数
return status;
}
/****************************************************************************
* 名 称:M500PcdConfig
* 功 能:配置RC500内部寄存器函数
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char M500PcdConfig(void){
char status;
if ((status = M500PcdReset()) == MI_OK){
WriteIO(RegClockQControl,0x00); //0x1f 控制时钟产生用于90o相移的Q 信道时钟
WriteIO(RegClockQControl,0x40);
delay_50us(2);
ClearBitMask(RegClockQControl,0x40); //如果该位为0 Q-时钟在复位后和从卡接收数据后自动校准
WriteIO(RegBitPhase,0xAD); //0x1b 选择发送器和接收器时钟之间的位相位
WriteIO(RegRxThreshold,0xFF); //0x1c 选择位解码器的阀值
WriteIO(RegRxControl2,0x01); //0x1e 控制解码器的状态并定义接收器的输入源
WriteIO(RegFIFOLevel,0x1A); //0x29 定义FIFO 上溢和下溢警告界限
WriteIO(RegTimerControl,0x02); //0x2b 选择定时器的起始和停止条件
WriteIO(RegIRqPinConfig,0x03); //0x2d 配置管脚IRQ 的输出状态
M500PcdRfReset(1);
}
return status;
}
/****************************************************************************
* 名 称:M500PcdMfOutSelect
* 功 能:Select Command defined in ISO14443(MIFARE)
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdMfOutSelect(unsigned char type){
WriteIO(RegMfOutSelect,type&0x7); //0x26 选择输出到管脚MFOUT 的内部信号
//来自内部编码器的调制信号包络Miller 编码
return MI_OK;
}
/****************************************************************************
* 名 称:MfConfig
* 功 能:芯片初始化
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char MfConfig(void){
char status=MI_OK;
char bak;
bak=M500PcdConfig();
if(bak!=MI_OK)status=bak;
bak=M500PcdMfOutSelect(2);
if(bak!=MI_OK)status=bak;
return status;
}
/****************************************************************************
* 名 称:M500PcdSetTmo
* 功 能:设置定时时间
* 入口参数:tmoLength 时间
* 出口参数:无
****************************************************************************/
void M500PcdSetTmo(unsigned char tmoLength){
switch(tmoLength){
case 1:
WriteIO(RegTimerClock,0x07);
WriteIO(RegTimerReload,0x6a);
break;
case 2:
WriteIO(RegTimerClock,0x07);
WriteIO(RegTimerReload,0xa0);
break;
case 3:
WriteIO(RegTimerClock,0x09);
WriteIO(RegTimerReload,0xa0);
break;
case 4:
WriteIO(RegTimerClock,0x09);
WriteIO(RegTimerReload,0xff);
break;
case 5:
WriteIO(RegTimerClock,0x0b);
WriteIO(RegTimerReload,0xff);
break;
case 6:
WriteIO(RegTimerClock,0x0d);
WriteIO(RegTimerReload,0xff);
break;
case 7:
WriteIO(RegTimerClock,0x0f);
WriteIO(RegTimerReload,0xff);
break;
default:
WriteIO(RegTimerClock,0x15);
WriteIO(RegTimerReload,tmoLength);
break;
}
}
/****************************************************************************
* 名 称:M500PiccCommonRequest
* 功 能:寻卡,防冲突,选择卡 返回卡类型(2 bytes)+ 卡系列号(4 bytes)
* 入口参数:req_code 寻卡指令 request code ALL = 0x52 or IDLE = 0x26
agq 返回卡类型
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccCommonRequest(unsigned char req_code,unsigned char *atq){
char status = MI_OK;
M500PcdSetTmo(3);
WriteIO(RegChannelRedundancy,0x03); //奇校验
ClearBitMask(RegControl,0x08); //选择定时器的起始和停止条件-当数据接收结束时定时器自动停
WriteIO(RegBitFraming,0x07); //定义要发送的最后一个字节的位数
SetBitMask(RegTxControl,0x03); //管脚TX2 ,TX1上的输出信号将传递由发送数据调制的13 56MHz 能量载波
ResetInfo(); //清0
SerBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
// 0x1e
status = M500PcdCmd((unsigned char)PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status){
*atq = 0;
}else{
if (MInfo.nBitsReceived != 16) {
*atq = 0;
status = MI_BITCOUNTERR;
}else{
status = MI_OK;
memcpy((void *)atq,(void *)SerBuffer,2);
}
}
return status;
}
RE:发一个读写RC531的STM32F2XX的DEMO
* 名 称:M500PiccCommonRequest
* 功 能:防冲突 读卡的系列号 MLastSelectedSnr
* 入口参数:bcnt 0
snr 卡序列号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccCascAnticoll (unsigned char bcnt,unsigned char *snr){
unsigned char status = MI_OK;
char snr_in[4];
char complete = 0;
char nbytes = 0;
char nbits = 0;
char i = 0;
char byteOffset = 0;
unsigned char dummyShift1;
unsigned char dummyShift2;
M500PcdSetTmo(106);
memcpy((void *)snr_in,(void *)snr,4);
WriteIO(RegDecoderControl,0x28); //0x1a 在一个位冲突之后的任何位都屏蔽为0
ClearBitMask(RegControl,0x08); //0x09 与卡的所有数据通信都被加密
complete = 0;
while ((!complete) && (status == MI_OK) ){//1
ResetInfo(); //清0
WriteIO(RegChannelRedundancy,0x03); //0x22 选择RF 信道上数据完整性检测的类型和模式
// 单独产生或者出现奇数的奇偶校验
// 奇偶校验位在每个字节后插入发送数据流中并会出现在接收据流的每个字节后
nbits = bcnt % 8;
if(nbits){ //"
RE:发一个读写RC531的STM32F2XX的DEMO
* 名 称:M500PiccAuthE2
* 功 能:校验卡密码(E2)
* 入口参数:auth_mode 密码类型
snr 卡序列号
keynr 扇区号
block 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccAuthE2( unsigned char auth_mode,unsigned char *snr,
unsigned char keynr,unsigned char block){
char status = MI_OK;
unsigned short e2addr = (unsigned short)0x80 + keynr * 0x18;
unsigned char *e2addrbuf;
if (auth_mode == PICC_AUTHENT1B){ //b密码
e2addr += 12;
}
e2addrbuf = (unsigned char *)&e2addr;
FlushFIFO(); //清FIFO
ResetInfo(); //清0
memcpy((void *)SerBuffer,(void *)e2addrbuf,2);
MInfo.nBytesToSend = 2;
if ((status=M500PcdCmd(PCD_LOADKEYE2,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK){
status = M500PiccAuthState(auth_mode,snr,block);
}
return status;
}
/****************************************************************************
* 名 称:M500HostCodeKey
* 功 能:密码转换
* 入口参数:uncoded 原始密码
coded 标准密码
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500HostCodeKey(unsigned char *uncoded, unsigned char *coded){
char status = MI_OK;
unsigned char cnt = 0;
unsigned char ln = 0;
unsigned char hn = 0;
for (cnt = 0; cnt < 6; cnt++){
ln = uncoded[cnt] & 0x0F;
hn = uncoded[cnt] >> 4;
coded[cnt * 2 + 1] = (~ln 8) & 0xFF;
memcpy((char *)SerBuffer + 2,_data,length);
MInfo.nBytesToSend = length + 2;
status = M500PcdCmd(PCD_WRITEE2,(unsigned char *)SerBuffer, (MfCmdInfo *)&MInfo);
return status;
}
/****************************************************************************
* 名 称:M500PcdLoadKeyE2
* 功 能:修改内部密码
* 入口参数:key_type 密码类型
sector 扇区号
uncoded_keys 密码
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdLoadKeyE2(unsigned char key_type,
unsigned char sector,
unsigned char *uncoded_keys){
signed char status = MI_OK;
unsigned short e2addr = (unsigned short)0x80 + sector * 0x18;
unsigned char coded_keys[12];
if (key_type == PICC_AUTHENT1B){
e2addr += 12; // key B offset
}
if ((status = M500HostCodeKey(uncoded_keys,coded_keys)) == MI_OK){
status = PcdWriteE2(e2addr,12,coded_keys);
}
return status;
}
/****************************************************************************
* 名 称:ChangePassWord
* 功 能:修改内部密码
* 入口参数:password 密码
bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char ChangePassWord(unsigned char *password,unsigned char bank){
return M500PcdLoadKeyE2(0x60,bank/4,password);
}
/****************************************************************************
* 名 称:SelectTag
* 功 能:选技卡
* 入口参数:snr 卡序列号
返回值
* 出口参数:0正常,其它错误码
****************************************************************************/
char SelectTag(unsigned char *snr, unsigned char *sak){
char status;
snr=snr;
status=M500PiccCascSelect(snr,sak);
return status;
}
/****************************************************************************
* 名 称:CascAnticoll
* 功 能:防碰撞
* 入口参数:bcnt 0
snr 卡序列号
* 出口参数:0正常,其它错误码
****************************************************************************/
char CascAnticoll(unsigned char bcnt,unsigned char *snr){
unsigned char status;
status=M500PiccCascAnticoll(bcnt,snr);
memcpy((void *)MLastSelectedSnr,(void *)snr,4);
return status;
}
/****************************************************************************
* 名 称:M500PiccRead
* 功 能:读卡实体函数
* 入口参数:_data 卡数据
addr 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccRead(unsigned char addr,unsigned char *_data){
char status = MI_OK;
FlushFIFO();
M500PcdSetTmo(1);
WriteIO(RegChannelRedundancy,0x0F);
ResetInfo();
SerBuffer[0] = PICC_READ;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
// MpIsrInfo
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status != MI_OK){
if (status != MI_NOTAGERR ){
if (MInfo.nBitsReceived == 4){
SerBuffer[0] &= 0x0f;
if ((SerBuffer[0] & 0x0a) == 0){
status = MI_NOTAUTHERR;
}else{
status = MI_CODEERR;
}
}
}
memcpy(_data,"0000000000000000",16);
}else // Response Processing
{
if (MInfo.nBytesReceived != 16){
status = MI_BYTECOUNTERR;
memcpy(_data,"0000000000000000",16);
}else{
memcpy(_data,(void *)SerBuffer,16);
}
}
M500PcdSetTmo(1);
return status;
}
/****************************************************************************
* 名 称:M500PiccWrite
* 功 能:写卡实体函数
* 入口参数:ReadData 卡数据
bank 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccWrite( unsigned char addr,unsigned char *_data){
char status = MI_OK;
ResetInfo();
SerBuffer[0] = PICC_WRITE;
SerBuffer[1] = addr;
MInfo.nBytesToSend = 2;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status != MI_NOTAGERR){
if (MInfo.nBitsReceived != 4){
status = MI_BITCOUNTERR;
}else{
SerBuffer[0] &= 0x0f;
if ((SerBuffer[0] & 0x0a) == 0){
status = MI_NOTAUTHERR;
}else{
if (SerBuffer[0] == 0x0a){
status = MI_OK;
}else{
status = MI_CODEERR;
}
}
}
}
if ( status == MI_OK){
M500PcdSetTmo(3);
ResetInfo();
memcpy((unsigned char *)SerBuffer,_data,16);
MInfo.nBytesToSend = 16;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status & 0x80){
status = MI_NOTAGERR;
}else{
if (MInfo.nBitsReceived != 4){
status = MI_BITCOUNTERR;
}else{
SerBuffer[0] &= 0x0f;
if ((SerBuffer[0] & 0x0a) == 0){
status = MI_WRITEERR;
}else{
if (SerBuffer[0] == 0x0a){
status = MI_OK;
}else{
status = MI_CODEERR;
}
}
}
}
M500PcdSetTmo(1);
}
return status;
}
RE:发一个读写RC531的STM32F2XX的DEMO
* 名 称:ReadCard
* 功 能:读卡
* 入口参数:ReadData 卡数据
bank 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char ReadCard( unsigned char *ReadData,unsigned char bank){
return M500PiccRead(bank,ReadData);
}
/****************************************************************************
* 名 称:WriteCard
* 功 能:写卡
* 入口参数:WriteData 卡数据
bank 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char WriteCard(unsigned char *WriteData,unsigned char bank){
return M500PiccWrite(bank,WriteData);
}
/****************************************************************************
* 名 称:fine
* 功 能:寻卡
* 入口参数:req_code 寻卡指令 request code ALL = 0x52 or IDLE = 0x26
agq 返回卡类型
* 出口参数:0正常,其它错误码
****************************************************************************/
char fine(unsigned char req_code,unsigned char *atq){
unsigned char status;
status=M500PiccCommonRequest(req_code,atq);
if(status!=0){
status=M500PiccCommonRequest(req_code,atq);
if(status!=0)
{
}
}
return status;
}
/****************************************************************************
* 名 称:M500PiccHalt
* 功 能:终止卡的操作
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccHalt(void){
char status = MI_CODEERR;
// ************* Cmd Sequence **********************************
ResetInfo();
SerBuffer[0] = PICC_HALT ; // Halt command code
SerBuffer[1] = 0x00; // dummy address
MInfo.nBytesToSend = 2;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status){
// timeout error ==> no NAK received ==> OK
if (status == MI_NOTAGERR || status == MI_ACCESSTIMEOUT){
status = MI_OK;
}
}
//reset command register - no response from tag
WriteIO(RegCommand,PCD_IDLE);
return status;
}
/****************************************************************************
* 名 称:Fine_Card
* 功 能:寻卡,碰撞,选卡
* 入口参数:CardSN 卡序列号
cardtype 返回卡类型
* 出口参数:0正常
0x10,无卡,
0x11,碰撞失败
0x12,选卡失败
****************************************************************************/
unsigned char Fine_Card(unsigned char *CardSN,unsigned char *cardtype){
unsigned char dat[4],sak[4];
if(fine(0x26,dat)==0){
*cardtype = dat[0];
if(CascAnticoll(0,dat)==0){
CardSN[0]=dat[0];
CardSN[1]=dat[1];
CardSN[2]=dat[2];
CardSN[3]=dat[3];
if(SelectTag(dat,sak)==0){
return 0;
}else return 0x12;
}
else return 0x11;
}
else return 0x10;
}
/****************************************************************************
* 名 称:PiccCMD14443_4
* 功 能:14443-4指令的发送与接收
* 入口参数:senddata 发送的数据
readdata 接收的数据
sendlen 发送的字节数
readlen 接收到的字节数
* 出口参数:0正常,,其它错误码
****************************************************************************/
char PiccCMD14443_4(unsigned char *senddata,unsigned char *readdata,unsigned char sendlen,unsigned char *readlen){
char status = MI_OK;
FlushFIFO();
M500PcdSetTmo(106);
WriteIO(RegChannelRedundancy,0x0F);
ResetInfo();
memcpy((void *)SerBuffer,senddata,sendlen);
MInfo.nBytesToSend = sendlen;
status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status != MI_OK){
if (status != MI_NOTAGERR ){ //
if (MInfo.nBitsReceived == 4){
SerBuffer[0] &= 0x0f;
if ((SerBuffer[0] & 0x0a) == 0){
status = MI_NOTAUTHERR;
}else{
status = MI_CODEERR;
}
}
}
//memcpy(_data,r_data,16); //超时
*readlen = 0;
}else{ // Response Processing
*readlen=MInfo.nBytesReceived;
memcpy(readdata,(void *)SerBuffer,*readlen);
}
M500PcdSetTmo(1);
return status;
}
/****************************************************************************
* 名 称:Select_3f02()
* 功 能:外部中断EINT3服务函数,取反B1控制口。
* 入口参数:指令执行状态
* 出口参数:0正常,,其它错误码
****************************************************************************/
unsigned char Select_3f02(unsigned char *p){
unsigned char cmd[]={0x0a,0x00,0x00,0xa4,0x00,0x00,0x02,0x3f,0x02};
unsigned char len;
unsigned short st;
if(PiccCMD14443_4(cmd,p,9,&len)==0){
st = p[len-2]*0x100+p[len-1];
if(st==0x9000){
memcpy(p,&p[0],len);
return 0;
}else{
return 2;
}
}
return 1;
}
/****************************************************************************
* 名 称:read_ls()
* 功 能:读历吏字节。
* 入口参数:olddata 历吏字节
* 出口参数:0正常,,其它错误码
****************************************************************************/
unsigned char read_ls(unsigned char *olddata){//ratq读历吏07 77 F7 80 02 47 65
unsigned char b[4];
unsigned char len;
unsigned char bak;
b[0]=0xe0;
b[1]=0x50;
bak = PiccCMD14443_4(b,olddata,2,&len);
return bak;
}
/****************************************************************************
* 名 称:GetCardSN()
* 功 能:取卡序列号
* 入口参数:SN 卡序列号
* 出口参数:0正常,,其它错误码
****************************************************************************/
unsigned char GetCardSN(unsigned char *SN){
unsigned char cmd[]={0x0b,0x00,0x00,0xb0,0x95,0x00,0x1c};//0a,0a
unsigned char buff[32];
unsigned char bak,i,len;
unsigned short st;
bak = PiccCMD14443_4(cmd,buff,7,&len);
if(bak==0){
st = buff[len-2]*0x100+buff[len-1];
if(st==0x9000){
memcpy(SN,&buff[14],8);
memcpy(&SN[24],&buff[22],8);
memcpy(&SN[8],&buff[2],2);
for( i = 2 ; i < 8 ; i++ ) SN[8+i] = 0xff;
SN[16]=buff[4];
SN[17]=buff[5]|0x0f;
for( i = 2 ; i < 8 ; i++ ) SN[16+i] = 0xff;
return 0;
}else {
return 1;
}
}
return 2;
}
/****************************************************************************
* 名 称:Get_Balance()
* 功 能:取余额
* 入口参数:money 余额
* 出口参数:0正常,,其它错误码
****************************************************************************/
unsigned char Get_Balance(unsigned long *money){
unsigned char cmd[]={0x0a,0x00,0x80,0x5c,0x00,0x02,0x04};
unsigned char buff[10];
unsigned char len;
unsigned short st;
if(PiccCMD14443_4(cmd,buff,7,&len)==0){
st = buff[len-2]*0x100+buff[len-1];
if(st==0x9000){
memcpy((unsigned char *)money,&buff[2],4);
return 0;
}else{
return 2;
}
}
return 1;
}
/****************************************************************************
* 名 称:Cash_Withdraw()
* 功 能:消费初始化
* 入口参数:sn 终端编号
money 交易金额
passwordtype 密码类型
MAC1 MAC1
len 卡返回数据的长度
* 出口参数:0正常,,其它错误码
****************************************************************************/
unsigned char Cash_Withdraw(unsigned char *sn,//终端编号
unsigned char *money,//交易金额
unsigned char passwordtype,
unsigned char *MAC1,
unsigned char *len){//消费初始化
unsigned char cmd[]={ 0x0b,0x00,0x80,0x50,0x01,0x02,0x0b};
unsigned char cmd1[19];
unsigned char i,cmd_len=0;
unsigned char bak;
unsigned short st;
for(i=0;icmd == PICC_ANTICOLL1){
WriteIO(RegChannelRedundancy,0x02); //奇偶校验
WriteRawIO(0,0x80);
}
}
if (irqBits & 0x0E){
nbytes = ReadRawIO(RegFIFOLength);
for ( cnt = 0; cnt < nbytes; cnt++){
MpIsrOut[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
MpIsrInfo->nBytesReceived++;
}
WriteRawIO(RegInterruptRq,0x0A & irqBits);
}
if (irqBits & 0x04){
WriteRawIO(RegInterruptEn,0x20);
WriteRawIO(RegInterruptRq,0x20);
irqBits &= ~0x20;
MpIsrInfo->irqSource &= ~0x20;
WriteRawIO(RegInterruptRq,0x04);
}
if (irqBits & 0x20){
WriteRawIO(RegInterruptRq,0x20);
MpIsrInfo->status = MI_NOTAGERR;
}
}
}
}
/****************************************************************************
* 名 称:Rc500Init
* 功 能:外部中断的初始化。
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char Rc500Init(void){
SPI1_Config();
RC531RST_CLR();
RC531NSS_SET();
return MfConfig();
}
/*
unsigned char PcdRequest(unsigned char req_code)
{
char status;
MfCmdInfo1 *pi;
PcdSetTmo(14);
WriteRC(RegChannelRedundancy,0x03);
ClearBitMask(RegControl,0x08);
WriteRC(RegBitFraming,0x07);
pi->MfCommand=PCD_TRANSCEIVE;
pi->MfLength=1;
pi->MfData[0]=req_code;
status=PcdComTransceive(pi);
// ser_send(&status,1);
if(!status)
{ if(pi->MfLength!=0x10)
{
//status=MI_BITCOUNTERR;
status=0x55;
}
}
return status;
}
unsigned char PcdAnticoll(unsigned char *snr) //读取卡片序列号函数
{
unsigned char i;
unsigned char snr_check=0;
char status=MI_OK;
MfCmdInfo1 *pi;
PcdSetTmo(14);
WriteRC(RegDecoderControl,0x28);
ClearBitMask(RegControl,0x08);
WriteRC(RegChannelRedundancy,0x03);
pi->MfCommand=PCD_TRANSCEIVE;
pi->MfLength=2;
pi->MfData[0]=PICC_ANTICOLL1;
pi->MfData[1]=0x20;
status=PcdComTransceive(pi);
// ser_send(&status,1);
if(!status)
{
for(i=0;iMfData;
}
if(snr_check!=pi->MfData)
{
status=MI_SERNRERR;
}
else
{
for(i=0;iMfData;
}
}
}
ClearBitMask(RegDecoderControl,0x20);
*/
RE:发一个读写RC531的STM32F2XX的DEMO
S0SPCCR = 128; 设置SPI时钟分频值为128
92.
93. S0SPCR = (0
RE:发一个读写RC531的STM32F2XX的DEMO
#if RC531_TEST
/**********************************************************************
** 函数名称: main()
** 功能描述: 系统主函数
** 输 入: 无
** 输 出: 无
** 函数说明: 程序C语言接口
***********************************************************************/
void test_RC531( void ){
unsigned char aa[64];
unsigned char a;
// unsigned short b = 0x1234;
a=Rc500Init();
while(1){
if(Fine_Card(aa,&a)==0){
for( a = 0 ; a < 6 ; a++ ) aa[a] = 0xff;
if((a = DownloadPassWord2(aa,13))==0){
if(WriteCard(aa,13)==0){
if((a = ReadCard(aa,13))==0){ //查看A,AA的值
a=0;
}else{
a=a;
}
M500PiccHalt();
}
}else{
a=a;
}
}
Delay_1us(10000);
}
}
#endif
RE:发一个读写RC531的STM32F2XX的DEMO
#define _RC531_H
//-------------------------------------------------------------------------------------------------------
#define RC531_CS1 (GPIO_Pin_2) //PA2
//********************************************************************************************************************
#define RC531_CS(x) ((x>0)? (GPIO_SetBits(GPIOA, RC531_CS1)) : (GPIO_ResetBits(GPIOA, RC531_CS1) ))//设置1,0
//-------------------------------------------------------------------------------------------------------
//IRQ 估计是用中断,请注意!!!!
#define RC531_IRQ1 (GPIO_Pin_1) //PA1
//********************************************************************************************************************
#define RC531_IRQ(x) ((x>0)? (GPIO_SetBits(GPIOA, RC531_IRQ1)) : (GPIO_ResetBits(GPIOA, RC531_IRQ1) ))//设置1,0
//-------------------------------------------------------------------------------------------------------
#define RC531_RSTPD1 (GPIO_Pin_3) //PA3
//********************************************************************************************************************
#define RC531_RSTPD(x) ((x>0)? (GPIO_SetBits(GPIOA, RC531_RSTPD1)) : (GPIO_ResetBits(GPIOA, RC531_RSTPD1) ))//设置1,0
//******************************************************************************
#define READER_ERR_BASE_START 0
#define MI_OK 0
#define MI_CHK_OK 0
#define MI_CRC_ZERO 0
#define MI_CRC_NOTZERO 1
#define MI_NOTAGERR 1
#define MI_CHK_FAILED 1
#define MI_CRCERR 2
#define MI_CHK_COMPERR 2
#define MI_EMPTY 3
#define MI_AUTHERR 4
#define MI_PARITYERR 5
#define MI_CODEERR 6
#define MI_SERNRERR 8
#define MI_KEYERR 9
#define MI_NOTAUTHERR 10
#define MI_BITCOUNTERR 11
#define MI_BYTECOUNTERR 12
#define MI_IDLE 13
#define MI_TRANSERR 14
#define MI_WRITEERR 15
#define MI_INCRERR 16
#define MI_DECRERR 17
#define MI_READERR 18
#define MI_OVFLERR 19
#define MI_POLLING 20
#define MI_FRAMINGERR 21
#define MI_ACCESSERR 22
#define MI_UNKNOWN_COMMAND 23
#define MI_COLLERR 24
#define MI_RESETERR 25
#define MI_INITERR 25
#define MI_INTERFACEERR 26
#define MI_ACCESSTIMEOUT 27
#define MI_NOBITWISEANTICOLL 28
#define MI_QUIT 30
#define MI_RECBUF_OVERFLOW 50
#define MI_SENDBYTENR 51
#define MI_SENDBUF_OVERFLOW 53
#define MI_BAUDRATE_NOT_SUPPORTED 54
#define MI_SAME_BAUDRATE_REQUIRED 55
#define MI_WRONG_PARAMETER_VALUE 60
#define MI_BREAK 99
#define MI_NY_IMPLEMENTED 100
#define MI_NO_MFRC 101
#define MI_MFRC_NOTAUTH 102
#define MI_WRONG_DES_MODE 103
#define MI_HOST_AUTH_FAILED 104
#define MI_WRONG_LOAD_MODE 106
#define MI_WRONG_DESKEY 107
#define MI_MKLOAD_FAILED 108
#define MI_FIFOERR 109
#define MI_WRONG_ADDR 110
#define MI_DESKEYLOAD_FAILED 111
#define MI_WRONG_SEL_CNT 114
#define MI_WRONG_TEST_MODE 117
#define MI_TEST_FAILED 118
#define MI_TOC_ERROR 119
#define MI_COMM_ABORT 120
#define MI_INVALID_BASE 121
#define MI_MFRC_RESET 122
#define MI_WRONG_VALUE 123
#define MI_VALERR 124
#define MI_SAKERR 0x46 //added by robbie
#define RegPage 0x00
#define RegCommand 0x01
#define RegFIFOData 0x02
#define RegPrimaryStatus 0x03
#define RegFIFOLength 0x04
#define RegSecondaryStatus 0x05
#define RegInterruptEn 0x06
#define RegInterruptRq 0x07
#define RegControl 0x09
#define RegErrorFlag 0x0A
#define RegCollPos 0x0B
#define RegTimerValue 0x0C
#define RegCRCResultLSB 0x0D
#define RegCRCResultMSB 0x0E
#define RegBitFraming 0x0F
#define RegTxControl 0x11
#define RegCwConductance 0x12
#define RFU13 0x13
#define RegModConductance 0x13 //驱动电导系数寄存器
#define RegCoderControl 0x14
#define RegModWidth 0x15
#define RFU16 0x16
#define RFU17 0x17
#define RegTypeBFraming 0x17 //TypeB帧设置寄存器
#define RegRxControl1 0x19
#define RegDecoderControl 0x1A
#define RegBitPhase 0x1B
#define RegRxThreshold 0x1C
#define RFU1D 0x1D
#define RegBPSKDemControl 0x1D //BPSK解调控制寄存器
#define RegRxControl2 0x1E
#define RegClockQControl 0x1F
#define RegRxWait 0x21
#define RegChannelRedundancy 0x22
#define RegCRCPresetLSB 0x23
#define RegCRCPresetMSB 0x24
#define RFU25 0x25
#define RegMfOutSelect 0x26
#define RFU27 0x27
#define RegFIFOLevel 0x29
#define RegTimerClock 0x2A
#define RegTimerControl 0x2B
#define RegTimerReload 0x2C
#define RegIRqPinConfig 0x2D
#define RFU2E 0x2E
#define RFU2F 0x2F
#define RFU31 0x31
#define RFU32 0x32
#define RFU33 0x33
#define RFU34 0x34
#define RFU35 0x35
#define RFU36 0x36
#define RFU37 0x37
#define RFU39 0x39
#define RegTestAnaSelect 0x3A
#define RFU3B 0x3B
#define RFU3C 0x3C
#define RegTestDigiSelect 0x3D
#define RFU3E 0x3E
#define RegTestDigiAccess 0x3F
#define DEF_FIFO_LENGTH 64
#define PCD_IDLE 0x00
#define PCD_WRITEE2 0x01
#define PCD_READE2 0x03
#define PCD_LOADCONFIG 0x07
#define PCD_LOADKEYE2 0x0B
#define PCD_AUTHENT1 0x0C
#define PCD_CALCCRC 0x12
#define PCD_AUTHENT2 0x14
#define PCD_RECEIVE 0x16
#define PCD_LOADKEY 0x19
#define PCD_TRANSMIT 0x1A
#define PCD_TRANSCEIVE 0x1E
#define PCD_RESETPHASE 0x3F
#define PICC_REQIDL 0x26
#define PICC_REQALL 0x52
#define PICC_ANTICOLL1 0x93
#define PICC_ANTICOLL2 0x95
#define PICC_ANTICOLL3 0x97
#define PICC_AUTHENT1A 0x60
#define PICC_AUTHENT1B 0x61
#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
#define mifare1 1
#define mifarepro 2
#define mifarelight 3
#define unkowncard 4
#define GetRegPage(addr) (0x80 | (addr>>3))
typedef struct {
unsigned char cmd;
char status;
unsigned char nBytesSent;
unsigned char nBytesToSend;
unsigned char nBytesReceived;
unsigned short nBitsReceived;
unsigned char irqSource;
unsigned char collPos;
} MfCmdInfo;
//#define ResetInfo(info) (info.cmd= 0; info.status= MI_OK; info.irqSource = 0;info.nBytesSent = 0; info.nBytesToSend= 0;info.nBytesReceived = 0; info.nBitsReceived = 0;info.collPos= 0;)
#endif
/****************************************************************************
* 名 称:Rc500Init
* 功 能:外部中断的初始化。
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
extern unsigned char Rc500Init(void);
///////////////////////////////////////////////////////////////////////
// 14443-3函数
///////////////////////////////////////////////////////////////////////
/****************************************************************************
* 名 称:fine
* 功 能:寻卡
* 入口参数:req_code 寻卡指令 request code ALL = 0x52 or IDLE = 0x26
agq 返回卡类型
* 出口参数:0正常,其它错误码
****************************************************************************/
extern char fine(unsigned char req_code,unsigned char *atq) ;
/****************************************************************************
* 名 称:CascAnticoll
* 功 能:防碰撞
* 入口参数:bcnt 0
snr 卡序列号
* 出口参数:0正常,其它错误码
****************************************************************************/
extern char CascAnticoll(unsigned char bcnt,unsigned char *snr);
/****************************************************************************
* 名 称:SelectTag
* 功 能:选技卡
* 入口参数:snr 卡序列号
返回值
* 出口参数:0正常,其它错误码
****************************************************************************/
extern char SelectTag(unsigned char *snr, unsigned char *sak);
/****************************************************************************
* 名 称:Fine_Card
* 功 能:寻卡,碰撞,选卡
* 入口参数:CardSN 卡序列号
cardtype 返回卡类型
* 出口参数:0正常
0x10,无卡,
0x11,碰撞失败
0x12,选卡失败
****************************************************************************/
extern unsigned char Fine_Card(unsigned char *CardSN,unsigned char *cardtype);
/****************************************************************************
* 名 称:ReadCard
* 功 能:读卡
* 入口参数:ReadData 卡数据
bank 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
extern unsigned char ReadCard( unsigned char *ReadData,unsigned char bank);
/****************************************************************************
* 名 称:WriteCard
* 功 能:写卡
* 入口参数:WriteData 卡数据
bank 块号
* 出口参数:0正常,其它错误码
****************************************************************************/
extern unsigned char WriteCard(unsigned char *WriteData,unsigned char bank);
/****************************************************************************
* 名 称:M500PiccHalt
* 功 能:终止卡的操作
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
extern char M500PiccHalt(void);
/****************************************************************************
* 名 称:DownloadPassWord
* 功 能:内部效验密码
* 入口参数:bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
extern unsigned char DownloadPassWord(unsigned char bank);
/****************************************************************************
* 名 称:DownloadPassWord2
* 功 能:直接效验密码
* 入口参数:bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char DownloadPassWord2(unsigned char *password ,unsigned char bank);
/****************************************************************************
* 名 称:ChangePassWord
* 功 能:修改内部密码
* 入口参数:password 密码
bank 所使用的块号
* 出口参数:0正常,其它错误码
****************************************************************************/
extern unsigned char ChangePassWord(unsigned char *password,unsigned char bank);
///////////////////////////////////////////////////////////////////////
// 14443-4函数
///////////////////////////////////////////////////////////////////////
/****************************************************************************
* 名 称:PiccCMD14443_4
* 功 能:14443-4指令的发送与接收
* 入口参数:senddata 发送的数据
readdata 接收的数据
sendlen 发送的字节数
readlen 接收到的字节数
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern char PiccCMD14443_4(unsigned char *senddata,unsigned char *readdata,unsigned char sendlen,unsigned char *readlen);
/****************************************************************************
* 名 称:Select_3f02()
* 功 能:外部中断EINT3服务函数,取反B1控制口。
* 入口参数:指令执行状态
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char Select_3f02(unsigned char *p);
/****************************************************************************
* 名 称:read_ls()
* 功 能:读历吏字节。
* 入口参数:olddata 历吏字节
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char read_ls(unsigned char *olddata);
/****************************************************************************
* 名 称:GetCardSN()
* 功 能:取卡序列号
* 入口参数:SN 卡序列号
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char GetCardSN(unsigned char *SN);
///////////////////////////////////////////////////////////////////////
// 14443-4函数
// 国家建设部消费协议
///////////////////////////////////////////////////////////////////////
/****************************************************************************
* 名 称:Cash_Withdraw()
* 功 能:消费初始化
* 入口参数:sn 终端编号
money 交易金额
passwordtype 密码类型
p 卡返回的数据
len 卡返回数据的长度
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char Cash_Withdraw( unsigned char *sn,//终端编号
unsigned char *money,//交易金额
unsigned char passwordtype,
unsigned char *p,
unsigned char *len);//消费初始?
/****************************************************************************
* 名 称:charCash_Withdraw2()
* 功 能:消费
* 入口参数:je_sn 义易序列号
je_data 交易日期
je_time 交易时间
mac1 MAC1
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char charCash_Withdraw2( unsigned char *je_sn,
unsigned char *je_data,
unsigned char *je_time,
unsigned char *mac1
);
/****************************************************************************
* 名 称:GetName()
* 功 能:取姓名
* 入口参数:name 名字
* 出口参数:0正常,,其它错误码
****************************************************************************/
extern unsigned char GetName( unsigned short *name );
/****************************************************************************
* 名 称:RC531_IRQ_Lib()
* 功 能:中断处理程序
* 入口参数:无
* 出口参数:无
内部处理全局变量 MInfo
****************************************************************************/
extern void RC531_IRQ_Lib(void);
//*************************************************************************
//读取IRQ的状态!!!!也可中断判别!!! 返回=1 已经有中断,=0 无!!!
unsigned char Read_RC531_IRQ(void);