⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rc500.c

📁 用PICC开发的RC500的完整C源程序。单片机用PIC16f73。
💻 C
📖 第 1 页 / 共 3 页
字号:
//文件包含

struct MfCmdInfo *MpIsrInfo = 0;
unsigned char *MpIsrOut = 0;
unsigned char *MpIsrIn = 0;


void delay()
{
    nop();
    clrwdt();
    nop();
    clrwdt();
}
void ISR_RC500(void)
{
    unsigned char irqBits;      //中断状态
    unsigned char irqMask;      //中断允许
    unsigned char oldPageSelect;        //原页号保存
    unsigned char nbytes;
    unsigned char cnt;
    if (MpIsrInfo && MpIsrOut && MpIsrIn)   // transfer pointers have to be set
    {
        oldPageSelect = GetRC500(RegPage); // save old page select
        PutRC500(RegPage,0x80);           // select page 0 for ISR
        while ((GetRC500(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
        {
            irqMask = GetRC500(RegInterruptEn); // read enabled interrupts
            irqBits = GetRC500(RegInterruptRq) & irqMask;
            MpIsrInfo->irqSource |= irqBits; // save pending interrupts

            if (irqBits & 0x01)     // LoAlert
                {
                //nbytes = MFIFOLength - ReadRawRC(RegFIFOLength);
                nbytes = 0x40 - GetRC500(RegFIFOLength);
                if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
                    {
                    nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
                    PutRC500(RegInterruptEn,0x01); // disable LoAlert IRQ
                    }
                for ( cnt = 0;cnt < nbytes;cnt++)
                    {
                    PutRC500(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
                    MpIsrInfo->nBytesSent++;
                    //dog=~dog;
                    }
                PutRC500(RegInterruptRq,0x01);        // reset IRQ bit
                }
            if (irqBits & 0x10)         // TxIRQ
                {
                PutRC500(RegInterruptRq,0x10);        // reset IRQ bit
                PutRC500(RegInterruptEn,0x82);        // enable HiAlert Irq for
                                                // response
                if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
                    {
                    PutRC500(RegChannelRedundancy,0x02); // RxCRC and TxCRC disable, parity disable
                    PutRC500(RegPage,0x00);       // reset page address
                    }
                }
            if (irqBits & 0x0E)         // HiAlert, Idle or RxIRQ
                {
                nbytes = GetRC500(RegFIFOLength);
                for ( cnt = 0; cnt < nbytes; cnt++)
                    {
                    MpIsrIn[MpIsrInfo->nBytesReceived] = GetRC500(RegFIFOData);
                    MpIsrInfo->nBytesReceived++;
                    }
                PutRC500(RegInterruptRq,0x0A & irqBits);
                }
            if (irqBits & 0x04)         // Idle IRQ
                {
                PutRC500(RegInterruptEn,0x20); // disable Timer IRQ
                PutRC500(RegInterruptRq,0x20); // disable Timer IRQ request
                irqBits &= ~0x20;       // clear Timer IRQ in local var
                MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
                PutRC500(RegInterruptRq,0x04);        // reset IRQ bit
                }
            if (irqBits & 0x20)     // timer IRQ
                {
                PutRC500(RegInterruptRq,0x20); // reset IRQ bit
                MpIsrInfo->status = MI_NOTAGERR; // timeout error
                }
        }
        PutRC500(RegPage,oldPageSelect | 0x80);
    }
}

// 在一个页内向RC500寄存器送数据
// 因为地址线只有3条,此操作可寻址8个地址
void PutRC500(unsigned char address,unsigned char dat3)//ok
{
    tris_data_port=tris_output;
    data_port=address;
    rc500_ale=1;
    rc500_ale=0;
    rc500_cs=0;
    data_port=dat3;
    rc500_wr=0;
    delay();
    rc500_wr=1;
    rc500_cs=1;
}
// 在一个页内从RC500寄存器读数据
// 因为地址线只有3条,此操作可寻址8个地址
char GetRC500(unsigned char address)//ok
{
    unsigned char temp_data;
    tris_data_port=tris_output;
    data_port=address;
    rc500_ale=1;
    rc500_ale=0;
    rc500_cs=0;
    tris_data_port=tris_input;
    rc500_rd=0;
    temp_data=data_port;
    rc500_rd=1;
    rc500_cs=1;
    return temp_data;
}
// 写数据到RC500指定寄存器
void WriteRC(unsigned char Address, unsigned char value)//ok
{
    PutRC500(0x00,GetRegPage(Address));   // select appropriate page
    PutRC500(Address,value);              // write value at the specified
}

// 从RC500指定寄存器读数据
char ReadRC(unsigned char Address)//ok
{
    PutRC500(0x00,GetRegPage(Address));   // select appropriate page
    return GetRC500(Address);              // read value at the specified
}
char PcdReset(void)
{
    unsigned int i,count01,count02;
    char ret_status = MI_OK;

    rc500_rst=0;                                                // CLEAR_MRST();
    for(i=0;i<16500;i++)
    {clrwdt();}
        rc500_rst=1;                                            // SET_MRST();
    for(i=0;i<1650;i++)
    {clrwdt();}
        rc500_rst = 0;                                          // CLEAR_MRST();
    rc500_cs  = 0;
    rc500_wr  = 1;
    rc500_rd  = 1;
    rc500_ale = 0;
    count01=Timecount;                                          // start_timeout(21);
    count02=21;
    // 检查是否复位成功,RegCommand&0x3F=0x3F?
    while (((GetRC500(RegCommand) & 0x3F) != 0x3F) && (!(count02==0)))
    {
        count01--;
        if (count01==0)
        {
            count01=Timecount;
            count02--;
        }
    };
    // 命令寄存器的Bit[0..5]不为全1,则认为复位不成功
    while ((GetRC500(RegCommand) & 0x3F) && (!(count02==0)))
    {
        clrwdt();
        count01--;
        if (count01==0)
        {
            count01=Timecount;
            count02--;
        }
    };
                                                                //stop_timeout();
    if (count02==0)
    {
        ret_status = MI_RESETERR; // 芯片复位不正确
    }
    if (ret_status == MI_OK)
    {
        PutRC500(RegPage,0x80); // Dummy access in order to determine the bus
        for(i=0;i<15;i++);
/*            {
            if (rc500_ale==0)
                rc500_ale=1;
            else
                rc500_ale=0;
            }*/
        rc500_ale=0;
        ret_status= GetRC500(RegCommand);
        if (ret_status!= MI_OK)
        {
            ret_status = MI_INTERFACEERR;
        }
        else
        {
            PutRC500(RegPage,0x00);                           // sequence is ok
        }
    }
    return ret_status;
}
// 设置RC500配置
char RC500Config(void)
{
    unsigned char i;
//    unsigned char temp;
    char ret_status = MI_RESETERR;//-25
    ret_status = PcdReset();
    if (ret_status == MI_OK)//0
    {
        WriteRC(RegClockQControl,0x80); // RegClockQControl:0x1f
        for(i=0;i<205;i++);
        WriteRC(RegClockQControl,0xc0); //新加
        for(i=0;i<105;i++);
        ClearBitMask(RegClockQControl,0x40);
//        WriteRC(RegCRCPresetLSB,0xAA);
//        WriteRC(RegCRCPresetMSB,0xAA);
        WriteRC(RegBitPhase,0xAD);
//        WriteRC(RegRxWait,0x10);
        WriteRC(RegRxThreshold,0xff);
        WriteRC(RegRxControl1,0x73);            //新加
        WriteRC(RegRxControl2,0x81);            //新改, 原为 0
        WriteRC(RegFIFOLevel,0x4);
        WriteRC(RegTimerControl,0x02);
        PcdSetTmo(1);                           // short timeout
        WriteRC(RegIRqPinConfig,0x3);
//        WriteRC(RegCwConductance,0x39);
        PcdRfReset(1);
    }
    return ret_status;
}
char RC500OutSelect(unsigned char type)
{
   WriteRC(RegMfOutSelect,type&0x7);
   return MI_OK;
}


char Mf500PiccRequest(unsigned char req_code,unsigned char *atq)
{
    return Mf500PiccCommonRequest(req_code,atq);
}

char Mf500PiccCommonRequest(unsigned char req_code,unsigned char *atq)          //ok
{
    char ret_status = MI_OK;
    PcdSetTmo(106);
    // 关闭CRC校验,采用偶校验,RegChannelRedundancy是校验标志寄存器
    WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
    //
    WriteRC(RegControl,0x08);
//     ClearBitMask(RegControl,0x08);  // disable crypto 1 unit
    WriteRC(RegBitFraming,0x07);    // set TxLastBits to 7

    ResetInfo(MInfo);

    MSndBuffer[0] = req_code;
    MInfo.nBytesToSend = 1;
    ret_status = PcdSingleResponseCmd(0x1e);

    if (ret_status)     // error occured
    {
        *atq = 0;
    }
    else
    {
        if (MInfo.nBitsReceived != 16) // 2 bytes expected
        {
            ret_status = MI_BITCOUNTERR;
        }
        else
        {
            ret_status = MI_OK;
            memcpy(atq,MRcvBuffer,2);
        }
    }
    return ret_status;
}

char Mf500PiccAnticoll(unsigned char bcnt,unsigned char *snr)
{
    return Mf500PiccCascAnticoll(0x93,bcnt,snr); // first cascade level
}
//
char Mf500PiccCascAnticoll (unsigned char select_code,unsigned char bcnt,unsigned char *snr)
{
    signed char ret_status = MI_OK;
    unsigned char snr_in[4];      // copy of the input parameter snr
    unsigned char nbytes = 0;     // how many bytes received
    unsigned char nbits = 0;      // how many bits received
    unsigned char complete = 0;   // complete snr recived
    unsigned char i = 0;
    unsigned char byteOffset = 0;
    unsigned char snr_crc;    // check byte calculation
    unsigned char snr_check;
    unsigned char dummyShift1;        // dummy byte for snr shift
    unsigned char dummyShift2;        // dummy byte for snr shift

//     if ((ret_status = Mf500PcdSetDefaultAttrib()) == MI_OK)
//     {
        PcdSetTmo(106);
        memcpy(snr_in,snr,4);
        WriteRC(RegDecoderControl,0x28); // ZeroAfterColl aktivieren
        ClearBitMask(RegControl,0x08);  // disable crypto 1 unit
        complete=0;
        while (!complete && (ret_status == MI_OK) )
        {
            ResetInfo(MInfo);
            WriteRC(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
            nbits = bcnt % 8;       // remaining number of bits
            if (nbits)
            {
                WriteRC(RegBitFraming,nbits << 4 | nbits); // TxLastBits/RxAlign auf nb_bi
                nbytes = bcnt / 8 + 1;
                if (nbits == 7 )
                {
                    MInfo.cmd = PICC_ANTICOLL1;     // pass command flag to ISR
                    WriteRC(RegBitFraming,nbits); // reset RxAlign to zero
                }
            }
            else
            {
                nbytes = bcnt / 8;
            }
            MSndBuffer[0] = select_code;
            MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
            for (i = 0; i < nbytes; i++)    // Sende Buffer beschreiben
            {
                MSndBuffer[i + 2] = snr_in[i];
            }
            MInfo.nBytesToSend = 2 + nbytes;
            ret_status = PcdSingleResponseCmd(0x1e);
            if (nbits == 7)
            {
                dummyShift1 = 0x00;
                for (i = 0; i < MInfo.nBytesReceived; i++)
                {
                    dummyShift2 = MRcvBuffer[i];
                    MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[i] << (7-i));
                    dummyShift1 = dummyShift2;
                }
                MInfo.nBitsReceived -= MInfo.nBytesReceived; // subtract received parity bits
                if ( MInfo.collPos )
                    MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
            }
            if ( (ret_status == MI_OK) || (ret_status == MI_COLLERR))   // no other occured
            {
                if ( MInfo.nBitsReceived != (40 - bcnt) ) // not 5 bytes answered
                {
                    ret_status = MI_BITCOUNTERR;
                }
                else
                {
                    byteOffset = 0;
                    if ( nbits != 0 )               // last byte was not complete
                    {
                        snr_in[nbytes - 1] = snr_in[nbytes - 1] | MRcvBuffer[0];
                        byteOffset = 1;
                    }
                    for ( i =0; i < (4 - nbytes); i++)
                    {
                        snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
                    }
                    if (ret_status != MI_COLLERR ) // no error and no collision
                    {
                        snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
                        snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
                        if (snr_crc != snr_check)
                        {
                            ret_status = MI_SERNRERR;
                        }
                        else
                        {
                            complete = 1;
                        }
                    }
                    else                    // collision occured
                    {
                        bcnt = bcnt + MInfo.collPos - nbits;
                        ret_status = MI_OK;
                    }
                }
            }
//         }
    }
    if (ret_status == MI_OK)
        {
        memcpy(snr,snr_in,4);
        }
    else
        {
        for(i=0;i<4;i++)
            snr[i]=0;
        memcpy(snr,"0000",4);
        }
    ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
    return ret_status;
}
//
char Mf500PiccSelect(unsigned char *snr,unsigned char *sak)
{
    return Mf500PiccCascSelect(0x93,snr,sak); // first cascade level
}
//
char Mf500PiccCascSelect(unsigned char select_code,unsigned char *snr,unsigned char *sak)
{
    char ret_status = MI_OK;

//     if ((ret_status = Mf500PcdSetDefaultAttrib()) == MI_OK)
//  {
        PcdSetTmo(106);
        WriteRC(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
        ClearBitMask(RegControl,0x08);  // disable crypto 1 unit
        ResetInfo(MInfo);
        MSndBuffer[0] = select_code;
        MSndBuffer[1] = 0x70;    // number of bytes send
        memcpy(MSndBuffer + 2,snr,4);
        MSndBuffer[6] = MSndBuffer[2]
                        ^ MSndBuffer[3]
                        ^ MSndBuffer[4]
                        ^ MSndBuffer[5];
        MInfo.nBytesToSend = 7;
        ret_status = PcdSingleResponseCmd(0x1e);
        *sak = 0;
        if (ret_status == MI_OK)    // no timeout occured
        {
            if (MInfo.nBitsReceived != 8)   // last byte is not complete
            {
                ret_status = MI_BITCOUNTERR;
            }
            else
            {
                *sak = MRcvBuffer[0];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -