📄 main.c
字号:
/****************************************************************************
* File : main.c *
* COPYRIGHT BY HUOYAN LTD.COMPANY *
* Version: V5.2 *
* Created: 18.11.2002 *
* Last Change: 8.Jan.2005 *
* Author: NIL *
* Compiler: KEIL C51 V7.10 *
* Description: AT89S52-Firmware for MFRC500 Demo Serial Reader *
* *
****************************************************************************/
#define __SRC
#include "main.h"
#undef __SRC
#include <string.h>
#include <stdio.h>
#include <absacc.h>
#include <intrins.h>
#include "AT89S52.h"
#include "Mfreg500.h"
#include "M500a.h"
#define uchar unsigned char
#define uint unsigned int
//#define DataPort P0 // 数据端口
//pin define mcu控制管脚定义
sbit RC500RST = P1^0; //由高变低时复位RC500
sbit RC500CS=P1^1;
sbit CARD_LED=P1^2;
sbit SPEAKER = P1^3;
bit bcard;
///////////////////////////////////////////////////////////////////////
// 主函数
///////////////////////////////////////////////////////////////////////
void main(void)
{ //设置变量
uchar baud;
InitSystem(); //初始化系统
// bcard=0;
delay_10ms(5);
while (1)
{
// KeyPress(); 处理按键
delay_10ms(5);
//检查串口命令标志
if (bCmd)
{
bCmd = FALSE; //清零命令标志以便接收下一个命令
if(RevBuffer[0]==0x10) //测试蜂鸣器
{
RevBuffer[2]=RevBuffer[1]; //蜂鸣时间存到RevBuffer[2]
cmd_ok(); //发送测试结果01 00给上位机
TI=1; //准备发给上位机数据
SPEAKER=1; //开蜂鸣器和指示灯
CARD_LED=ON;
delay_10ms(RevBuffer[2]); //延时
SPEAKER=0;
CARD_LED=OFF;
}
else if(RevBuffer[0]==0x11) //串口参数设置,设置通讯波特率
{
switch(RevBuffer[1])
{
case 0:
baud=BAUD_9600;
break;
case 1:
baud=BAUD_14400;
break;
case 2:
baud=BAUD_19200;
break;
case 3:
baud=BAUD_28800;
break;
case 4:
baud=BAUD_38400;
break;
case 5:
baud=BAUD_57600;
break;
case 6:
baud=BAUD_115200;
break;
default:
baud=BAUD_19200;
break;
}
cmd_ok(); //发送测试结果01 00给上位机
TI=1;
delay_10ms(5); //延时设置波特率
TR1 = 0;
TH1 = baud;
TL1 = TH1;
delay_10ms(2);
TR1 = TRUE;
}
else
{
uart_process(); // 进入串口处理程序
TI=1; //处理完准备发送结果给上位机
}
}
}
}
///////////////////////////////////////////////////////////////////////
// 系统初始化
///////////////////////////////////////////////////////////////////////
void InitSystem(void)
{
RC500CS=0; //选中RC500
RC500RST=0; //复位
ET2 = FALSE; // T/C2关中断
T2CON = 0x04; //TR2=1,设为TIMER2,auto reload
PCON = 0x80;
SCON = 0x70; // SMOD = 1;
TMOD = 0x21; //TMOD = 0x22;
TH1 = BAUD_19200; //默认波特率
TL1 = TH1;
TR1 = TRUE; // 以T1作为波特率发生器
ET1=FALSE;
IT0 =TRUE; // Config ext0 as edge trigger for RC500
EX0 =TRUE; // Enable ext0 interrupt for RC500
EA = TRUE; // Enable all interrupts
TR2=FALSE; //Close T2
IP=0x10; // 设串口中断高优先级
ES = TRUE; //打开串口
bCmd=FALSE; //初始化为0,没有收到命令
beep(1); //开机喇叭和指示灯测试
splash(1);
MfConfig(); //配置RC500
}
///////////////////////////////////////////////////////////////////////
// 串口接收和发送中断
//数据包格式:数据包长度L(1byte)+命令字C(1byte)+数据包D(L-1 bytes)
//其中数据包长度是从命令字开始算起的。
///////////////////////////////////////////////////////////////////////
void Uart_Int(void) interrupt 4 using 1
{
uchar len, i;
uint j=0;
if(RI) //收到数据
{
len=SBUF; //第一个字节是数据包的长度
RI=0; //清零RI以便接收下一个
for(i=0;i<len;i++)
{
while(!RI)
{
j++;
if(j>1000)
{
break;
}
}
if(j<1000)
{
RevBuffer[i]=SBUF;
RI=0;
j=0;
}
else
{
break;
}
}
if(i==len)
{
REN=0; // 清零接收位
bCmd=TRUE; //接收完毕,收到命令有效,置位1
}
}
else if(!RI && TI) //发送-RI=0,TI=1
{
TI=0;
len=RevBuffer[0]; //发送的第一个字节是包的长度
for(i=0;i<len+1;i++)
{
SBUF=RevBuffer[i];
while(!TI);
TI=0;
}
REN=1;
}
}
///////////////////////////////////////////////////////////////////////
// IC卡命令处理函数
///////////////////////////////////////////////////////////////////////
void uart_process(void)
{
uchar cmd;
uchar status;
cmd = RevBuffer[0];
switch(cmd)
{
case 0x20: // Request ,寻卡
status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]);
if(status!=0)
{
status=M500PiccCommonRequest(RevBuffer[1],&RevBuffer[2]);
if(status!=0)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
}
if(RevBuffer[2]==2)
cardtype=mifare1S70; // Mifare1 S70 卡
else if(RevBuffer[2]==4)
cardtype=mifare1S50; // Mifare1 S50 卡
else if(RevBuffer[2]==16)
cardtype=mifarelight; // Mifare Light 卡
else
cardtype=unknowncard;
RevBuffer[0]=3; // 返回3个字节:状态(1字节)+卡类型(2字节)
RevBuffer[1]=status;
break;
case 0x21: // 防冲突 读卡的系列号 CardSnr
status = M500PiccCascAnticoll(0,&RevBuffer[2]);
if(status!=0) //失败
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
memcpy(CardSnr,&RevBuffer[2],4); //读出4字节序列号
RevBuffer[0]=5; // 返回5个字节:状态(1字节)+序列号(4字节)
RevBuffer[1]=status;
break;
case 0x22: // 选择卡 Select Card
status=M500PiccCascSelect(CardSnr,&RevBuffer[2]);
if(status!=MI_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
RevBuffer[0]=3;
RevBuffer[1]=status;
break;
case 0x23: // Key loading into the MF RC500's EEPROM
// 校验卡密码(E2)
status=M500PiccAuthE2(RevBuffer[1],CardSnr,RevBuffer[2],RevBuffer[3]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 0x24: // Key loading into the MF RC500's EEPROM
// 下载密码(E2)
status=M500PcdLoadKeyE2(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 0x25: // Read the mifare card
// 读卡
status=M500PiccRead(RevBuffer[1],&RevBuffer[2]);
if(status==0)
{
if(cardtype==mifare1S50||cardtype==mifare1S70)
RevBuffer[0]=17;
else if(cardtype==1)
RevBuffer[0]=9;
else
RevBuffer[0]=16;
}
else
{
RevBuffer[0]=1;
}
RevBuffer[1]=status;
break;
case 0x26: // Write the mifare card
// 写卡 下载密码
status=M500PiccWrite(RevBuffer[1],&RevBuffer[2]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 0x27: //钱包块值操作:加.减,
status = M500PiccValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3],RevBuffer[7]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 0x28: //终止卡的操作
status=M500PiccHalt();
RevBuffer[0]=1; //返回休眠卡的结果
RevBuffer[1]=status;
break;
case 0x29: //进入软件掉电模式
SetBitMask(RegControl,0x10); // PowerDown = 1
cmd_ok(); // 内部电流消耗模块包括晶振在内关闭
break;
case 0x30: //退出软件掉电模式
ClearBitMask(RegControl,0x10); // PowerDown = 0
cmd_ok();
break;
default: // 其余默认操作错误
RevBuffer[0]=1;
RevBuffer[1]=1;
break;
}
}
///////////////////////////////////////////////////////////////////////
//发送命令成功信号0100给上位机
///////////////////////////////////////////////////////////////////////
void cmd_ok(void)
{
RevBuffer[0]=1;
RevBuffer[1]=0;
}
///////////////////////////////////////////////////////////////////////
/**********************RC500操作函数定义******************************/
///////////////////////////////////////////////////////////////////////
// 往一个地址写一个数据
///////////////////////////////////////////////////////////////////////
void WriteRawIO(uchar Address,uchar value)
{
XBYTE[Address]=value;
}
///////////////////////////////////////////////////////////////////////
// 从一个地址读出一个数据
///////////////////////////////////////////////////////////////////////
uchar ReadRawIO(uchar Address)
{
return XBYTE[Address];
}
///////////////////////////////////////////////////////////////////////
// G E N E R I C W R I T E
// 往一个地址写一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
void WriteIO(uchar Address, uchar value)
{
WriteRawIO(0x00,GetRegPage(Address));
WriteRawIO(Address,value);
}
///////////////////////////////////////////////////////////////////////
// G E N E R I C R E A D
// 从一个地址读出一个数据(EEPROM)
///////////////////////////////////////////////////////////////////////
uchar ReadIO(uchar Address)
{
WriteRawIO(0x00,GetRegPage(Address));
return ReadRawIO(Address);
}
///////////////////////////////////////////////////////////////////////
// 设置RC500定时时间
///////////////////////////////////////////////////////////////////////
void M500PcdSetTmo(uchar 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,0x07);
WriteIO(RegTimerReload,tmoLength);
break;
}
}
///////////////////////////////////////////////////////////////////////
// Request Command defined in ISO14443(Mifare)
///////////////////////////////////////////////////////////////////////
char M500PcdCmd(uchar cmd,
volatile uchar data *rcv,
MfCmdInfo idata *info)
{
char idata status = MI_OK;
char idata tmpStatus ;
uchar idata lastBits;
unsigned int idata timecnt = 0;
uchar idata irqEn = 0x00;
uchar idata waitFor = 0x00;
uchar idata timerCtl = 0x00;
WriteIO(RegInterruptEn,0x7F); //Clear Int
WriteIO(RegInterruptRq,0x7F);
WriteIO(RegCommand,PCD_IDLE); // (0x00) No action: cancel current command
FlushFIFO();
MpIsrInfo = info;
MpIsrOut = rcv;
info->irqSource = 0x00;
switch(cmd)
{
case PCD_IDLE:
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2:
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG:
case PCD_LOADKEYE2:
case PCD_AUTHENT1:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2:
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE:
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE:
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -