📄 typeb.c
字号:
#include <REGX52.H>
#include <main.h>
#include <function.h>
#include <typeb.h>
#include <string.h>
/***************************
*变量定义
***************************/
static idata unsigned char g_cFWI;
static idata unsigned char TYPE;
static volatile struct TranSciveBuffer{unsigned char MfCommand;
unsigned int MfLength;
unsigned char MfData[64];
};
/****************************
*MFRC500 复位程序
*返回1 ->复位不成功
*返回0 ->复位成功
************************/
uchar M500PcdReset(void)
{
uchar timecount;
CLR_RC500RST(); //起动复位引脚
Delay(25); //延时
SET_RC500RST(); //进行复位
Delay(20); //延时
CLR_RC500RST(); //复位完成
Delay(10); //延时待MFRC500进行数据进行复制
timecount=250; //置数超时计数器
while((ReadIO(RegCommand)&0x3f)&(timecount--)); //判断 MFRC500复位完毕没有与是否超时
if(!timecount)return 1; //如果超时了就返回1
if(ReadIO(RegCommand)!=0x00)return 1; //如果MFRC500复位完后的值不是0X00,表明出现异常,返回1
return 0; //复位成功则返回0
}
/****************************
*清除位
*
*
************************/
void ClearBitMask(uchar reg,uchar mask)
{
uchar temp;
temp=ReadIO(reg); //读取寄存器
WriteIO(reg,(temp&(~mask)));//清除相应的位
}
/****************************
*置位
*
*
************************/
void SetBitMask(uchar reg,uchar mask)
{
uchar temp;
temp=ReadIO(reg); //读取寄存器的值
WriteIO(reg,(temp|mask));//置位相应的位
}
//////////////////////////////////////////////////////////////////////
//REQUEST B
//////////////////////////////////////////////////////////////////////
char M531PiccRequestB(unsigned char req_code,
unsigned char AFI,
unsigned char N,
unsigned char *ATQB)
{
char status;
struct TranSciveBuffer MfComData;
struct TranSciveBuffer *pi;
pi=&MfComData;
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
// SetBitMask(RegTxControl,0x03); // Tx2RF-En, Tx1RF-En enable
PcdSetTmo(5);
MfComData.MfCommand = PCD_TRANSCEIVE;
MfComData.MfLength = 3;
MfComData.MfData[0] = ISO14443B_ANTICOLLISION; // APf code
MfComData.MfData[1] = AFI; //
MfComData.MfData[2] = ((req_code<<3)&0x08) | (N&0x07); // PARAM
status = PcdComTransceive(pi);
if (status!=MI_OK && status!=MI_NOTAGERR)
{ status = MI_COLLERR; }
if (MfComData.MfLength != 96)
{ status = MI_COM_ERR; }
if (status == MI_OK)
{
memcpy(ATQB, &MfComData.MfData[0], 16);
PcdSetTmo(ATQB[11]>>4); // set FWT
}
return status;
}
void PcdSetTmo(uchar tmoLength)
{
switch(tmoLength)
{
case 1: // short timeout (1,0 ms)
WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
WriteIO(RegTimerReload,0x6a); // TReloadVal = 'h6a =106(dec)
break;
case 2: // medium timeout (1,5 ms)
WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
WriteIO(RegTimerReload,0xa0); // TReloadVal = 'ha0 =160(dec)
break;
case 3: // long timeout (6 ms)
WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
WriteIO(RegTimerReload,0xa0); // TReloadVal = 'ha0 =160(dec)
break;
case 4: // long timeout (9.6 ms)
WriteIO(RegTimerClock,0x09); // TAutoRestart=0,TPrescale=4*128
WriteIO(RegTimerReload,0xff); // TReloadVal = 'ff =255(dec)
break;
default: // short timeout (1,0 ms)
WriteIO(RegTimerClock,0x07); // TAutoRestart=0,TPrescale=128
WriteIO(RegTimerReload,tmoLength);// TReloadVal = tmoLength
break;
}
WriteIO(RegTimerControl,0X06);
}
/******************************************************
*发送指令
***************************************************/
unsigned char PcdComTransceive(struct TranSciveBuffer *pi)
{
bit recebyte = 0;
char status;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned char lastBits;
unsigned char n;
unsigned int i;
switch (pi->MfCommand)
{
case PCD_IDLE:
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2:
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2:
irqEn = 0x07;
waitFor = 0x04;
recebyte=1;
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:
irqEn = 0x06;
waitFor = 0x04;
recebyte=1;
break;
case PCD_LOADKEY:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT:
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE:
irqEn = 0x3D;
waitFor = 0x04;
recebyte=1;
break;
default:
pi->MfCommand = MI_UNKNOWN_COMMAND;
break;
}
if (pi->MfCommand != MI_UNKNOWN_COMMAND)
{
WriteIO(RegPage,0x00);
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
WriteIO(RegCommand,PCD_IDLE);
SetBitMask(RegControl,0x01);
WriteIO(RegInterruptEn,irqEn|0x80);
for (i=0; i<pi->MfLength; i++)
{
WriteIO(RegFIFOData, pi->MfData[i]);
}
WriteIO(RegCommand, pi->MfCommand);
i = 0x3500;
do
{
n = ReadIO(RegInterruptRq);
i--;
}
while ((i!=0) && !(n&irqEn&0x20) && !(n&waitFor));
status = MI_COM_ERR;
if ((i!=0) && !(n&irqEn&0x20))
{
if (!(ReadIO(RegErrorFlag)&0x17))
{
status = MI_OK;
if (recebyte)
{
n = ReadIO(RegFIFOLength);
lastBits = ReadIO(RegSecondaryStatus) & 0x07;
if (lastBits)
{
pi->MfLength = (n-1)*8 + lastBits;
}
else
{
pi->MfLength = n*8;
}
if (n == 0)
{
n = 1;
}
for (i=0; i<n; i++)
{
pi->MfData[i] = ReadIO(RegFIFOData);
}
}
}
else if (ReadIO(RegErrorFlag)&0x01)
{
status = MI_COLLERR;
if (recebyte)
{
n = ReadIO(RegFIFOLength);
lastBits = ReadIO(RegSecondaryStatus) & 0x07;
if (lastBits)
{
pi->MfLength = (n-1)*8 + lastBits;
}
else
{
pi->MfLength = n*8;
}
if (n == 0)
{
n = 1;
}
for (i=0; i<n; i++)
{
pi->MfData[i+1] = ReadIO(RegFIFOData);
}
}
pi->MfData[0]=ReadIO(0x0B);
}
}
else if (n & irqEn & 0x20)
{ status = MI_NOTAGERR; }
else if (!(ReadIO(RegErrorFlag)&0x17))
{ status = MI_ACCESSTIMEOUT; }
else
{ status = MI_COM_ERR; }
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
SetBitMask(RegControl,0x04); // stop timer now
WriteIO(RegCommand,PCD_IDLE);
}
return status;
}
//////////////////////////////////////////////////////////////////////
//ATTRIB
//////////////////////////////////////////////////////////////////////
unsigned char PcdAnticoll(unsigned char *snr) //读取卡片序列号函数
{
unsigned char i;
unsigned char snr_check=0;
char status=MI_OK;
struct TranSciveBuffer *pi;
PcdSetTmo(14);
WriteIO(RegDecoderControl,0x28);
ClearBitMask(RegControl,0x08);
WriteIO(RegChannelRedundancy,0x03);
pi->MfCommand=PCD_TRANSCEIVE;
pi->MfLength=2;
pi->MfData[0]=PICC_ANTICOLL1;
pi->MfData[1]=0x20;
status=PcdComTransceive(pi);
// ser_send(&status,1);
if(!status)
{
for(i=0;i<4;i++)
{
snr_check^=pi->MfData[i];
}
if(snr_check!=pi->MfData[i])
{
status=MI_SERNRERR;
}
else
{
for(i=0;i<4;i++)
{
*(snr+i)=pi->MfData[i];
}
}
}
ClearBitMask(RegDecoderControl,0x20);
return status;
}
///////////////////////////////////////////////////////////////////////
// C O N F I G I S O 1 4 4 4 3 T Y P E
///////////////////////////////////////////////////////////////////////
unsigned char M500PcdConfigISOType(unsigned char type)
{
if(type==TYPEA)
{
WriteIO(RegTxControl,0x5b); // Force100ASK, TX1 & TX2 enable 0x11内部编码器 b的设置位不懂??
WriteIO(RegCoderControl,0x19); // Miller coding, 106kbps iso14443-A 0x14地址
WriteIO(RegRxControl1,0x73); //8puls iso14443A&B 42dB 0x19
WriteIO(RegDecoderControl,0x08); // Manchester Coding iso14443A 0x1a
WriteIO(RegCRCPresetLSB,0x63); // set CRC preset to 0x6363 0x23 复位值为0x63
WriteIO(RegCRCPresetMSB,0x63); //0x23 复位值为0x63
WriteIO(RegRxThreshold,0xff); // set max MinLevel & ColLevel. //0x1c复位值为0xff
TYPE = TYPEA;
}
else
{
WriteIO(RegTxControl,0x4b); // disable Force100ASk ok
WriteIO(RegCoderControl,0x20); // NRZ-L, TypeB baud 106kbps ok
WriteIO(RegRxControl1,0x73); // ok
WriteIO(RegDecoderControl,0x19); // BPSK coding ok
WriteIO(RegCRCPresetLSB,0xff); // set CRC preset to 0xffff ok
WriteIO(RegCRCPresetMSB,0xff); // ok
WriteIO(RegTypeBFraming,0x23); // EGT=0 0x17 定义了mode的宽度 ok
WriteIO(RegBitFraming,0x07); // ok
WriteIO(RegBPSKDemControl,0x3e); // ASK=0xfe,ignore EOF and SOF 0x1d地址看datasheet
WriteIO(RegModConductance,0x06); // set modulation index at 12% 0x13地址看datasheet
// WriteIO(RegChannelRedundancy, 0x2c);//RegChannelRedundancy
WriteIO(RegRxThreshold,0x44); // Reduce MinLevel & ColLevel. 0x1c地址
// WriteIO(RegRxThreshold,0x68);
// WriteIO(RegRxWait,0x09);
TYPE = TYPEB;
}
return MI_OK;
}
/*************************************
*MFRC632初始化
*************************************/
void M500PcdConfig(void)
{
ClearBitMask(RegControl,0x08); //清除RegControl标志位
WriteIO(RegClockQControl,0x0); //设置Q时钟值
WriteIO(RegClockQControl,0x40); //设置Q时钟值
Delay(20); //延时
ClearBitMask(RegClockQControl,0x40);//清除Q时钟标志位
WriteIO(RegTxControl,0x4b); //设置发送控制
WriteIO(RegCwConductance,0x17); //设置CwConductance宽度
WriteIO(RegModConductance,0x06); //设置ModConductance数值
WriteIO(RegCoderControl,0x20); //设置CoderControl代码控制寄存器
WriteIO(RegModWidth,0x13); //设置ModWidth发射波长
WriteIO(RegModWidthSOF,0x3F); //设置ModWidthSOF长度
WriteIO(RegTypeBFraming,0x3B); //设置TypeB帧
WriteIO(RegRxControl1,0x73); //设置RxControl1接受寄存器
WriteIO(RegDecoderControl,0x19); //设置DecoderControl解码控制寄存器
WriteIO(RegBitPhase,0xAD); //设置位标置控制寄存器BitPhase
WriteIO(RegRxThreshold,0x88); //设置RxThreshold接受标志位寄存器
WriteIO(RegBPSKDemControl,0x7E); //设置BPSKDemControl寄存器BPSK发射波长
WriteIO(RegRxControl2,0x01); //设置RxControl2接受寄存器的数值
WriteIO(RegRxWait,0x06); //设置RegRxWait若罔闻寄存器等待时间
WriteIO(RegChannelRedundancy,0x2C); //设置ChannelRedundancy等待时间
WriteIO(RegCRCPresetLSB,0xFF); //设置CRCPresetLSB寄存器低位
WriteIO(RegCRCPresetMSB,0xFF); //设置CRCPresetMSB寄存器高位
WriteIO(RegTimeSlotPeriod,0x00); //设置TimeSlotPeriod寄存器
WriteIO(RegMfOutSelect,0x00); //禁止MfOutSelect输出
WriteIO(RFU27,0x00); //设置RFU27寄存器输出0
WriteIO(RegFIFOLevel,0x3F); //设置RegFIFOLevel--FIFOLevel溢出值
WriteIO(RegTimerClock,0x07); //设置TimerClock时钟值
WriteIO(RegTimerReload,0x0A); //设置RegTimerReload时钟装入值
WriteIO(RegTimerControl,0x06); //设置RegTimerControl--定时器控制
WriteIO(RegIRqPinConfig,0x02); //设置RegIRqPinConfig--中断请求配置
WriteIO(RFU2E,0x00); //设置RFU2E--寄存器位应保持0x00
WriteIO(RFU2F,0x00); //设置RFU2F--寄存器位应保持0x00
PcdSetTmo(106); //设置发送控制时间
Delay(10); //延时二十毫秒
PcdAntennaOn();
}
/*******************************************************************************************************
** 函数名称:PcdAntennaOn()
** 函数功能:开启天线
** 函数说明:每次开启或关闭天线发射之间至少有1ms的间隔
** 返 回 值:无
*******************************************************************************************************/
unsigned char PcdAntennaOn(void)
{
unsigned char i;
i = ReadIO(RegTxControl);
if (!(i & 0x03))
{
SetBitMask(RegTxControl,0x03);
}
return 0;
}
/*******************************************************************************************************
** 函数名称:PcdAntennaOff()
** 函数功能:关闭天线
** 函数说明:每次开启或关闭天线发射之间至少有1ms的间隔
** 返 回 值:无
*******************************************************************************************************/
void PcdAntennaOff(void)
{
ClearBitMask(RegTxControl,0x03);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -