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

📄 m500auc.c

📁 51单片机进行mifare1射频卡开发
💻 C
📖 第 1 页 / 共 5 页
字号:
#define M500_GLOBALS

//PICC=卡,PCD=阅读器

//以下位要包含的头文件
#include <string.h>           /*字符串函数及存储器函数头文件*/
#include <stdio.h>            /*标准I/O头文件*/
#include <absacc.h>           /*存储器绝对地址访问定义,与指令MOVX相关*/
#include <intrins.h>          /*内部函数定义,与循环指令(例如RR),位判断指令(例如JB),以及空操作指令(NOP)等相关*/

#include "Mfreg500.h"         /* MF-RC500内部寄存器定义头文件*/
#include "MfErrNo.h"          /* MF-RC500内部寄存器错误标志头文件*/
#include "reg52.h"            /* 8052内部寄存器定义头文件*/
#include "M500AuC.h"          /* MF-RC500用户自定义相关变量和数据结构头文件*/

#define GetRegPage(addr)    (0x80 | (addr>>3))   /* 将addr右移3位再与80h取或 */
#define nocard			    0    /*能量场中没有卡*/
#define mifare1			    1    /*场中有mifare1卡 */
#define mifarepro		    2    /*场中有mifarepro卡 */
#define mifarelight		    3    /*场中有mifarelight卡 */
#define unknowncard		    4    /*场中有未知卡 */
#define NO_TIMER2                   1    /*? */

#define uchar unsigned char
bdata uchar AA;                   //A,可位寻址单字节数据类型
sbit  high_bit=AA^7;              //ACC.7
sbit  low_bit=AA^0;               //ACC.0


//uchar sebuf;                //RECBUF,SENBUF
uchar idata disp_buf[4];

void  del_8us()
{
      uchar i;
	  for(i=0;i<1;i++)
	     {;}
}

void  del_50us()                  //延时子程序
{
      uchar i;
	  for(i=0;i<6;i++)
	     {;}
}

void  del_50ms()
{
      uchar i,j;
	  for(i=0;i<255;i++)
	     for(j=0;j<255;j++)
	     {;}
}

void send(uchar sebuf)              //发送子程序
{
      uchar i;
 	  AA=sebuf;
	  CLK=0;
	  CS=0;
	  del_50us();
	  for(i=0;i<8;i++)
	  {
           del_8us();
	   DIO=high_bit;
	   CLK=1;
           del_8us();
           AA=AA<<1;                //循环移位
 	   CLK=0;
	  }
          DIO=0;
}

void reset_light()                    //复位子程序
{
      KEY=1;
      DIO=1;
      del_8us();
      send(0xa4);
      CS=1;
      del_8us();
}

void reset_7289()
{
  reset_light();                    //上电初检
  send(0xbf);
  CS=1;                       //测试所有的led灯
  del_50ms();
  reset_light();                    //恢复熄灭状态
}

void display()
{
 uchar i;
 for(i=0;i<4;i++)
    {send(0xa1);CS=1;del_8us();               //逻辑左移指令
     send(0xc8);
     send((disp_buf[i]>>4)&0x0f);CS=1;del_8us();
     send(0xa1);CS=1;del_8us();               //逻辑左移指令
     send(0xc8);
     send(disp_buf[i]&0x0f);CS=1;del_8us();
    }
}


///////////////////////////////////////////////////////////////////////
                 /* 往一个寄存器写一个数据 */
///////////////////////////////////////////////////////////////////////
void WriteRawIO(unsigned char Address,unsigned char value)
{
	XBYTE[Address]=value;        /* 调用XBYTE函数? */
}

///////////////////////////////////////////////////////////////////////
                /* 从一个寄存器读出一个数据 */
///////////////////////////////////////////////////////////////////////
unsigned char ReadRawIO(unsigned char Address)
{
	return XBYTE[Address];       /* 调用XBYTE函数 */
}

///////////////////////////////////////////////////////////////////////
               /* 用页选方式访问寄存器(写入)*/
///////////////////////////////////////////////////////////////////////
void WriteIO(unsigned char Address, unsigned char value)
{
    WriteRawIO(0x00,GetRegPage(Address));      /* 调用writerawio()函数,页选(80h-87h) */
    WriteRawIO(Address,value);                 /* 调用writerawio()函数,选择一个寄存器(0-7h) */
}

///////////////////////////////////////////////////////////////////////
               /* 用页选方式访问寄存器(读出)*/
///////////////////////////////////////////////////////////////////////
unsigned char ReadIO(unsigned char Address)
{
   WriteRawIO(0x00,GetRegPage(Address));       /* 调用writerawio()函数,页选 */
   return ReadRawIO(Address);                  /* 调用readrawio()函数 */
}

///////////////////////////////////////////////////////////////////////
                     /* 设置定时时间 */
///////////////////////////////////////////////////////////////////////
void M500PcdSetTmo(unsigned char tmoLength)
{
    switch(tmoLength)
    {
        case 1:
            WriteIO(RegTimerClock,0x07);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,0x6a);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(6AH) */
            break;
        case 2:
            WriteIO(RegTimerClock,0x07);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,0xa0);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(A0H) */
            break;
        case 3:
            WriteIO(RegTimerClock,0x09);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/512--2^9 */
            WriteIO(RegTimerReload,0xa0);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(A0H) */
            break;
        case 4:
            WriteIO(RegTimerClock,0x09);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(09H)=13.56MHZ/512--2^9 */
            WriteIO(RegTimerReload,0xff);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(FF) */
            break;
        case 5:
            WriteIO(RegTimerClock,0x0b);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,0xff);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(FFH) */
            break;
        case 6:
            WriteIO(RegTimerClock,0x0d);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,0xff);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(FFH) */
            break;
        case 7:
            WriteIO(RegTimerClock,0x0f);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,0xff);     /* 调用WRITEIO()函数,从单片机写计时器的初始值(FFH) */
            break;
        default:                              /* 其它情况 */
            WriteIO(RegTimerClock,0x07);      /* 调用WRITEIO()函数,从单片机写计时器得分频比(07H)=13.56MHZ/128--2^7 */
            WriteIO(RegTimerReload,tmoLength);  /* 调用WRITEIO()函数,从单片机写计时器的初始值(TMOLENTH) */
            break;
    }
}

///////////////////////////////////////////////////////////////////////
// Request Command defined in ISO14443(Mifare)
           /* 命令判别程序 */
///////////////////////////////////////////////////////////////////////
char  M500PcdCmd(unsigned char cmd,
                 volatile unsigned char data *rcv,
                 MfCmdInfo idata *info)
{
    char          idata status    = MI_OK;
    char          idata tmpStatus ;               /* 中间状态寄存器 */
    unsigned char idata lastBits;                 /* 中间状态寄存器 */
    unsigned int  idata timecnt = 0;
    unsigned char idata irqEn = 0x00;
    unsigned char idata waitFor = 0x00;
    unsigned char idata timerCtl  = 0x00;

    WriteIO(RegInterruptEn,0x7F);                 /*(06H)SETEN,0,TIMER,TX,RX,IDLE,HI,LO=0111,1111:禁中断使能  */
    WriteIO(RegInterruptRq,0x7F);                 /* (07H) SETIRQ,0,TIMER,TX,RX,IDLE,HI,LO=0111,1111:禁中断请求 */
    WriteIO(RegCommand,PCD_IDLE);                 /* (01H) 命令代号均写入此处相当于单片机的指令寄存器PC:进入待命态 */

    FlushFIFO();                                  /* 清缓冲区标志,这样FIFO区就可供单片机或RC500状态机使用  */
    MpIsrInfo = info;                             /* ? */
    MpIsrOut = rcv;                               /* 接收数据缓冲区 */
    info->irqSource = 0x00;                       /* ->:存储结构或联合单元(右结合)  */
    switch(cmd)
    {                                             /* 根据输入的命令分支 */
        case PCD_IDLE:                            /* 是IDLE命令(00H) */
            irqEn = 0x00;
            waitFor = 0x00;
            break;
        case PCD_WRITEE2:                         /* 是写EEROM命令(01H) */
            irqEn = 0x11;
            waitFor = 0x10;
            break;
        case PCD_READE2:                          /* 是读EEROM命令(03H) */
            irqEn = 0x07;
            waitFor = 0x04;
            break;
        case PCD_LOADCONFIG:                      /* 是载入配置命令(07H) */
        case PCD_LOADKEYE2:                       /* 是从EEROM载入密钥命令(0BH) */
        case PCD_AUTHENT1:                        /* 是执行认证1命令(0CH) */
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_CALCCRC:                         /* 是激活CRC命令(12H) */
            irqEn = 0x11;
            waitFor = 0x10;
            break;
        case PCD_AUTHENT2:                        /* 是执行认证2命令(14H) */
            irqEn = 0x04;
            waitFor = 0x04;
            break;
        case PCD_RECEIVE:                         /* 是激活接收器命令(16H) */
            info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
            irqEn = 0x06;
            waitFor = 0x04;
            break;
        case PCD_LOADKEY:                         /* 是从FIFO中载入密钥命令(19H) */
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_TRANSMIT:                        /* 是将FIFO数据发送到卡片命令(1AH) */
            irqEn = 0x05;
            waitFor = 0x04;
            break;
        case PCD_TRANSCEIVE:                      /* 是先发送然后立即接收命令(1EH) */
	        info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
            irqEn = 0x3D;
            waitFor = 0x04;
            break;
        default:
            status = MI_UNKNOWN_COMMAND;          /* 是未知命令 */
    }
    if (status == MI_OK)                          /* 命令是否被正确执行 */
    {                                             /* 是的 */
        irqEn |= 0x20;                            /* 开启定时器 */
        waitFor |= 0x20;
        timecnt=1000;                             /* ? */
        WriteIO(RegInterruptEn,irqEn | 0x80);     /* 开相应的中断使能 */
        WriteIO(RegCommand,cmd);                  /* 写入相应的入口命令 */
        while (!(MpIsrInfo->irqSource & waitFor||!(timecnt--)));   /* 错误发生情况1?  */
        WriteIO(RegInterruptEn,0x7F);             /* 定时器计完,禁中断系统 */
        WriteIO(RegInterruptRq,0x7F);
        SetBitMask(RegControl,0x04);              /* 这一位设置作用是立即结束中断计时 */
        WriteIO(RegCommand,PCD_IDLE);             /* 进入IDLE态 */
        if (!(MpIsrInfo->irqSource & waitFor))     /* 错误发生情况2  */
        {
            status = MI_ACCESSTIMEOUT;             /* 在规定的时间内没有完成任务 */
        }
        else                                       /* 错误发生情况3  */
        {
            status = MpIsrInfo->status;
        }
        if (status == MI_OK)                       /* 命令执行成功  */
        {
            if (tmpStatus = (ReadIO(RegErrorFlag) & 0x17))   /* 取出错误状态寄存器内容  */
            {
                if (tmpStatus & 0x01)              /* 取出比特碰撞位,是否为1(1:有碰撞)  */
                {
                    info->collPos = ReadIO(RegCollPos);      /* 得到碰撞的具体位置  */
                    status = MI_COLLERR;                     /* 有碰撞  */
                }
                else
                {
                    info->collPos = 0;                       /* 无碰撞  */
                    if (tmpStatus & 0x02)
                    {
                        status = MI_PARITYERR;               /* 1:奇偶校验错 */
                    }
                }
                if (tmpStatus & 0x04)              /* 取出帧检测位,是否为1(1:帧头错SOF)  */
                {
                    status = MI_FRAMINGERR;        /* 1:帧头错SOF */
                }
                if (tmpStatus & 0x10)              /* 取出FIFO状态位,是否为1 */
                {
                    FlushFIFO();                   /* 清缓冲区 */
                    status = MI_OVFLERR;           /* 1:FIFO满 */
                }
 	            if (tmpStatus & 0x08)          /* 取出crc校验位,是否为1 */
	            {
                    status = MI_CRCERR;            /* 1:CRC校验错 */
	            }
                if (status == MI_OK)
                    status = MI_NY_IMPLEMENTED;     //该命令不存在
            }
            if (cmd == PCD_TRANSCEIVE)             /* 如果是发接指令1 */

⌨️ 快捷键说明

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