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

📄 m500auc.c

📁 射频卡读卡头的程序
💻 C
📖 第 1 页 / 共 5 页
字号:

#pragma large

//#include <w77e58.h>
#include <cpu.h>

#include <Mfreg500.h>
#include <M500A.h>
#include <RdIo.h>

#include <string.h>
#include <stdio.h>
#include <main.h>

////////////////////////////////////////////////////////////////////////////////
//                M O D U L E   D E F I N I T I O N
////////////////////////////////////////////////////////////////////////////////
// COMMENT: This library module is modified from the original source code for a
//	    microcontroller C164 CI, to suit the general purpose 8051 mcu.
//          The source can be ported to other platforms very easily.
//          The communication channel to the RC500 reader IC is assumed to be
//          unknown. All data is written with the generic IO functions
//          of the module ReaderIO.h. In our case the reader module is
//          connected via memory mapped io at base address 0x7f00.
//          The interrupt pin of the reader IC is assumed to be connected to
//          the fast external interrupt pin INT0# (active low) and the reset
//          pin of the reader IC should be connected to a dedicated port pin
//          (Port3: Pin: 3).
//          In this configuration, a reset of the reader module is independend
//          from the reset of the microcontroller.
//          In order to generate communication timeouts,
//          general purpose timer 2 of the microcontroller is used. This
//          timer need not to be initialised in advance. Before every usage
//          the timer is completely initialised in each function.
//          Non of the timers is essential for the functionality of the reader
//          module, but are helpful furing software development. All protocoll
//          relevant timing constraints are generated
//          by the internal timer of the reader module.
//
//          Some explanations to the programming method of this library.
//          There are three kind of functions coded in this module.
//            a) internal functions, which have no prototypes in a header
//               file and are not intended to be used outside of this file
//            b) commands, which are intended for the reader module itself
//            c) commands, which are intended for any tag in the rf field.
//               These commands are send to the reader and the reader module
//               transmitts the data to the rf interface.
//          Commands for the reader and for the tag have the appropriate
//          prefix (PCD for proximity coupled device or reader module
//                  PICC for proximity integrated circuit card or tag)
//          and their protypes are defined in the header file.
//          Each command for a PICC consists of a PCD command. Therefore
//          the function M500PcdCmd is very important for the understanding
//          of the communication.
//
//          The basic functionality is provided by the interrupt service
//          routine (ISR), which closely works together with the function
//          M500PcdCmd. All kinds of interrupts are serviced by the
//          same ISR.


static  unsigned char   keycoded[12];
//         存取控制字节:    0xff,0x07,0x80,0x69 

uchar code AledKey[16][12]={{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0x08,0x04,0x08,0x00,0x02,0x01,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                             {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
                           } ;

// inline structure in order to reset the communication channel between
// function and ISR
#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;

// struct definition for a communication channel between function and ISR
typedef struct
         {
            unsigned char   cmd;           //!< command code
            char            status;        // communication status
            unsigned char   nBytesSent;    // how many bytes already sent
            unsigned char   nBytesToSend;  // how many bytes to send
            unsigned char   nBytesReceived;// how many bytes received
            unsigned short  nBitsReceived; // how many bits received
            unsigned char   irqSource;     // which interrupts have occured
            unsigned char   collPos;       // at which position occured a
                                          // collision
         } MfCmdInfo;

// modul variables
extern	 unsigned char xdata *GpBase;

static   unsigned char data MFIFOLength = DEF_FIFO_LENGTH; // actual FIFO length

static   unsigned char xdata MKeys[16][12]; // storage for authentication keys
                                      // in order to provide a calling
                                      // compatible interface to old libraries
                             // Other reader modules keep several sets
                             // of keys in an E2PROM. In this case,
                             // these keys are stored in the uC and
                             // transfered to the reader module
                             // before authentication

// Infomation concerning data processing
         // send buffer for general use
static   volatile unsigned char xdata MSndBuffer[SND_BUF_LEN];
         // receive buffer for general use
static   volatile unsigned char xdata MRcvBuffer[RCV_BUF_LEN];
         // info struct for general use
static   volatile  MfCmdInfo  xdata   MInfo;

// Interrupt service routine
// Variable in order to exchange data between function and ISR
static   volatile MfCmdInfo      xdata   *MpIsrInfo = 0;
        // ISR send buffer
static   volatile unsigned char  xdata   *MpIsrOut  = 0;
         // ISR receive buffer
static   volatile unsigned char  xdata   *MpIsrIn   = 0;

// storage of the last selected serial number including check byte.
//For multi level serial numbers, only the first 4 bytes are stored.
unsigned char MLastSelectedSnr[5];

// Timer 2
bit		      data  T2IR	 	= 0;        	// Timer2 timeout flag
unsigned int  data	CountDown	= 0;	// Timeout counter with 50us resolution



///////////////////////////////////////////////////////////////////////////////
//             Prototypes for local functions
///////////////////////////////////////////////////////////////////////////////

void start_timeout(unsigned int _50us);
void stop_timeout(void);

// _____________________________________________________________________________
//
//  FUNCTION: M500PcdSetTmo
//        IN: tmoLength   1  ... 1.0 ms timeout periode
//                        2  ... 1.5 ms timeout periode
//                        3  ... 6.0 ms timeout periode
//        		  4  ... 9.6 ms timeout period
//                        5  ... 38.5 ms timeout period
//                        6  ... 154 ms timeout period
//                        7  ... 616.2 ms timeout period
//       OUT: -
//    RETURN:
//   COMMENT: Set timeout length of the reader internal timer.
//
void M500PcdSetTmo(unsigned char tmoLength);

// _____________________________________________________________________________
//
//  FUNCTION: M500PcdCmd
//        IN: cmd  PCD_IDLE
//                   PCD_WRITEE2
//                   PCD_READE2
//                   PCD_LOADCONFIG
//                   PCD_LOADKEYE2
//                   PCD_AUTHENT1
//                   PCD_CALCCRC
//                   PCD_AUTHENT2
//                   PCD_RECEIVE
//                   PCD_LOADKEY
//                   PCD_TRANSMIT
//                   PCD_TRANSCEIVE
//                   PCD_RESETPHASE
//                   for a detailed description of the parameter values, please
//                   have a look on the header file of the reader register
//                   definitions.
//            send      byte stream of variable length, which should be send to
//                      the PICC, the length of stream has to be specified
//                      in the info - structure
//       OUT: rcv    byte stream of variable length, which was received
//                      from the PICC or PCD
//            info      communication and status structure
//    RETURN:
//   COMMENT: This function provides the central interface to the reader module.
//            Depending on the "cmd"-value, all necessary interrupts are enabled
//            and the communication is started. While the processing is done by
//            the reader module, this function waits for its completion.
//            It's notable, that the data in the "send byte stream" is written
//            to the FIFO of the reader module by the ISR. Immediate after
//            enabling the interrupts, the LoAlert interrupt is activated.
//            The ISR writes the data to the FIFO. This function is not involved
//            in writing or fetching data from FIFO, all work is done by the
//            ISR.After command completion, the error status is evaluated and
//            returned to the calling function.
//
char M500PcdCmd(unsigned char cmd,
                volatile unsigned char* send,
                volatile unsigned char* rcv,
                volatile MfCmdInfo *info);

// _____________________________________________________________________________
//
//  FUNCTION: SetBitMask
//        IN: reg      register address
//            mask     bit mask to set
//       OUT: -
//    RETURN:
//   COMMENT:  This function performs a read - modify - write sequence
//             on the specified register. All bits with a 1 in the mask
//             are set - all other bits keep their original value.
//
char SetBitMask(unsigned char reg,unsigned char mask);

// _____________________________________________________________________________
//
//  FUNCTION: ClearBitMask
//        IN: reg      register address
//            mask     bit mask to clear
//       OUT: -
//    RETURN:
//   COMMENT:  This function performs a read - modify - write sequence
//             on the specified register. All bits with a 1 in the mask
//             are cleared - all other bits keep their original value.
//
char ClearBitMask(unsigned char reg,unsigned char mask);

// _____________________________________________________________________________
//
//  FUNCTION: FlushFIFO
//        IN: -
//       OUT: -
//    RETURN:
//   COMMENT: All remaining date in the FIFO of the reader module is
//            erased by this function. Before wrinting new data or
//            starting a new command, all remaining data from former
//            commands should be deleted. Please note, that in
//            normal operation, never data should be left, that means
//            that a call to this function should not be necessary.
//
void FlushFIFO(void);

// _____________________________________________________________________________
//
//  FUNCTION: M500PiccAuthState
//        IN: auth_mode
//            snr
//            sector
//       OUT: -
//    RETURN:
//   COMMENT:
//
char M500PiccAuthState(unsigned char auth_mode,// PICC_AUTHENT1A, PICC_AUTHENT1B
                       unsigned char *snr,    // 4 byte serial number
                       unsigned char sector); // 0 <= sector <= 15
                                            // sector address for authentication

//////////////////////////////////////////////////////////////////////
//           E X C H A N G E   B Y T E   S T R E A M
///////////////////////////////////////////////////////////////////////
char ExchangeByteStream(unsigned char Cmd,
                        unsigned char *send_data,
                        unsigned char send_bytelen,
                        unsigned char *rec_data,
                        unsigned char *rec_bytelen);

///////////////////////////////////////////////////////////////////////////////
//                   Handler RC500
// RC500 与Mifare 卡之间的数据通讯由中断服务程序完成
// 入口参数: 1. *MpIsrInfo  通讯参数结构指针
//           2. *MpIsrout   发送数据指针 send
//           3. *MpIsrin    接收数据指针 rec         
///////////////////////////////////////////////////////////////////////////////
void RC500ISR (void) interrupt 2 using 1    //Ext1 interrupt
{
   static uchar data irqBits;
   static uchar data irqMask;   
   static uchar data nbytes;
   static uchar data cnt;

   IE1 = 0; 	// Clear interrupt request flag

   if (MpIsrInfo && MpIsrOut && MpIsrIn)  // transfer pointers have to be set  correctly
   {
      while( ReadRawIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending
                                                 // Attention: IRQ bit is
                                                 // inverted when used with
                                                 // low activ IRQ
      {
         irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts
         // read pending interrupts
         irqBits = ReadRawIO(RegInterruptRq) & irqMask;//irqBits 表示何种中断
         MpIsrInfo->irqSource |= irqBits; // save pending interrupts
         //************ LoAlertIRQ ******************
         if (irqBits & 0x01)    // LoAlert
         {
            // MFIFOLength = DEF_FIFO_LENGTH;
           
            nbytes = MFIFOLength - ReadRawIO(RegFIFOLength);//计算FIFO 可以容纳的字节空间
            // less bytes to send, than space in FIFO
           
            if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)//需要发送的字节数<FIFO 可以容纳的字节空间 按照需要发送的字节数
            {
               nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;//需要发送的字节数
               WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ
            }
            // write remaining data to the FIFO
            for ( cnt = 0;cnt < nbytes;cnt++)
            {
               WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
               MpIsrInfo->nBytesSent++;
            }
            WriteRawIO(RegInterruptRq,0x01);  // reset IRQ bit
         }

         //************* TxIRQ Handling **************
         if (irqBits & 0x10)       // TxIRQ
         {
            WriteRawIO(RegInterruptRq,0x10);    // reset IRQ bit
            WriteRawIO(RegInterruptEn,0x82);    // enable HiAlert Irq for
                                           // response
            if (MpIsrInfo->cmd == PICC_ANTICOLL1) 	// if cmd is anticollision
	        {                                           // switch off parity generation
               WriteRawIO(RegChannelRedundancy,0x02);	// RXCRC and TXCRC disable, parity disable
	        }
         }

         //************* HiAlertIRQ or RxIRQ Handling ******************
         if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
         {
            // read some bytes ( length of FIFO queue)
            // into the receive buffer
            nbytes = ReadRawIO(RegFIFOLength);
            // read date from the FIFO and store them in the receive buffer
            for ( cnt = 0; cnt < nbytes; cnt++)
            {
               MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
               MpIsrInfo->nBytesReceived++;
               Temp =  MpIsrIn[MpIsrInfo->nBytesReceived] ;
            }
            WriteRawIO(RegInterruptRq,0x0A & irqBits);
                                       // reset IRQ bit - idle irq will
                                       // be deleted in a seperate section
         }

         //************** IdleIRQ Handling ***********
         if (irqBits & 0x04)     // Idle IRQ
         {
            WriteRawIO(RegInterruptEn,0x20); // disable Timer IRQ

⌨️ 快捷键说明

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