AB1601之125K ID卡读写代码

来源:互联网 发布:在u盘上安装ubuntu 编辑:程序博客网 时间:2024/06/11 22:44
#include "DoorIdReader.h"




/*
#define ID_HALF_PERIOD_MAX 256//unit:us
#define ID_ONE_PERIOD_MAX     512
#define ID_WAIT_MAX         1000
#define ID_CARD_TIME       1000
*/


/*
#define ID_HALF_PERIOD_MAX (25+5)//unit:us
#define ID_ONE_PERIOD_MAX     (50+10)
#define ID_WAIT_MAX         (100+10)
#define ID_CARD_TIME       (100+10)
*/


///*
#define ID_HALF_PERIOD_MAX CLOCK_SYS_CLOCK_1US*(25+5)*10//unit:us
#define ID_ONE_PERIOD_MAX     CLOCK_SYS_CLOCK_1US*(50+10)*10
#define ID_WAIT_MAX         CLOCK_SYS_CLOCK_1US*(100+10)*10
#define ID_CARD_TIME       CLOCK_SYS_CLOCK_1US*(100+10)*10
//*/


/*
#define ID_HALF_PERIOD_MAX CLOCK_SYS_CLOCK_1US*(25+5)*15//unit:us
#define ID_ONE_PERIOD_MAX     CLOCK_SYS_CLOCK_1US*(50+10)*15
#define ID_WAIT_MAX         CLOCK_SYS_CLOCK_1US*(100+10)*15
#define ID_CARD_TIME       CLOCK_SYS_CLOCK_1US*(100+10)*15
*/


/*
#define ID_HALF_PERIOD_MAX CLOCK_SYS_CLOCK_1US*(25+5)*20//unit:us
#define ID_ONE_PERIOD_MAX     CLOCK_SYS_CLOCK_1US*(50+10)*20
#define ID_WAIT_MAX         CLOCK_SYS_CLOCK_1US*(100+10)*20
#define ID_CARD_TIME       CLOCK_SYS_CLOCK_1US*(100+10)*20
*/




/*
#define ID_HALF_PERIOD_MAX (256+10)//unit:us
#define ID_ONE_PERIOD_MAX     (512+20)
#define ID_WAIT_MAX         (1000+100)
#define ID_CARD_TIME       (1000+100)
*/




/*
#define ID_HALF_PERIOD_MAX (256+50)//unit:us
#define ID_ONE_PERIOD_MAX     (512+100)
#define ID_WAIT_MAX         (1000+100)
#define ID_CARD_TIME       (1000+100)
*/






#define ID_RFIN_PIN GPIO_GP23//ok










static U32 RfBeginTime = 0;
static U8 Rf125kCardReadFlag = 0;








void SetRf125kCardReadFlag(U8 flag)
{
Rf125kCardReadFlag = flag;
}








U8 GetRf125kCardReadFlag(void)
{
return Rf125kCardReadFlag;
}








void DoorRfIoInit(void)
{


}






static U8 DoorGetRfIoState(void)
{
U8 ioValue;
U32 ioOriginState;
ioOriginState = gpio_read(ID_RFIN_PIN);
if(ioOriginState == 0x00000000)
{
ioValue = 0;
}
else
{
ioValue = 1;
}
return ioValue;
}










static U32 GetCounterCurrentValue(void)
{
U32 currentValue;
currentValue = clock_time();
return currentValue;
}








static U32 GetRfWaitedTime(void)
{
U32 currentValue;
currentValue = GetCounterCurrentValue();
if(currentValue >= RfBeginTime)
{
return  currentValue - RfBeginTime;
}
else
{
return (0xffffffff-RfBeginTime) + currentValue;
}
}




static U8 TestFlag1 = 0;
static U8 TestFlag2 = 0;


U8 DoorIdReadEm4001(U8 *serialNumber)
{
U8 i,j;
U8 retryCnt = 0;
U8 rfIoState;
U8 rfIoStateTmp;
U32 rfWaitedTime;
U8 dataB0;
U8 dataB1;
U8 dataB2;
U8 dataB3;
U8 dataB4;
U8 dataB5;
U8 dataB6;
U8 dataB7;
U8 lrcB0;
U8 lrcB1;
U8 lrcB2;
U8 lrcB3;
U8 checkSum;
U8 codedValueBit;
U8 tmpData;
rfIoState = DoorGetRfIoState();//记录口线历史状态
begin:
RfBeginTime = GetCounterCurrentValue();//设置时间基准
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == 1)
{


}
else
{
break;//等待低电平出现
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
TestFlag1 = 0xAA;
return 0;
}
TestFlag1 = 1;
}


rfIoState = DoorGetRfIoState();//记录口线历史状态(此时一定为低电平)
RfBeginTime = GetCounterCurrentValue();//设置时间基准
for(i=0; i<16; i++)//8个1,16个跳变,ID卡的头共9个1
{
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == rfIoState)
{


}
else
{
break;//发现跳变
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
TestFlag2 = 0xAA;
return 0;
}
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_HALF_PERIOD_MAX)//没有发现空跳变,则认为不是连续的9个1
{
retryCnt++;//找同步包头失败次数计数
if(retryCnt >= 64)
{
TestFlag2 = 0xAB;
return 0;
}
else
{
TestFlag2 = 0xAC;
goto begin;
}
}
rfIoState = DoorGetRfIoState();//记录口线历史状态
RfBeginTime = GetCounterCurrentValue();//设置时间基准
}


if(i == 16)
{


}
else
{
TestFlag2 = 0xAD;
return 0;
}



TestFlag2 = 0x01;




lrcB0 = 0;//第一列纵向校验和
lrcB1 = 0;
lrcB2 = 0;
lrcB3 = 0;
codedValueBit = 1;//预设下一个解码出来的数据位为1(前一个位的状态)
for(i=0; i<5; i++)//0 1 2 3 4(每行前4位是数据,最后1位为校验和)
{
tmpData = 0x00;
for(j=0; j<10; j++)//共10行
{
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == rfIoState)
{


}
else
{
break;//发现跳变
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
//printf("return 777777......\n");
return 0;
}
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_HALF_PERIOD_MAX)//没有空跳变,则跟预设值相反
{
codedValueBit = (~codedValueBit) & 0x01;
}
else//有空跳变,则跟预设值相同
{
rfIoState = DoorGetRfIoState();//记录口线历史状态
RfBeginTime = GetCounterCurrentValue();//设置时间基准
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == rfIoState)
{


}
else
{
break;//发现跳变
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
//printf("return 888888......\n");
return 0;
}
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_HALF_PERIOD_MAX)//超时处理
{
//printf("return 999999:%d %d......\n", i*5+j, rfWaitedTime);
//printf("%02x\n", tmpData);
return 0;
}
}
if(j==4 || j==9)//校验和处理
{
dataB0 = (tmpData >> 0) & 0x01;
dataB1 = (tmpData >> 1) & 0x01;
dataB2 = (tmpData >> 2) & 0x01;
dataB3 = (tmpData >> 3) & 0x01;
dataB4 = (tmpData >> 4) & 0x01;
dataB5 = (tmpData >> 5) & 0x01;
dataB6 = (tmpData >> 6) & 0x01;
dataB7 = (tmpData >> 7) & 0x01;
checkSum = (dataB0^dataB1^dataB2^dataB3) & 0x01;
if(checkSum == codedValueBit)
{


}
else//校验和出错
{
//printf("return aaaaaa......\n");
return 0;
}
}
else//数据位处理
{
tmpData = tmpData << 1;
tmpData = tmpData | codedValueBit;
}
rfIoState = DoorGetRfIoState();//记录口线历史状态
RfBeginTime = GetCounterCurrentValue();//设置时间基准
}//for(j....)
lrcB0 = (lrcB0 ^ dataB0 ^ dataB4) & 0x01;//计算纵向校验和
lrcB1 = (lrcB1 ^ dataB1 ^ dataB5) & 0x01;
lrcB2 = (lrcB2 ^ dataB2 ^ dataB6) & 0x01;
lrcB3 = (lrcB3 ^ dataB3 ^ dataB7) & 0x01;
serialNumber[i] = tmpData;
}//for(i....)






if(i == 5)
{


}
else
{
//printf("return xxxxxx......\n");
return 0;
}
tmpData = 0;
for(i=0; i<5; i++)//4个纵向校验和与结束位(0)
{
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == rfIoState)
{


}
else
{
break;//发现跳变
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
//printf("return xxxxxx111......\n");
return 0;
}
}


rfWaitedTime = GetRfWaitedTime();//计算等待了的时间
if(rfWaitedTime > ID_HALF_PERIOD_MAX)//没有空跳变,则跟预设值相反
{
codedValueBit = (~codedValueBit) & 0x01;
}
else//有空跳变,则跟预设值相同
{
rfIoState = DoorGetRfIoState();//记录口线历史状态
RfBeginTime = GetCounterCurrentValue();//设置时间基准
while(1)
{
rfIoStateTmp = DoorGetRfIoState();//获取口线实时状态
if(rfIoStateTmp == rfIoState)
{


}
else
{
break;//发现跳变
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_ONE_PERIOD_MAX)//超时处理
{
//printf("return xxxxxx222......\n");
return 0;
}
}
rfWaitedTime = GetRfWaitedTime();//获取等待了的时间
if(rfWaitedTime > ID_HALF_PERIOD_MAX)//超时处理
{
//printf("return xxxxxx333......\n");
return 0;
}
}
if(i == 4)//结束位检查是否为0
{
if(codedValueBit == 0)
{


}
else
{
//printf("return xxxxxx444......\n");
return 0;
}
dataB0 = (tmpData >> 0) & 0x01;
dataB1 = (tmpData >> 1) & 0x01;
dataB2 = (tmpData >> 2) & 0x01;
dataB3 = (tmpData >> 3) & 0x01;
dataB4 = (tmpData >> 4) & 0x01;
dataB5 = (tmpData >> 5) & 0x01;
dataB6 = (tmpData >> 6) & 0x01;
dataB7 = (tmpData >> 7) & 0x01;
}
else//校验位
{
tmpData = tmpData << 1;
tmpData = tmpData | codedValueBit;
}
rfIoState = DoorGetRfIoState();//记录口线历史状态
RfBeginTime = GetCounterCurrentValue();//设置时间基准
}//for(i.....)
if( (lrcB0 == dataB0)&&
(lrcB1 == dataB1) &&
(lrcB2 == dataB2)&&
(lrcB3 == dataB3))
{


}
else//纵向校验出错
{
//printf("return xxxxxx555......\n");
return 0;
}
//printf("return yyyyyy......\n");


if( (serialNumber[0] == 0x00)&&
(serialNumber[1] == 0x00)&&
(serialNumber[2] == 0x00) &&
(serialNumber[3] == 0x00)&&
(serialNumber[4] == 0x00))
{
//printf("return zzzzzz......\n");
return 0;//失败
}
else
{
/*
U32 cardNumber;
printf("125k card serial number:%02x %02x %02x %02x %02x \n", serialNumber[0], serialNumber[1], serialNumber[2], serialNumber[3], serialNumber[4]);
cardNumber = serialNumber[1];
cardNumber = (cardNumber << 8) | serialNumber[2];
cardNumber = (cardNumber << 8) | serialNumber[3];
cardNumber = (cardNumber << 8) | serialNumber[4];
printf("125k card number:%lu\n\n", cardNumber);
*/
return 1;//成功读出卡号
}
}






U8 DoorIdIntervalTime = 0x00;


U8 serialNumber[8];
static U8 DoorRdIdErrCnt = 100;
void DoorIdReadEm4001Test(void)
{
U8 ret;
//U8 serialNumber[8];
if(DoorIdIntervalTime == 0x00)
{


}
else
{
return;
}
ret = DoorIdReadEm4001(serialNumber);
if(ret == 1)
{
//if(DoorRdIdErrCnt >= 1)
{
LightOnlyTipsMode2();
}
DoorRdIdErrCnt = 0x00;
DoorIdIntervalTime = 100;//1s
}
else
{
//printf("err11...\n");
if(DoorRdIdErrCnt < 0xff)
{
DoorRdIdErrCnt++;
}
DoorIdIntervalTime = 1;//10ms
return;
}
}












static U8 OldIdSerialNumber[8] = {0x00, 0x00, 0x00, 0x00, 0x00,};
static U8 DoorIdSerialNumberCmp(U8 *currentIdSerialNumber)
{
U8 i;
for(i=0; i<5; i++)
{
if(OldIdSerialNumber[i] == currentIdSerialNumber[i])
{
continue;
}
return 0;
}
return 1;
}








static void DoorIdSerialNumberSave(U8 *currentIdSerialNumber)
{
U8 i;
for(i=0; i<5; i++)
{
OldIdSerialNumber[i] = currentIdSerialNumber[i];
}
}








U8 GetOk_F(void)
{
return 0;
}






void CarNoMsg(u8 *CarNo)
{


}












void DoorIdReadEm4001Deal(void)
{
U8 ret;
U8 cmpFlag;
U8 serialNumber[8];
    U8 UID[4];
    if(GetOk_F())
return;
ret = DoorIdReadEm4001(serialNumber);




/*
DOOR_PRINT("DoorIdReadEm4001:%d\n", ret);


//only for test
{
if(ret == 1)
{
U32 cardNumber;
DOOR_PRINT("125k card serial number:%02x %02x %02x %02x %02x \n", serialNumber[0], serialNumber[1], serialNumber[2], serialNumber[3], serialNumber[4]);
cardNumber = serialNumber[1];
cardNumber = (cardNumber << 8) | serialNumber[2];
cardNumber = (cardNumber << 8) | serialNumber[3];
cardNumber = (cardNumber << 8) | serialNumber[4];
DOOR_PRINT("125k card number:%lu\n\n", cardNumber);
}
}
return;
*/








if(ret == 1)
{
   DoorRdIdErrCnt = 0x00; 
cmpFlag = DoorIdSerialNumberCmp(serialNumber);
if(cmpFlag == 1)//THE SAME AS LAST TIME
{
/*if(DoorRdIdErrCnt >= 3)
{
goto READ_ID_OK;
}
else
{
return;
}*/
return;  
}
else
{
//DoorRdIdErrCnt = 0x00;
DoorIdSerialNumberSave(serialNumber);
}


//READ_ID_OK:
//DoorRdIdErrCnt = 0x00;
//LightOnlyTipsMode2();
//VoiceOnlyTipsMode2();


/*
memrecpy(UID,serialNumber,4);
DoorRs485SetNewSerialNumber(serialNumber+1);//第一个字节不是卡号
//only for test
{
U32 cardNumber;
DOOR_PRINT("125k card serial number:%02x %02x %02x %02x %02x \n", serialNumber[0], serialNumber[1], serialNumber[2], serialNumber[3], serialNumber[4]);
cardNumber = serialNumber[1];
cardNumber = (cardNumber << 8) | serialNumber[2];
cardNumber = (cardNumber << 8) | serialNumber[3];
cardNumber = (cardNumber << 8) | serialNumber[4];
DOOR_PRINT("125k card number:%lu\n\n", cardNumber);
}
*/

        CarNoMsg(UID);
}
else
{
//printf("err11...\n");
DoorRdIdErrCnt++;
if(DoorRdIdErrCnt >50)
{
   DoorRdIdErrCnt=0;
   memset(serialNumber,0,5);
   DoorIdSerialNumberSave(serialNumber);
}
return;
}
}



原创粉丝点击