打印
[STM32F2]

发一个读写RC531的STM32F2XX的DEMO

[复制链接]
9940|35
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
MOn51|  楼主 | 2014-8-1 11:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
#ifndef _RC531_H
#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);

评分
参与人数 1威望 +3 收起 理由
mmuuss586 + 3 赞一个!
沙发
MOn51|  楼主 | 2014-8-1 11:02 | 只看该作者
extern void Delay_1us(unsigned int nDly);

#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

使用特权

评论回复
板凳
MOn51|  楼主 | 2014-8-1 11:02 | 只看该作者

/*
S0SPCCR = 128;                           设置SPI时钟分频值为128   
92.      
93.    S0SPCR  = (0 << 3) |              // CPHA = 0, 数据在SCK 的第一个时钟沿采样   
94.             (1 << 4) |               // CPOL = 1, SCK 为低有效   
95.             (1 << 5) |               // MSTR = 1, SPI 处于主模式   
96.             (0 << 6) |               // LSBF = 0, SPI 数据传输MSB (位7)在先   
97.             (0 << 7);                // SPIE = 0, SPI 中断被禁止   
98.               
*/
//******************************************************************************
#define SPIx_SCK_PIN                     GPIO_Pin_5
#define SPIx_SCK_SOURCE                  GPIO_PinSource5

#define SPIx_MISO_PIN                    GPIO_Pin_6
#define SPIx_MISO_SOURCE                 GPIO_PinSource6

#define SPIx_MOSI_PIN                    GPIO_Pin_7
#define SPIx_MOSI_SOURCE                 GPIO_PinSource7

#define SPIx_NSS_PIN                     GPIO_Pin_2
#define SPIx_NSS_SOURCE                  GPIO_PinSource2
//***************************************************************************
void SPI1_IO_Init(void){
        GPIO_InitTypeDef GPIO_InitStructure;

/* SPI pin mappings */
  GPIO_PinAFConfig(GPIOA, SPIx_SCK_SOURCE, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, SPIx_MOSI_SOURCE, GPIO_AF_SPI1);
  GPIO_PinAFConfig(GPIOA, SPIx_MISO_SOURCE, GPIO_AF_SPI1);
// GPIO_PinAFConfig(GPIOB, SPIx_NSS_SOURCE, GPIO_AF_SPI1);
  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  /* SPI SCK pin configuration */
  GPIO_InitStructure.GPIO_Pin = SPIx_SCK_PIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* SPI  MOSI pin configuration */
  GPIO_InitStructure.GPIO_Pin =  SPIx_MOSI_PIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  /* SPI MISO pin configuration */
  GPIO_InitStructure.GPIO_Pin = SPIx_MISO_PIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* SPI NSS pin configuration */
// GPIO_InitStructure.GPIO_Pin = SPIx_NSS_PIN;
//  GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Pin = SPIx_NSS_PIN |  RC531_RSTPD1;        //RC531--两个片选
  GPIO_Init(GPIOA, &GPIO_InitStructure);       
       
        RC531_CS(1);
        RC531_RSTPD(1);
        //** irq set input
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Pin =  RC531_IRQ1;        //RC531--irq
  GPIO_Init(GPIOA, &GPIO_InitStructure);       

}
//*************************************************************************
//读取IRQ的状态!!!!
unsigned char Read_RC531_IRQ(void){
        return GPIO_ReadInputDataBit(        GPIOA,RC531_IRQ1);
}
//***************************************************************************
void SPI1_Config(void){
  SPI_InitTypeDef  SPI_InitStructure;

  /* Enable the SPI peripheral */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
        //RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOC, ENABLE);

        SPI1_IO_Init();
  /* SPI configuration -------------------------------------------------------*/
  //SPI_DeInit(SPI1);
  //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI1, ENABLE);
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI设置为双线双向全双工
        SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//设置为主SPI
        SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构
        SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//选择了串行时钟的稳态:时钟悬空高
        SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//数据捕获于第二个时钟沿
        SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;//Fclk/2
  /* Initialize the SPI_FirstBit member */
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
        SPI_InitStructure.SPI_CRCPolynomial=7;
        SPI_Init(SPI1, &SPI_InitStructure);
  /* Enable SPI1  */
  SPI_Cmd(SPI1, ENABLE);
}
/*******************************************************************************
* Function Name  : SPI_ReadWriteByte
* Description    : SPI读写一个字节(发送完成后返回本次通讯读取的数据)
* Input          : unsigned char TxData 待发送的数
* Output         : None
* Return         : unsigned char RxData 收到的数
Flash_ReadWriteByte
*******************************************************************************/
unsigned char SPI1_ReadWriteByte(unsigned char TxData){
    unsigned char RxData = 0;
   
    //等待发送缓冲区空
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
    //发一个字节
    SPI_I2S_SendData(SPI1, TxData);
//    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

    //等待数据接收
    while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
    //取数据
    RxData = SPI_I2S_ReceiveData(SPI1);
    return (unsigned char)RxData;
}

使用特权

评论回复
地板
MOn51|  楼主 | 2014-8-1 11:04 | 只看该作者
//------------------------------------------------------------------------------------------------------  
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 << 30)            /* 设置 RC500RST 口为GPIO口 */                                                          
//#define  RC531RST_OUT()         RC531_RSTPD(1)                               /* 设置 RC500RST 口为输出口 */                                                          
#define  RC531RST_SET()         RC531_RSTPD(1)                               /* 置 RC500RST 为高电平 */                                                          
#define  RC531RST_CLR()         RC531_RSTPD(0)                               /* 置 RC500RST 为低电平 */                                                          
                                                          
/* RC531NSS 引脚 */                                                                 
//#define  RC531NSS               0x00000400                                                                                
//#define  RC531NSS_GPIO()        PINSEL0 &= ~((unsigned int)0x03 << 20)            /* 设置 RC500RST 口为GPIO口 */                                                          
//#define  RC531NSS_OUT()         IODIR |= RC531NSS                               /* 设置 RC500RST 口为输出口 */                                                          
#define  RC531NSS_SET()         RC531_CS(1)                               /* 置 RC500RST 为高电平 */                                                          
#define  RC531NSS_CLR()         RC531_CS(0)                               /* 置 RC500RST 为低电平 */                                                          



//全局变量                                                                    
static   volatile MfCmdInfo   MInfo;                                                                      

                                                          
volatile unsigned char SerBuffer[40];                                                           
                                                          
static   volatile MfCmdInfo      *MpIsrInfo;                                                           
static   volatile unsigned char  *MpIsrOut;                                                          
volatile unsigned char MLastSelectedSnr[4];                                                          
                                                          
                                                          
//***********************************************************************
//以下代码为1uS的延时,用视波器调整的,很准,KEIL MDK编译,优化等级为0,频率120M
void tDelay_1us(unsigned int nDly){
         register unsigned char  n;
         while(nDly--){
                         n = 22;
                         while(n--);
         }
}                                                                                                                   
/****************************************************************************                                                         
* 名    称:DelayNS()                                                         
* 功    能:长软件延时。                                                         
* 入口参数:dly      延时参数,值越大,延时越久                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void  delay_1ms(unsigned long  dly){                                                            
                tDelay_1us(8000);  //1000us
}                                                          
/****************************************************************************                                                         
* 名    称:delay_50us()                                                         
* 功    能:长软件延时。                                                         
* 入口参数:dly      延时参数,值越大,延时越久                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void delay_50us(unsigned char _50us){                                                          
                tDelay_1us(40);  //50us
}
//*****************************************************************************
//不改动原来函数!必须传入数据
void ResetInfo(void){
        memset((unsigned char *)&MInfo,0,sizeof( MInfo));
}
/****************************************************************************                                                         
* 名    称:ReadRawIO()                                                         
* 功    能:从一个地址读出一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
* 出口参数:数据                                                         
****************************************************************************/                                                          
unsigned char ReadRawIO(unsigned char Address){                                                          
    unsigned char a;                                                          
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte((Address<<1)|0x80);                                                          
    a = SPI1_ReadWriteByte(0xff);  //亚指令!                                                         
    SPI1_ReadWriteByte(0x00);                                                             
    RC531NSS_SET();                                                          
    return a;                                                                
}                                                          
                               
/****************************************************************************                                                         
* 名    称:WriteRawIO()                                                         
* 功    能:往一个地址写一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
            value    数据                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void WriteRawIO(unsigned char Address, unsigned char value){                                                          
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte((Address<<1)&0x7f);                                                          
    SPI1_ReadWriteByte(value);                                                          
    RC531NSS_SET();                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:WriteIO()                                                         
* 功    能:往一个地址写一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
            value    数据                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void WriteIO(unsigned char Address, unsigned char value){                                                          
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte(0x00);                                                          
    SPI1_ReadWriteByte(GetRegPage(Address));                                                          
    RC531NSS_SET();                                                          
                                                              
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte((Address<<1)&0x7f);                                                          
    SPI1_ReadWriteByte(value);                                                          
    RC531NSS_SET();                                                                       
}                                                          
/****************************************************************************                                                         
* 名    称:ReadIO()                                                         
* 功    能:从一个地址读出一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
* 出口参数:数据                                                         
****************************************************************************/                                                          
unsigned char ReadIO(unsigned char Address) {                                                          
   unsigned char a;                                                          
   RC531NSS_CLR();                                                          
   SPI1_ReadWriteByte(0x00);                                                          
   SPI1_ReadWriteByte(GetRegPage(Address));                                                          
   RC531NSS_SET();                                                          
                                                             
   RC531NSS_CLR();                                                          
   SPI1_ReadWriteByte((Address<<1)|0x80);                                                          
   a = SPI1_ReadWriteByte(0xff);  //亚指令!                                                         
   SPI1_ReadWriteByte(0x00);                                                             
   RC531NSS_SET();                                                          
   return a;                                                                       
}                                                           
       
/****************************************************************************                                                         
* 名    称:RFRegWrite()                                                         
* 功    能:往一个地址写一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
            value    数据                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void RFRegWrite(unsigned char Address, unsigned char value){                                                          
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte(0x00);                                                          
    SPI1_ReadWriteByte(GetRegPage(Address));                                                          
    RC531NSS_SET();                                                          
                                                              
    RC531NSS_CLR();                                                          
    SPI1_ReadWriteByte((Address<<1)&0x7f);                                                          
    SPI1_ReadWriteByte(value);                                                          
    RC531NSS_SET();                                                                       
}                                                          
/****************************************************************************                                                         
* 名    称:ReadIO()                                                         
* 功    能:从一个地址读出一个数据(EEPROM)。                                                         
* 入口参数:Address  地址                                                         
* 出口参数:数据                                                         
****************************************************************************/                                                          
unsigned char RFRegRead(unsigned char Address){                                                          
   unsigned char a;                                                          
   RC531NSS_CLR();                                                          
   SPI1_ReadWriteByte(0x00);                                                          
   SPI1_ReadWriteByte(GetRegPage(Address));                                                          
   RC531NSS_SET();                                                          
                                                             
   RC531NSS_CLR();                                                          
   SPI1_ReadWriteByte((Address<<1)|0x80);                                                          
   a = SPI1_ReadWriteByte(0xff);  //亚指令!                                                         
   SPI1_ReadWriteByte(0x00);                                                             
   RC531NSS_SET();                                                          
   return a;                                                                       
}                                                          
/****************************************************************************                                                         
* 名    称:SetBitMask()                                                         
* 功    能:清一个bit                                                         
* 入口参数:reg      内存                                                         
            mask俺码                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
char SetBitMask(unsigned char reg,unsigned char mask){                                                          
    char tmp = 0x00;                                                          
                                                          
    tmp = ReadIO(reg);                                                          
    WriteIO(reg,tmp | mask);  // set bit mask                                                          
    return 0x00;                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:ClearBitMask()                                                         
* 功    能:清一个bit                                                         
* 入口参数:reg      内存                                                         
            mask俺码                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
char ClearBitMask(unsigned char reg,unsigned char mask){                                                          
    char tmp = 0x00;                                                          
                                                          
    tmp = ReadIO(reg);                                                          
    WriteIO(reg,tmp & ~mask);  // clear bit mask                                                          
    return 0x00;                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:FlushFIFO()                                                         
* 功    能:清除内部FIFO                                                         
* 入口参数:无                                                         
* 出口参数:无                                                         
****************************************************************************/                                                          
void FlushFIFO(void){                                                            
    SetBitMask(RegControl,0x01);                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:M500PcdCmd()                                                         
* 功    能:清一个bit                                                         
* 入口参数:unsigned char cmd,                                                         
            unsigned char *rcv,                                                         
            MfCmdInfo idata *info                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
char  M500PcdCmd(unsigned char cmd,                                                          
                 unsigned char *rcv,                                                          
                 MfCmdInfo  *info){                                                          
    char status    = MI_OK;                                                          
    unsigned char irqEn = 0x00;                                                          
    unsigned char waitFor = 0x00;                                                          
    unsigned int timecnt = 0;                                                          
    char tmpStatus ;                                                          
    unsigned char lastBits;                                                          
    WriteIO(RegInterruptEn,0x7F);               //开中断                                                          
    WriteIO(RegInterruptRq,0x7F);               //清中断                                                          
    WriteIO(RegCommand,PCD_IDLE);               //清除指令                                                          
                                                              
    FlushFIFO();                                                               
    MpIsrInfo = info;                                                            
    MpIsrOut = rcv;                                                          
                                                              
    info->irqSource = 0x00;                                                                                
                                                              
    switch(cmd){                                                          
        case PCD_IDLE:                          //0x00      无指令,清指令                                                                   
            irqEn = 0x00;                                                          
            waitFor = 0x00;                                                          
            break;                                                          
        case PCD_WRITEE2:                       //0x01      写FIFO,并定入EEPROM                                                           
            irqEn = 0x11;                                                          
            waitFor = 0x10;                                                          
            break;                                                          
        case PCD_READE2:                        //0x03      从EEPROM取数据并写入FIFO                                                               
            irqEn = 0x07;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_LOADCONFIG:                    //0x07      从EEPROM读数据并用于初始化                                                            
        case PCD_LOADKEYE2:                     //0x0b      将密钥从EEPROM复制到KEY缓存                                                          
        case PCD_AUTHENT1:                      //0x0c      执行Cryptol算法的认证过程                                                          
            irqEn = 0x05;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_CALCCRC:                       //0x12      激活CRC                                                          
            irqEn = 0x11;                                                          
            waitFor = 0x10;                                                          
            break;                                                          
        case PCD_AUTHENT2:                      //0x14      执行Cryptol算法的认证过程二                                                          
            irqEn = 0x04;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_RECEIVE:                       //0x16      接收                                                            
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);                                                          
            irqEn = 0x06;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_LOADKEY:                       //0x19      将密钥从FIFO复制到KEY缓存                                                          
            irqEn = 0x05;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_TRANSMIT:                      //0x1a      发送FIFO缓存数据                                                          
            irqEn = 0x05;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        case PCD_TRANSCEIVE:                    //1e        发送接收                                                          
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);                                                          
            irqEn = 0x3D;                                                          
            waitFor = 0x04;                                                          
            break;                                                          
        default:                                                          
            status = MI_UNKNOWN_COMMAND;        //23                                                          
    }                                                          
//-----------------------------------------------------------------------------------                                                             
    if (status == MI_OK){                                                          
        irqEn |= 0x20;                          //发送中断                                                                             
        waitFor |= 0x20;                        //发送中断                                                          
        timecnt=900000;                                                          
        WriteIO(RegInterruptEn,irqEn | 0x80);                                                           
        WriteIO(RegCommand,cmd);
                               
                                /****************   可以中断处理  **********************/
                                do{
                                        if(Read_RC531_IRQ()==0)  RC531_IRQ_Lib();
        }while ((!(MpIsrInfo->irqSource & waitFor))&&(--timecnt));   //等待中断到来!!!!!!!                                                        
                                                                  
        WriteIO(RegInterruptEn,0x7F);           //开中断                                                                              
        WriteIO(RegInterruptRq,0x7F);           //清中断                                                          
        SetBitMask(RegControl,0x04);            //内部电流消耗模块包括晶振在内关闭                                                                              
        WriteIO(RegCommand,PCD_IDLE);           //清指令                                                          
                                                                  
                                                                  
        if (!(MpIsrInfo->irqSource & waitFor)){                                                                                         
            status = MI_ACCESSTIMEOUT;          //                                                          
        }else{                                                          
            status = MpIsrInfo->status;      //   超时                                                                 
        }                                                          
                                                                  
        if (status == MI_OK){                                                          
            //有错                                                          
            tmpStatus = (ReadIO(RegErrorFlag) & 0x17);                                                          
            if (tmpStatus){//Error 标志指示上一个执行命令的错误状态                                                          
                if (tmpStatus & 0x01){                    //如果检测到一个位冲突该位置位                                                          
                     info->collPos = ReadIO(RegCollPos);   //取位碰撞的位置                                                          
                    status = MI_COLLERR;                                                          
                }else{                                                          
                    info->collPos = 0;                   //没有位冲突                                                          
                    if (tmpStatus & 0x02){                                                          
                        status = MI_PARITYERR;          //如果奇偶校验失                                                          
                    }                                                          
                }                                                          
                if (tmpStatus & 0x04){                   //如果SOF 不正确该位置 起始桢头不正确                                                          
                    status = MI_FRAMINGERR;                                                          
                }                                                          
                if (tmpStatus & 0x10){                  //FIFO 缓冲区而FIFO 缓冲区已满时                                                          
                    FlushFIFO();                                                          
                    status = MI_OVFLERR;                                                          
                }                                                          
                if (tmpStatus & 0x08){                   //如果RxCRCEn 置位且CRC 失败                                                          
                    status = MI_CRCERR;                                                          
                }                                                             
                if (status == MI_OK)                    //                                                          
                    status = MI_NY_IMPLEMENTED;         //100                                                             
            }                                                          
            if (cmd == PCD_TRANSCEIVE){                                                          
                lastBits = ReadIO(RegSecondaryStatus) & 0x07;//显示最后接收字节的有效位个数                                                          
                if (lastBits)                                                          
                    info->nBitsReceived += (info->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;                                                          
}                                                          

使用特权

评论回复
5
MOn51|  楼主 | 2014-8-1 11:04 | 只看该作者

/****************************************************************************                                                         
* 名    称: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;                                                          
}                                                          
/****************************************************************************                                                         
* 名    称: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){                               //"<<" > "|"                                                          
            WriteIO(RegBitFraming,nbits << 4 | nbits);  //0x0f        位方式帧的调节                                                          
            nbytes = bcnt / 8 + 1;                                                             
            if (nbits == 7)                                                          
            {                                                          
                MInfo.cmd = PICC_ANTICOLL1;             //0x93                                                          
                WriteIO(RegBitFraming,nbits);                                                           
            }                                                          
        }else{                                                          
            nbytes = bcnt / 8;                                                          
        }                                                          
                                                                  
        SerBuffer[0] = 0x93;                                                          
        SerBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits;                                                          
                                                                  
        for (i = 0; i < nbytes; i++){                                                          
            SerBuffer[i + 2] = snr_in[i];                                                          
        }                                                          
        MInfo.nBytesToSend   = 2 + nbytes;                                                   
                                                                  
        status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);                                                          
        if (nbits == 7){                                                          
            dummyShift1 = 0x00;                         ///////////////////////                                                          
            for (i = 0; i < MInfo.nBytesReceived; i++){                                                          
                dummyShift2 = SerBuffer[i];                                                          
                SerBuffer[i] = (dummyShift1 >> (i+1)) | (SerBuffer[i] << (7-i));                                                          
                dummyShift1 = dummyShift2;                                                          
            }                                                          
            MInfo.nBitsReceived -= MInfo.nBytesReceived;                                                 
            if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;                                  
        }                                                          
        if ( status == MI_OK || status == MI_COLLERR){//2                                                          
            if ( MInfo.nBitsReceived != (40 - bcnt) ){                                                          
                status = MI_BITCOUNTERR;                                                           
            }else{//3                                                          
                byteOffset = 0;                                                          
                if( nbits != 0 ){                                                          
                    snr_in[nbytes - 1] = snr_in[nbytes - 1] | SerBuffer[0];                                                          
                    byteOffset = 1;                                                          
                }                                                          
                                                          
                for ( i = 0 ; i < (4 - nbytes) ; i++){                                                          
                    snr_in[nbytes + i] = SerBuffer[i + byteOffset];                                                          
                }                                                          
                                                            
                if (status != MI_COLLERR ){                                                          
                    dummyShift2 = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];                                                          
                    dummyShift1 = SerBuffer[MInfo.nBytesReceived - 1];                                                  
                    if (dummyShift2 != dummyShift1){                                                          
                        status = MI_SERNRERR;                                                          
                    }else{                                                          
                        complete = 1;                                                          
                    }                                                          
                }else{                                                          
                    bcnt = bcnt + MInfo.collPos - nbits;                                                  
                    status = MI_OK;                                                          
                }                                                          
            }//3                                                          
        }//2                                                          
                                                                  
    }//1                                                          
                                                              
    if (status == MI_OK){                                                          
        memcpy(snr,snr_in,4);                                                          
    }else{                                                          
        memcpy(snr,"0123",4);                                                          
    }                                                          
    ClearBitMask(RegDecoderControl,0x20);                                                          
                                                              
    return status;                                                            
}                                                          

使用特权

评论回复
6
MOn51|  楼主 | 2014-8-1 11:04 | 只看该作者
/****************************************************************************                                                         
* 名    称:M500PiccCascSelect                                                         
* 功    能:选技卡                                                         
* 入口参数:snr 卡序列号                                                         
            sak 返回值         卡类型                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
char M500PiccCascSelect(unsigned char *snr,unsigned char *sak){                                                          
    char status = MI_OK;                                                           
                                                              
    M500PcdSetTmo(106);                                                          
                                                              
    WriteIO(RegChannelRedundancy,0x0F);                 //接收帧的最后字节被解释为CRC 字节                                                          
                                                        //对发送数据进行CRC 计算并将CRC 字节加到数据流中                                                          
                                                        //单独产生或者出现奇数的奇偶校验                                                          
                                                        //奇偶校验位在每个字节后插入发送数据流中并会出现在接收数据流的每个字节后                                                          
    ClearBitMask(RegControl,0x08);                      //与卡的所有数据通信都被加密                                                          
                                                                 
    ResetInfo();                                   //清0                                                           
                                                              
                                                                
    SerBuffer[0] = 0x93;                                                          
    SerBuffer[1] = 0x70;                                                           
                                                                     
                                                             
    memcpy((char *)SerBuffer + 2,(char *)snr,4);                                                          
    SerBuffer[6] = SerBuffer[2] ^ SerBuffer[3] ^ SerBuffer[4] ^ SerBuffer[5];                                                          
    MInfo.nBytesToSend   = 7;                                                  
    status = M500PcdCmd(PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);                                                          
                                                          
    *sak = 0;                                                             
    if (status == MI_OK){                                                          
        if (MInfo.nBitsReceived != 8){                                                          
            status = MI_BITCOUNTERR;                                                          
        }else{                                                          
            //SerBuffer[0]=SerBuffer[1]=SerBuffer[2]=6;                                                          
            *sak = SerBuffer[0];                                                          
        }                                                             
    }                                                          
    return status;                                                          
}                                                          
       
/****************************************************************************                                                         
* 名    称:M500PiccAuthE2                                                         
* 功    能:校验卡密码(E2)                                                         
* 入口参数:auth_mode     密码类型                                                         
            snr           卡序列号                                                         
            block         块号                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
char M500PiccAuthState( unsigned char auth_mode,unsigned char *snr,unsigned char block){                                                          
    char status = MI_OK;                                                          
                                                             
    status = ReadIO(RegErrorFlag);                                                                                               
    if (status != MI_OK){                                                          
        if (status & 0x40){                                                          
            status = MI_KEYERR;                                                          
        }else{                                                          
            status = MI_AUTHERR;                                                              
        }                                                          
    }else{                                                          
        SerBuffer[0] = auth_mode;                                                              
        SerBuffer[1] = block;                                                            
        memcpy((char *)SerBuffer + 2,snr,4);                                                           
        ResetInfo();                                                          
        MInfo.nBytesToSend = 6;                                                  
        if ((status = M500PcdCmd(PCD_AUTHENT1,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK){                                                          
            if (ReadIO(RegSecondaryStatus) & 0x07){              //不完全接收                                                          
                status = MI_BITCOUNTERR;                                                          
            }else{                                               //完全接收                                                          
                ResetInfo();                                                          
                MInfo.nBytesToSend = 0;                                                  
                delay_1ms(1);                                                          
                if ((status = M500PcdCmd(PCD_AUTHENT2,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK){                                                          
                    if ( ReadIO(RegControl) & 0x08 ){           //通信是否加密成功                                                          
                        status = MI_OK;                                                          
                    }else{                                                          
                        status = MI_AUTHERR;                                                          
                    }                                                          
                }                                                          
            }                                                          
        }                                                          
    }                                                          
    return status;                                                          
}                                                          
/****************************************************************************                                                         
* 名    称: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 << 4) | ln;                                                          
        coded[cnt * 2 ] = (~hn << 4) | hn;                                                          
    }                                                          
    return status;                                                          
}                                                          

/****************************************************************************                                                         
* 名    称:M500PiccAuthKey                                                         
* 功    能:直接校验密码                                                          
* 入口参数:auth_mode     密码类型                                                         
            snr           卡序列号                                                         
            keynr         扇区号                                                         
            block         块号                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
char M500PiccAuthKey(  unsigned char auth_mode,                                                          
                       unsigned char *snr,                                                                 
                       unsigned char *keys,                                                                
                       unsigned char block){                                                          
    char status = MI_OK;                                                          
//  unsigned char i;                                                          
                                                              
//   M500PcdSetTmo(106);                                                          
    FlushFIFO();                                                             
    ResetInfo();                                                          
    memcpy((void *)SerBuffer,(void *)keys,12);                                                                           
    MInfo.nBytesToSend = 12;                                                  
    if ((status=M500PcdCmd(PCD_LOADKEY,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo)) == MI_OK){                                                               
        status = M500PiccAuthState(auth_mode,snr,block);                                                           
    }else{                                                          
        //Uart1_SendByte(0x55);                                                          
    }                                                          
    return status;                                                          
}                                                           

/****************************************************************************                                                         
* 名    称:DownloadPassWord2                                                         
* 功    能:直接校验密码                                                          
* 入口参数:bank 所使用的块号                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
unsigned char DownloadPassWord2(unsigned char *password ,unsigned char bank){                                                          
    unsigned char _data[12];                                                          
    char status = MI_OK;                                                          
    M500HostCodeKey(password,_data);                                                          
    status = M500PiccAuthKey(0x60,(unsigned char *)MLastSelectedSnr,_data,bank);                                                          
    return  status;                                                               
}                                                          

/****************************************************************************                                                         
* 名    称:DownloadPassWord                                                         
* 功    能:内部效验密码                                                         
* 入口参数:bank 所使用的块号                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
unsigned char DownloadPassWord(unsigned char bank){                                                          
    unsigned char fan;                                                          
    fan=bank/4;                                                          
                    // A密码效验  卡序列号     区号 块号                                                          
    return M500PiccAuthE2(0x60,(unsigned char *)MLastSelectedSnr,fan,bank);                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:PcdWriteE2                                                         
* 功    能:保存内部密码                                                         
* 入口参数:startaddr        密码起始地址                                                         
            length          密码长度                                                         
            _data           密码                                                         
* 出口参数:0正常,其它错误码                                                         
****************************************************************************/                                                          
char PcdWriteE2(unsigned short startaddr,                                                          
                unsigned char length,                                                          
                unsigned char* _data){                                                          
    char status = MI_OK;                                                          
    ResetInfo();                                                             
    SerBuffer[0] = startaddr & 0xFF;                                                          
    SerBuffer[1] = (startaddr >> 8) & 0xFF;                                                          
    memcpy((char *)SerBuffer + 2,_data,length);                                                          
                                                          
    MInfo.nBytesToSend   = length + 2;                                                  
                                                                   
    status = M500PcdCmd(PCD_WRITEE2,(unsigned char *)SerBuffer, (MfCmdInfo *)&MInfo);                                                           
    return status;                                                          
}                                                           

使用特权

评论回复
7
MOn51|  楼主 | 2014-8-1 11:05 | 只看该作者
/****************************************************************************                                                         
* 名    称: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;                                                          
}                                                          
/****************************************************************************                                                         
* 名    称: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;                                                          
}                                                          

使用特权

评论回复
8
MOn51|  楼主 | 2014-8-1 11:05 | 只看该作者
/****************************************************************************                                                         
* 名    称: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;                                                          
}                                                          

使用特权

评论回复
9
MOn51|  楼主 | 2014-8-1 11:05 | 只看该作者
/****************************************************************************                                                         
* 名    称: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;i<7;i++)                                                          
    cmd1[cmd_len++]=cmd[i];                                                          
    cmd1[cmd_len++]=passwordtype;                                                          
    for(i=0;i<4;i++)                                                          
    cmd1[cmd_len++]=money[i];                                                          
    for(i=0;i<6;i++)                                                          
    cmd1[cmd_len++]=sn[i];                                                          
    cmd1[cmd_len++]=0x0f;                                                          
    bak = PiccCMD14443_4(cmd1,MAC1,19,len);                                                          
    if(bak==0){
        st = MAC1[*len-2]*0x100+MAC1[*len-1];                                                          
        if(st==0x9000){                                                          
            return 0;                                                          
        }else{
            return 2;                                                          
        }                                                          
    }else{
        return 1;                                                          
    }                                                             
}                                                          
/****************************************************************************                                                         
* 名    称:charCash_Withdraw2()                                                         
* 功    能:消费                                                        
* 入口参数:je_sn            义易序列号                                                         
            je_data         交易日期                                                         
            je_time         交易时间                                                         
            mac1            MAC1                                                         
* 出口参数:0正常,,其它错误码                                                         
****************************************************************************/                                                          
unsigned char charCash_Withdraw2(unsigned char *je_sn,                                                          
                                 unsigned char *je_data,                                                          
                                 unsigned char *je_time,                                                          
                                 unsigned char *mac1                                                          
                                ){                                                          
    unsigned char cmd[30];                                                          
    unsigned char i,cmd_len=7;                                                          
    unsigned char bak;                                                          
    unsigned short st;                                                          
    unsigned char buff[20];                                                          
    unsigned char len;                                                          
    je_sn=je_sn;                                                          
    cmd[0]=0x0a;                                                          
    cmd[1]=0x00;                                                          
    cmd[2]=0x80;                                                          
    cmd[3]=0x54;                                                          
    cmd[4]=0x01;                                                          
    cmd[5]=0x00;                                                          
    cmd[6]=0x0f;                                                          
    for(i=0;i<4;i++)                                                          
    cmd[cmd_len++]=je_sn[i];                                                          
    for(i=0;i<4;i++)                                                          
    cmd[cmd_len++]=je_data[i];                                                          
    for(i=0;i<3;i++)                                                          
    cmd[cmd_len++]=je_time[i];                                                          
    for(i=0;i<4;i++)                                                          
    cmd[cmd_len++]=mac1[i];                                                          
    bak = PiccCMD14443_4(cmd,buff,22,&len);                                                          
    if(bak==0){                                                             
        st = buff[len-2]*0x100+buff[len-1];
        if(st==0x9000) return 0;                                                          
        return 2;                                                          
   }else{                                                          
        return bak;                                                          
    }                                                          
}                                                          
/****************************************************************************                                                         
* 名    称:GetName()                                                         
* 功    能:取姓名                                                        
* 入口参数:name             名字                                                         
* 出口参数:0正常,,其它错误码                                                         
****************************************************************************/                                                          
unsigned char GetName(  unsigned short *name ){                                                          
    unsigned char cmd[]={0x0b,0x00,0x00,0xb0,0x96,0x00,0x0a};//0a,0a                                                          
    unsigned char buff[15];                                                          
    unsigned char len;                                                          
    unsigned char i;                                                          
    unsigned short st;                                                          
    unsigned char r_data[]="0123456789abcdef";                                                          
    unsigned char r_data1[]="0123456789ABCDEF";                                                          
    //11 0A 00 6F 0B 84 09 A0 00 00 00 03 86 98 07 02 90 00                                                          
    if(PiccCMD14443_4(cmd,buff,7,&len)==0){                                                             
        st = buff[len-2]*0x100+buff[len-1];                                                          
//      SendStr(buff,len);                                                          
        if(st==0x9000){                                                          
            *name = 0 ;                                                          
            for( i = 0 ; i < 16 ; i++ ){                                                          
               if(r_data[i]==buff[2])                         break;                                                          
               if(r_data1[i]==buff[2])      break;                                                          
            }                                                          
            *name = *name * 0x10;                                                          
            *name = *name+i;                                                          
                                                                      
            for( i = 0 ; i < 16 ; i++ ){                                                          
                if(r_data[i]==buff[3]) break;                                                          
                if(r_data1[i]==buff[3]) break;                                                          
           }                                                          
            *name = *name * 0x10;                                                          
            *name = *name+i;                                                          
                                                                      
            for( i = 0 ; i < 16 ; i++ ){                                                          
                if(r_data[i]==buff[4]) break;                                                          
               if(r_data1[i]==buff[4]) break;                                                          
            }                                                          
            *name = *name * 0x10;                                                          
            *name = *name+i;                                                          
                                                                      
            for( i = 0 ; i < 16 ; i++ ){                                                          
                if(r_data[i]==buff[5]) break;                                                          
                if(r_data1[i]==buff[5]) break;                                                          
            }                                                          
            *name = *name * 0x10;                                                          
            *name = *name+i;                                                          
            //*name = buff[2]*0x100+buff[3];                                                          
            return 0;                                                          
        }else{                                                          
            return 2;                                                          
        }                                                          
    }                                                          
    return 1;//0B 00 62 28 10 20 01 00 00 00 02 02 00 00 20 07 08 01 00 00 00 08 90 00                                                           
                                                       //20 07 08 01 00 00 00 08                                                                                              
}                                                          

/****************************************************************************                                                          
* 名    称:IRQ_Eint3()                                                          
* 功    能:外部中断EINT3服务函数,取反B1控制口。                                                          
* 入口参数:无                                                          
* 出口参数:无                                                          
****************************************************************************/                                                          
void  RC531_IRQ_Lib(void){                                                          
    static unsigned char irqBits;                                                          
    static unsigned char irqMask;                                                                      
    static unsigned char nbytes;                                                          
    static unsigned char cnt;                                                          
                                                                  
    WriteRawIO(0,0x80);                                                          
    if (MpIsrInfo && MpIsrOut){                                                          
        while( ReadRawIO(RegPrimaryStatus) & 0x08){                      //是否有中断                                                          
            irqMask = ReadRawIO(RegInterruptEn);                                                          
            irqBits = ReadRawIO(RegInterruptRq) & irqMask;                                                          
            MpIsrInfo->irqSource |= irqBits;                                                           
            if (irqBits & 0x01){                                                            
                nbytes = 64 - ReadRawIO(RegFIFOLength);                 //取FIFO长度                                                          
                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes){                                                          
                    nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;                                                          
                    WriteRawIO(RegInterruptEn,0x01);                    //开中断                                                          
                }                                                             
                for ( cnt = 0;cnt < nbytes;cnt++){                                                          
                    WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);                                                          
                    MpIsrInfo->nBytesSent++;                                                          
                }                                                          
                WriteRawIO(RegInterruptRq,0x01);                                                            
            }                                                                
            if (irqBits & 0x10){                                                          
                WriteRawIO(RegInterruptRq,0x10);                        //清除标中断标记                                                          
                WriteRawIO(RegInterruptEn,0x82);                                                             
                if (MpIsrInfo->cmd == 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;i<4;i++)                                                         
{                                                         
snr_check^=pi->MfData[i];                                                         
}                                                         
if(snr_check!=pi->MfData[i])                                                         
{                                                         
status=MI_SERNRERR;                                                         
}                                                         
else                                                         
{                                                         
for(i=0;i<4;i++)                                                         
{                                                         
*(snr+i)=pi->MfData[i];                                                         
}                                                         
}                                                         
                                                         
}                                                         
ClearBitMask(RegDecoderControl,0x20);                                                         
*/

                                                       

使用特权

评论回复
10
spy2009| | 2014-8-1 11:39 | 只看该作者
楼主辛苦了,存个文件上来多好。

使用特权

评论回复
11
Zxj_123L| | 2014-8-1 14:17 | 只看该作者
顶一个!

使用特权

评论回复
12
MOn51|  楼主 | 2014-8-1 14:52 | 只看该作者
ANT_RC531.rar (1.53 KB)

PCP_ANT.rar (11.48 KB)

RC531.rar

3.66 KB

使用特权

评论回复
13
MOn51|  楼主 | 2014-8-1 14:53 | 只看该作者
网络有问题,一直发不上来。

使用特权

评论回复
14
yyhhgg| | 2014-8-1 19:06 | 只看该作者
看的有点晕

使用特权

评论回复
15
gxliu08| | 2014-8-1 19:34 | 只看该作者
谢谢分享,学习学习

使用特权

评论回复
16
mmuuss586| | 2014-8-2 09:51 | 只看该作者
只用过rc522,应该差不多。谢谢分享

使用特权

评论回复
17
qrshi| | 2014-8-2 10:18 | 只看该作者
谢谢楼主分享,MARK.

使用特权

评论回复
18
ljp98| | 2014-8-4 08:46 | 只看该作者
谢谢分享!

使用特权

评论回复
19
beyond696| | 2014-8-6 12:13 | 只看该作者

RC522的上位机测试软件。


使用特权

评论回复
20
yzqok| | 2014-8-8 17:08 | 只看该作者
路过学习,很好支持

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

121

主题

472

帖子

7

粉丝