|
/***********************************************************
* 莆田市吉美电子科技有限公司
* (c)Copyright 2010--2020
* All Rights Reserved
* 版本号: v1.00
*-----------------------------------------------------------
*文件名: rfid.c
*编 写: hnzjc7
*日 期: 2010年9月1日
*描 述: ID卡读卡驱动程序
***********************************************************/
#ifdef _rfid_c_
#define _rfid_c_ 1
#endif
#include "include.h"
/*
****************************************************************************************
*RFID数据输入端口
****************************************************************************************
*/
#define Rfid() (PC_IDR&0x80) // PC7口
/*
****************************************************************************************
*函数原形:uint8 ReadRfid(uint32 *iCard_id)
*入口参数:uint32 *iCard_id 接收到的卡号
*出口参数:YES接收成功 NO接收失败
*功能描述:接收ID卡号
****************************************************************************************
*/
uint8 ReadRfid(uint8 *cData)
{
uint8 j=0, k, cDat[14], cPinBit, cTemp, cTemp1, cTemp2, cTemp3;
uint16 i;
Wlkey.cRFIDReadTime = 20; // 系统分配给读卡的时间
cPinBit = Rfid();
do{
if(!Wlkey.cRFIDReadTime) return NO; // 读卡超时退出
i = 0; // 超时机制
do{
if(Rfid()!=cPinBit) break; // 有跳变
i++;
}while(i<300);
cPinBit = Rfid();
if((i<300)&&(i>70)) // 正常跳变
{
switch(j)
{
case 0: // 检测上一个卡的停止位到当前卡的第1个位的位置
if(!cPinBit) // 下降沿
{
if(i>180) // 长度够长
{
for(k=0; k<14; k++) cDat[k] = 0;
k = 1;
cDat[0] = 1;
j = 1;
}
}
break;
case 1: // 上升沿测量低电平宽度
j = 0;
if(cPinBit)
{
k++; cDat[k/5] <<= 1;
if(i<150) // 数据为1
{
cDat[k/5] |= 0x01;
j = 2;
}
else// 数据为0
{
if(k<10) j = 0;
else j = 6;
}
}
break;
case 2: // 等待一个下降沿
if(!cPinBit) j = 1;
else j = 0;
break;
case 6: // 下降沿测量高电平宽度
j = 0;
if(!cPinBit)
{
k++; cDat[k/5] <<= 1;
if(i>150) // 数据为1
{
cDat[k/5] |= 0x01;
j = 1;
}
else // 数据为0
{
j = 7;
}
}
break;
case 7: // 等待一个上升沿
if(cPinBit) j = 6;
else j = 0;
break;
default: j = 0;
}
if(k>64)
{
for(k=3, cTemp=cDat[2]; k<12; k++)
{
cTemp ^= cDat[k];
}
cTemp &= 0x1e;
if(cDat[12]==cTemp) // 列校验
{
for(cTemp=2; cTemp<12; cTemp++)
{
cTemp1 = cDat[cTemp];
cTemp3 = 0;
for(cTemp2=0; cTemp2<5; cTemp2++)
{
if(cTemp1&0x01) cTemp3++;
cTemp1 >>= 1;
}
if(cTemp3&0x01) return NO; // 行校验失败
}
break; // 读卡成功 跳出
}
}
}
else { j = 0; }
}while(1);
// ------------ 整理成4个字节的卡号 -------------
cDat[4] <<= 3;
cDat[4] &= 0xf0;
cDat[5] >>= 1;
cData[1] = cDat[4]|cDat[5];
cDat[6] <<= 3;
cDat[6] &= 0xf0;
cDat[7] >>= 1;
cData[2] = cDat[6]|cDat[7];
cDat[8] <<= 3;
cDat[8] &= 0xf0;
cDat[9] >>= 1;
cData[3] = cDat[8]|cDat[9];
cDat[10] <<= 3;
cDat[10] &= 0xf0;
cDat[11] >>= 1;
cData[4] = cDat[10]|cDat[11];
return(YES);
}
/*---------------------------------------------|
*| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 九个头 |
*----------------------------------------------|
*| 八个版本 | 1 | 0 | 0 | 0 | 1 | |
*| 厂商信息 | 0 | 1 | 0 | 0 | 1 | |
*------------------------------------- | 曼
*| 32数据位 1 | 1 | 1 | 0 | 0 | 0 | 10个行 | 彻
*| 2 | 0 | 0 | 1 | 0 | 1 | 校验位 | 斯
*| 3 | 1 | 0 | 1 | 0 | 0 | | 特
*| 4 | 0 | 1 | 1 | 0 | 0 | | 码
*| 5 | 1 | 1 | 1 | 0 | 1 | | 的
*| 6 | 0 | 0 | 0 | 1 | 1 | | 数
*| 7 | 1 | 0 | 0 | 1 | 0 | | 据
*| 8 | 0 | 1 | 0 | 1 | 0 | | 格
*|---------------------------------------------| 式
*| 四个列校验位 | 1 | 1 | 0 | 1 | 0 | 停止位 |
*|--------------------------------------------*/
/*
************************************************************
* end of file
************************************************************
*/
该程序为一款产品上用到的一段代码,经过很多次优化的结果。可以识别市面上全部ID卡(之前版本会出现劣质ID卡读取多次只有一次正确的情况)。
已经做了行列校验,C程序读ID卡这个程序的速度还不错
我使用的是STM芯片
读卡带超时机制
-------------------------修改原因:删除一些在这里面没用到的函数和定义 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|