📄 m500auc.c
字号:
#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 + -