找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 27697|回复: 34
打印 上一主题 下一主题
收起左侧

由STC12C5A60S2+RC522构成的IC卡读卡器

  [复制链接]
跳转到指定楼层
楼主
本帖最后由 lbq691477940 于 2014-11-18 23:56 编辑

由STC12C5A60S2+RC522构成的IC卡读卡器

读出的卡号从串口返回

RC522 非接触式IC卡读卡模块 采用I2C接口通信方式占用CPU I/O口最少,非SPI通信接口方式。
外观尺下:62X34mm

插针间距: 7Pin x 2.54mm

本模块非SPI通信接口方式,采用I2C接口通信方式占用CPU I/O口最少;从机器件地址为:0x00H


有需要IC卡读卡模块的点这:RC522 非接触式IC卡读卡模块
http://item.taobao.com/item.htm?spm=686.1000925.0.0.zmdRBz&id=42037523587
有此模块的可以提供完整的读写卡源码

/***********************************************************************************************************/
#include <STC12C5A60S2.h>
#define uchar unsigned char
#define uint unsigned int
/***********************************************************************************************************/
//端口定义
//MFRC522
sbit SDA = P1^4;
sbit SCL = P1^5;
// sbit SDA = P0^4;//IO2
// sbit SCL = P0^5;//IO1
sbit BEEP = P2^3;         //BZ
sbit LED_GREEN = P1^7;
/***********************************************************************************************************/
void InitializeSystem(); //系统初始化                                 
#define BAUD_115200        256 - (OSC_FREQ / 192L) / 115200L   // 255
#define BAUD_57600         256 - (OSC_FREQ / 192L) / 57600L    // 254
#define BAUD_38400         256 - (OSC_FREQ / 192L) / 38400L    // 253
#define BAUD_28800         256 - (OSC_FREQ / 192L) / 28800L    // 252
#define BAUD_19200        256 - (OSC_FREQ / 192L) / 19200L    // 250
#define BAUD_14400         256 - (OSC_FREQ / 192L) / 14400L    // 248
#define BAUD_9600         256 - (OSC_FREQ / 192L) / 9600L     // 244                                   
#define OSC_FREQ          22118400L
#define RCAP2_50us      65536L - OSC_FREQ / 40417L
#define RCAP2_1ms       65536L - OSC_FREQ / 2000L
#define RCAP2_10ms      65536L - OSC_FREQ / 1200L
#define TIME0_500us     65536L - OSC_FREQ / 8000L
#define TIME0_10ms      65536L - OSC_FREQ / 200
#define CALL_isr_UART()    TI = 1
#define TRUE 1
#define FALSE 0
/***********************************************************************************************************/

/***********************************************************************************************************
                                由STC12C5A60S2+RC522构成的IC卡读卡器
CPU = STC12C5A60S2
OSC = 22.1184Mhz
功能简介:
具有串口波特率可更改和同一张卡防重读功能,即如果同一张卡如果一直放在感应区域中只读一次,只有离开感应区域
再次进入时才重新读取每成功读一次会返回扇区0的块0~3的内容即共64个字节,和蜂鸣器响一声,LED闪一次。

串口通信协议:串口波特率(默认为115200)
发送 0x02 0x0B + 0xXX 为打开蜂鸣器,后跟的参数0xXX为响的时长(可选值为1~255).并返回OK
发送 0x02 0x0D + 0xXX为更改波特率,后跟的参数(可选值为0~6)如下介绍.并返回OK
分别为:
        0x00 = 9600
        0x01 = 14400
        0x02 = 19200
        0x03 = 28800
        0x04 = 38400
        0x05 = 57600
        0x06 = 115200

程序编辑:红尘有你                                                                                2014-11-18
/***********************************************************************************************************/
#include "STC12C5A60S2.H"
#include "main.H"
#include "mfrc522.H"   
#include <string.H>
uchar code DefaultKey[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};  
uchar idata MLastSelectedSnr[4];    //存放4个字节的卡片序列号
uchar idata RevBuffer[70];  
uchar data SerBuffer[4];
bit CmdValid;     //串口接收完成标志位               
/***********************************************************************************************************/
void InitializeSystem()        //系统初始化
{
    //P0 = P1 = P3 = 0xFF;
    //P0M0 = 0x08;
    BEEP = 1;
    PCON = 0x80;               
    SCON = 0x70;                 
    TMOD = 0x21;        //TMOD = 0x22;
    //TH1 = BAUD_9600;
    TH1 = BAUD_115200;
    TL1 = TH1;
    TR1 = EA = ES = LED_GREEN = 1;                //
    PcdReset();                    //复位RC522
    PcdAntennaOff();            //关闭天线
    PcdAntennaOn();              //开启天线
    M500PcdConfigISOType('A');    //设置RC522的工作方式
    BEEP = 1;
    LED_GREEN = 0;
    delay_10ms(5);   
    BEEP = 0;
    LED_GREEN = 1;
    delay_10ms(5);
    BEEP = 1;
    LED_GREEN = 0;
    CmdValid = 0;                 //串口接收完成标志位清0
}
/***********************************************************************************************************/
void isr_UART(void) interrupt 4 using 1    //接收和发送中断
{
    uchar len,i;
    uint  j = 0;     
    if(RI == 1)                                //接收中断
    {        
        len = SBUF;
        RI = 0;   
        for(i = 0;i < len;i++)
        {
            while(!RI)
            {
                j++;
                if(j > 2000)            //j的大小取值与晶体振荡器有关
                {
                    break;
                }
            }
            if(j < 2000)                //j的大小取值与晶体振荡器有关
            {
                RevBuffer = SBUF;
                RI = j = 0;
            }
            else
            {
                break;
            }
        }
        if(i == len)
        {
            REN = 0;                    //禁止串口接收
            CmdValid = 1;                //串口接收完成标志位置1
        }
    }
    else if(!RI && TI)                    //发送中断
    {
        TI = 0;
        len = RevBuffer[0];
        for(i = 1;i < len + 1;i++)
        {
            SBUF = RevBuffer;
            while(!TI);
            TI = 0;            
        }
        REN = 1;                        //允许串口接收
    }
}
/***********************************************************************************************************/
void main()
{   
    uchar baud,UltraLight;
    InitializeSystem();        //系统初始化
    // SBUF = ReadRawRC(VersionReg);    //读取RC522芯片版本号,返回到串口输出
    // while(!TI);                    //读取RC522芯片版本号,返回到串口输出
    // TI = 0;                        //读取RC522芯片版本号,返回到串口输出
    while(1)
    {
/**********************************************************************************************************/
        baud = PcdRequest(PICC_REQALL,&RevBuffer[1]);        //寻卡/成功返回MI_OK
        if(baud != MI_OK)//不为0表明无卡在感应区域内
        {
            baud = PcdRequest(PICC_REQALL,&RevBuffer[1]);    //寻卡/成功返回MI_OK
            if(baud != MI_OK)//表明无卡在感应区域内则将以下内存填上FF使其能进行下一次读卡               
            {
                SerBuffer[0] = SerBuffer[1] = 0xff;
                SerBuffer[2] = SerBuffer[3] = 0xff;
                UltraLight = 0;
            }
        }
/**********************************************************************************************************   
        if(baud == MI_OK)//寻到卡后返回卡类型
        {
            ES = 0;
            SBUF = RevBuffer[1];
            while(!TI);
            TI = 0;
            SBUF = RevBuffer[2];
            while(!TI);
            TI = 0;   
            ES = 1;
        }
/**********************************************************************************************************/        
         if((RevBuffer[1] == 0x44) && (RevBuffer[2] == 0x00)) //判断是否为超薄卡识别码为0x4400(例:深圳地铁卡)
        {
            UltraLight = 1;                            //超薄卡识别标志位置1
        }
        baud = PcdAnticoll(&RevBuffer[1]);            //防冲撞/成功返回MI_OK以及将卡号存在RevBuffer数组内
/*********************************************************************************************************
        if(baud == MI_OK)//防冲撞/成功返回
        {
            ES = 0;
            SBUF = 0x11;
            while(!TI);
            TI = 0;
            SBUF = 0x22;
            while(!TI);
            TI = 0;   
            ES = 1;
        }
/**********************************************************************************************************/        
        memcpy(MLastSelectedSnr,&RevBuffer[1],4);    //将RevBuffer[1]开始4个地址中的卡号复制到MLastSelectedSnr中
        baud = PcdSelect(MLastSelectedSnr);            //选定卡片/成功返回MI_OK
/**********************************************************************************************************        
        if(baud == MI_OK)//选定卡片/成功返回
        {
            ES = 0;
            SBUF = 0x33;
            while(!TI);
            TI = 0;
            SBUF = 0x44;
            while(!TI);
            TI = 0;   
            ES = 1;
        }
/**********************************************************************************************************/            
        if(UltraLight)    //如果是超薄卡不要密码验证就能读取扇区内数据
        {
            baud = PcdRead(0,&RevBuffer[1]);                            //读扇区0的页0~3
            baud = PcdRead(4,&RevBuffer[17]);                            //读扇区0的页4~7
            baud = PcdRead(8,&RevBuffer[33]);                            //读扇区0的页8~11
            baud = PcdRead(12,&RevBuffer[49]);                            //读扇区0的页12~15            
        }
        else    //如果不是超薄卡要密码验证后才能读取扇区内数据
        {
            baud = PcdAuthState(PICC_AUTHENT1A,0,DefaultKey,MLastSelectedSnr);    //0x60为校验卡A组密码、0x61则校验卡B组密码
/**********************************************************************************************************        
        if(baud == MI_OK)//校验卡A组密码成功后返回
        {
            ES = 0;
            SBUF = 0x55;
            while(!TI);
            TI = 0;
            SBUF = 0x66;
            while(!TI);
            TI = 0;   
            ES = 1;
        }
/**********************************************************************************************************/               
            baud = PcdRead(0,&RevBuffer[1]);                            //读扇区0的块0
/**********************************************************************************************************        
        if(baud == MI_OK)//读扇区0的块0成功后返回
        {
            ES = 0;
            SBUF = 0x77;
            while(!TI);
            TI = 0;
            SBUF = 0x88;
            while(!TI);
            TI = 0;   
            ES = 1;
        }
/**********************************************************************************************************/            
            baud = PcdRead(1,&RevBuffer[17]);                            //读扇区0的块1
            baud = PcdRead(2,&RevBuffer[33]);                            //读扇区0的块2
            baud = PcdRead(3,&RevBuffer[49]);                            //读扇区0的块3
        }   
        if((memcmp(MLastSelectedSnr,SerBuffer,4) != 0) && (baud == 0))//相同为0
        {
            memcpy(SerBuffer,MLastSelectedSnr,4);//将MLastSelectedSnr中的4个值复制到SerBuffer中
            RevBuffer[0] = 64;        //共发送64个字节
            CALL_isr_UART();        //将发送结束中断位置1
            BEEP = 0;
            LED_GREEN = 1;
            delay_10ms(3);
            BEEP = 1;
            LED_GREEN = 0;
            baud = PcdHalt();        //命令卡片进入休眠状态/成功返回MI_OK
        }
/**********************************************************************************************************/               
        if(CmdValid)            //串口接收完成标志位=1
        {
            CmdValid = 0;    //串口接收完成标志位清0
            if(RevBuffer[0] == 0x0B)    //测试读卡器
            {
                baud = RevBuffer[1];    //先将上位机发来的蜂鸣时间暂存
                 RevBuffer[0] = 4;        //共发送4个字节            
                RevBuffer[1] = 'O';
                RevBuffer[2] = 'K';
                RevBuffer[3] = 0x0D;    //回车转行
                RevBuffer[4] = 0x0A;    //回车转行
                CALL_isr_UART();        //将串口通信的TI标志位置1        
                LED_GREEN = 1;
                BEEP = 0;
                delay_10ms(baud);
                LED_GREEN = 0;
                BEEP = 1;

            }
            else if(RevBuffer[0] == 0x0D)           //设置通讯波特率
            {
                switch(RevBuffer[1])
                {
                    case 0:
                        baud = BAUD_9600;
                        break;
                    case 1:
                        baud = BAUD_14400;
                        break;
                    case 2:
                        baud = BAUD_19200;
                        break;
                    case 3:
                        baud = BAUD_28800;
                        break;
                    case 4:
                        baud = BAUD_38400;
                        break;
                    case 5:
                        baud = BAUD_57600;
                        break;
                    case 6:
                        baud = BAUD_115200;
                        break;
                    default:
                        baud = BAUD_9600;
                        break;
                }               
                RevBuffer[0] = 4;        //共发送4个字节            
                RevBuffer[1] = 'O';
                RevBuffer[2] = 'K';
                RevBuffer[3] = 0x0D;    //回车转行
                RevBuffer[4] = 0x0A;    //回车转行
                CALL_isr_UART();
                BEEP = 0;
                delay_10ms(3);   
                BEEP = 1;
                TR1 = 0;
                TH1 = baud;
                TL1 = TH1;
                delay_10ms(2);
                TR1 = TRUE;
            }
            else                //如果不是以上二种情况则执行如下语句
            {               
                RevBuffer[0] = 5;        //共发送5个字节            
                RevBuffer[1] = 'E';
                RevBuffer[2] = 'R';
                RevBuffer[3] = 'R';
                RevBuffer[4] = 0x0D;    //回车转行
                RevBuffer[5] = 0x0A;    //回车转行
                CALL_isr_UART();
                BEEP = 0;
                delay_10ms(3);   
                BEEP = 1;
                delay_10ms(2);   
                BEEP = 0;
                delay_10ms(2);   
                BEEP = 1;
                delay_10ms(2);   
                BEEP = 0;
                delay_10ms(2);   
                BEEP = 1;
            }
        }
/**********************************************************************************************************/        
    }
}
/***********************************************************************************************************/
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏11 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:1 发表于 2014-11-18 21:17 | 只看该作者
[i] 替换成 [ i] 可防治出现斜体.
回复

使用道具 举报

板凳
ID:51088 发表于 2014-11-19 12:40 来自手机 | 只看该作者
楼主太给力了,果断收藏,
回复

使用道具 举报

地板
ID:69398 发表于 2014-11-25 11:32 | 只看该作者
金创图科技   专业做烧录各种芯片的自动化烧录方案.    机器烧录的好处: 1. 机器比人工快,时间好把握; 2,从长远说,机器烧录比人工烧录便宜;  3.芯片和程序外发烧录,程序有可能会被泄露, 自己购买了机器烧录就不用担心程序泄露的危险. 4,降低产器成本.    邹先生      18664339205          QQ:495684850
回复

使用道具 举报

5#
ID:47760 发表于 2014-11-28 03:35 | 只看该作者
谢谢你的分享不错哦
回复

使用道具 举报

6#
ID:61200 发表于 2014-11-28 08:54 | 只看该作者
收藏                                
回复

使用道具 举报

7#
ID:67821 发表于 2015-1-15 20:41 | 只看该作者
能否可以把完整代码发一份给我
回复

使用道具 举报

8#
ID:48994 发表于 2015-4-25 21:18 | 只看该作者
楼主能否可以把完整代码发一份给我。谢谢了!邮箱:294763701@qq.com
回复

使用道具 举报

9#
ID:78367 发表于 2015-4-28 20:54 | 只看该作者
楼主,求程序772691978@qq.com
回复

使用道具 举报

10#
ID:78376 发表于 2015-4-28 22:12 | 只看该作者
很好好强大
回复

使用道具 举报

11#
ID:80185 发表于 2015-5-16 20:11 | 只看该作者
难得的参考。
回复

使用道具 举报

12#
ID:77562 发表于 2015-5-24 23:27 | 只看该作者
看看吧
回复

使用道具 举报

13#
ID:111007 发表于 2016-4-9 22:44 来自手机 | 只看该作者
求源代码
回复

使用道具 举报

14#
ID:126302 发表于 2016-6-12 07:55 | 只看该作者
楼主能否可以把完整代码发一份给我。谢谢了!邮箱:158432053@qq.com
回复

使用道具 举报

15#
ID:145565 发表于 2016-11-1 19:58 | 只看该作者
这星期刚好接手这块,求完成代码,非常谢谢
回复

使用道具 举报

16#
ID:145565 发表于 2016-11-1 20:00 | 只看该作者
求楼主完整代码,刚忘了加邮箱1162209054@qq.com
回复

使用道具 举报

17#
ID:128380 发表于 2016-11-12 15:30 来自手机 | 只看该作者
好程序
回复

使用道具 举报

18#
ID:150090 发表于 2017-3-6 21:40 | 只看该作者
楼主好人  求源代码参考学习,谢谢   2529867499@qq.com
回复

使用道具 举报

19#
ID:168435 发表于 2017-3-8 11:43 | 只看该作者
楼主能否发一份程序,303852563@qq.com,感谢
回复

使用道具 举报

20#
ID:184677 发表于 2017-3-29 23:59 | 只看该作者

RC523可以直接替代RC522,但RC522不能替代RC523,主要在于RC522只支持ISO14443A协议,而RC支持RC523支持ISO14443A以及ISO14443B两种协议。另外,我司有MS522与MS523可以直接pin对pin替换RC522与RC523. 无需调整硬件,性能不变,价格变低,详情咨询 陈生 18826580495 QQ:609091075
回复

使用道具 举报

21#
ID:187525 发表于 2017-4-8 19:31 | 只看该作者
158432053 发表于 2016-6-12 07:55
**** 作者被禁止或删除 内容自动屏蔽 ****

朋友能把代码也发我一份吗?谢谢!
回复

使用道具 举报

22#
ID:187525 发表于 2017-4-8 19:32 | 只看该作者
卿卿 发表于 2016-11-1 19:58
**** 作者被禁止或删除 内容自动屏蔽 ****

朋友能把代码也发我一份吗?谢谢!
回复

使用道具 举报

23#
ID:187525 发表于 2017-4-8 19:32 | 只看该作者
18065166254 发表于 2017-3-8 11:43
楼主能否发一份程序,,感谢

朋友能把代码也发我一份吗?谢谢!
回复

使用道具 举报

24#
ID:187525 发表于 2017-4-8 19:33 | 只看该作者
朋友能把代码也发我一份吗?谢谢!
回复

使用道具 举报

25#
ID:187525 发表于 2017-4-8 19:36 | 只看该作者
朋友能把代码也发我一份吗?谢谢!916703769@qq.com
回复

使用道具 举报

26#
ID:105781 发表于 2017-5-14 17:03 | 只看该作者
楼主的RC522的电压是3.3V的吗?怎么处理的电压,谢谢
回复

使用道具 举报

27#
ID:206004 发表于 2017-5-30 10:17 | 只看该作者

楼主能否可以把完整代码发一份给我。谢谢了!邮箱:787875389@qq.com
回复

使用道具 举报

28#
ID:189104 发表于 2017-9-24 20:56 | 只看该作者
能不能发一下完整代码啊,谢谢楼主 846599713@qq.com
回复

使用道具 举报

29#
ID:245725 发表于 2017-11-3 15:45 | 只看该作者
楼主大人可否发我一份完整代码:3400682008@qq.com谢谢
回复

使用道具 举报

30#
ID:269601 发表于 2017-12-31 21:07 | 只看该作者
楼主大人可否发我一份完整代码啊,万分感谢!!!:412323530@qq.com
回复

使用道具 举报

31#
ID:60628 发表于 2018-6-3 10:38 | 只看该作者
求源代码 楼主发给我一份liangpin521@163.com
回复

使用道具 举报

32#
ID:347744 发表于 2018-6-8 17:13 | 只看该作者
求完整源代码 楼主发给我一份1638802453@qq.com
回复

使用道具 举报

33#
ID:347744 发表于 2018-6-8 17:14 | 只看该作者
楼主大人可否发我一份完整代码啊,万分感谢!!!:yd_liu_feng@163.com
回复

使用道具 举报

34#
ID:382181 发表于 2019-2-7 16:43 来自手机 | 只看该作者
楼主大人,求一份完整源码124443120@qq.com
回复

使用道具 举报

35#
ID:488693 发表于 2019-5-2 15:35 | 只看该作者
求楼主发一份完整程序 1027684342@qq.com 谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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