本帖最后由 lbq691477940 于 2014-11-18 23:56 編輯
由STC12C5A60S2+RC522構成的IC卡讀卡器
108_623247_a385369a1dbb50b.jpg (51.06 KB, 下載次數: 300)
下載附件
2014-11-18 23:55 上傳
讀出的卡號從串口返回
108_623247_ed3b9c52d97f9e9.jpg (156.91 KB, 下載次數: 282)
下載附件
2014-11-18 23:56 上傳
RC522 非接觸式IC卡讀卡模塊 采用I2C接口通信方式占用CPU I/O口最少,非SPI通信接口方式。
外觀尺下:62X34mm
插針間距: 7Pin x 2.54mm
本模塊非SPI通信接口方式,采用I2C接口通信方式占用CPU I/O口最少;從機器件地址為:0x00H
108_623247_271ae08cfd73d8c.jpg (91.8 KB, 下載次數: 281)
下載附件
2014-11-18 23:56 上傳
有需要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;
}
}
/**********************************************************************************************************/
}
}
/***********************************************************************************************************/
|