搜索
bottom↓
回复: 13

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

[复制链接]

出0入0汤圆

发表于 2011-9-11 17:05:54 | 显示全部楼层 |阅读模式
/***********************************************************
*                莆田市吉美电子科技有限公司
*                (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, 杜汶泽)

出0入0汤圆

发表于 2011-11-21 09:34:59 | 显示全部楼层
谢谢

出0入0汤圆

发表于 2011-11-21 09:38:59 | 显示全部楼层
mk

出0入0汤圆

发表于 2011-11-21 13:55:13 | 显示全部楼层
看过

出0入0汤圆

 楼主| 发表于 2012-5-5 23:47:02 | 显示全部楼层
似乎发错地方了,应该发到RFID板块去,自己好像也不能换额

出0入0汤圆

发表于 2012-5-6 20:56:28 | 显示全部楼层
学习了。谢谢

出0入0汤圆

发表于 2012-5-6 22:17:34 | 显示全部楼层
一直没有搞懂EM读卡时序,楼主有没有资料啊

出0入0汤圆

发表于 2012-5-6 23:19:35 来自手机 | 显示全部楼层
要看看再看看在看看看

出0入0汤圆

发表于 2012-5-8 11:40:04 | 显示全部楼层
学习了 学习了。谢谢

出0入0汤圆

发表于 2012-5-8 13:49:17 | 显示全部楼层
正要学习SD卡读写,MARK

出0入0汤圆

发表于 2012-5-8 14:46:34 | 显示全部楼层
坚持学习!!!

出0入12汤圆

发表于 2012-5-8 14:55:09 | 显示全部楼层
纯软件延时,可移植性差.

出0入0汤圆

发表于 2014-6-28 20:34:50 | 显示全部楼层
Wlkey.cRFIDReadTime = 20;  这句话什么意思。 Wlkey是什么?

出0入0汤圆

发表于 2014-6-28 20:37:15 | 显示全部楼层
确实可移植性差,我是用ICP做的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 21:30

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表