hnzjc 发表于 2011-9-11 17:05:54

发一个读ID卡号的C程序版本,程序量很小

/***********************************************************
*                莆田市吉美电子科技有限公司
*                (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, 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 = 0;
                                                k = 1;
                                                cDat = 1;
                                                j = 1;
                                                }
                                        }
                                break;
                        case 1:        // 上升沿测量低电平宽度
                                j = 0;
                                if(cPinBit)
                                        {
                                        k++; cDat <<= 1;
                                        if(i<150)        // 数据为1
                                                {
                                                cDat |= 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 <<= 1;
                                        if(i>150)        // 数据为1
                                                {
                                                cDat |= 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; k<12; k++)
                                {
                                cTemp ^= cDat;
                                }
                        cTemp &= 0x1e;
                        if(cDat==cTemp)                                                                                                                                         // 列校验
                                {
                                for(cTemp=2; cTemp<12; cTemp++)
                                        {
                                        cTemp1 = cDat;
                                        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 <<= 3;         
cDat &= 0xf0;
cDat >>= 1;
cData = cDat|cDat;
cDat <<= 3;
cDat &= 0xf0;
cDat >>= 1;
cData = cDat|cDat;
cDat <<= 3;         
cDat &= 0xf0;
cDat >>= 1;
cData = cDat|cDat;
cDat <<= 3;         
cDat &= 0xf0;
cDat >>= 1;
cData = cDat|cDat;
        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芯片
读卡带超时机制

-------------------------修改原因:删除一些在这里面没用到的函数和定义

szfrg 发表于 2011-11-21 09:34:59

谢谢

changhui0222 发表于 2011-11-21 09:38:59

mk

taojie 发表于 2011-11-21 13:55:13

看过

hnzjc 发表于 2012-5-5 23:47:02

似乎发错地方了,应该发到RFID板块去,自己好像也不能换额

jack_yu 发表于 2012-5-6 20:56:28

学习了。谢谢

yanglong5918 发表于 2012-5-6 22:17:34

一直没有搞懂EM读卡时序,楼主有没有资料啊

fx5700 发表于 2012-5-6 23:19:35

要看看再看看在看看看

dgdjfw 发表于 2012-5-8 11:40:04

学习了 学习了。谢谢

时代还怪 发表于 2012-5-8 13:49:17

正要学习SD卡读写,MARK

dory_m 发表于 2012-5-8 14:46:34

坚持学习!!!

skynet 发表于 2012-5-8 14:55:09

纯软件延时,可移植性差.

煮酒fu 发表于 2014-6-28 20:34:50

Wlkey.cRFIDReadTime = 20;这句话什么意思。 Wlkey是什么?

SNOOKER 发表于 2014-6-28 20:37:15

确实可移植性差,我是用ICP做的
页: [1]
查看完整版本: 发一个读ID卡号的C程序版本,程序量很小