标题:
51单片机读写RC522卡(LCD12864)RFID开发程序与原理图
[打印本页]
作者:
之文组合
时间:
2018-1-2 14:59
标题:
51单片机读写RC522卡(LCD12864)RFID开发程序与原理图
RFID RC522程序及原理
RC522原理图1.png
(165.44 KB, 下载次数: 99)
下载附件
2018-1-2 14:58 上传
单片机源程序如下:
#include "reg52.h"
#include "main.h"
#include "mfrc522.h"
#include "LCD12864.h"
#include <string.h>
#include <stdio.h>
sbit BEEP=P0^1 ;
#define SET_BEEP BEEP = 0
#define CLR_BEEP BEEP = 1
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
unsigned char code data2[4] = {0x12,0,0,0};
unsigned char code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
//unsigned char g_ucTempbuf[20];
unsigned char idata MLastSelectedSnr[4];
unsigned char idata RevBuffer[30];
//unsigned char data SerBuffer[20];
bit CmdValid;
unsigned char code ASCII_NUM[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
unsigned char idata LastKeyA[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};//NO.2卡
unsigned char idata NewKeyA[6]={0x19,0x84,0x07,0x15,0x76,0x14};//NO.2卡
unsigned char idata NewKey[16]={0x19,0x84,0x07,0x15,0x76,0x14,
0xff,0x07,0x80,0x69,
0x19,0x84,0x07,0x15,0x76,0x14};
unsigned char idata Read_Data[16]={0x00};
//unsigned char idata RevBuffer[30];
//unsigned char idata MLastSelectedSnr[4];
unsigned char data OperationCard;
uchar data bWarn,bPass;
#define REGCARD 0xa1
#define CONSUME 0xa2
#define READCARD 0xa3
#define ADDMONEY 0xa4
void KeyScan(void)
{
if(REGCARDBTN == 0)//注册
{
delay_10ms(1);
if(REGCARDBTN == 0 )
OperationCard = REGCARD;
LCD_PutString(0,3,"注册:");
}
if(CONSUMEBTN == 0)//消费
{
delay_10ms(1);
if(CONSUMEBTN == 0 )
OperationCard = CONSUME;
LCD_PutString(0,3,"消费: ");
}
if(ADDMONEYBTN == 0)//充值
{
delay_10ms(1);
if(ADDMONEYBTN == 0 )
OperationCard = ADDMONEY;
LCD_PutString(0,3,"充值: ");
}
if(READCARDBTN == 0)//读卡信息
{
delay_10ms(1);
if(READCARDBTN == 0 )
OperationCard = READCARD;
LCD_PutString(0,3,"查询: ");
}
}
/*
void delay(void)
{
uint i ;
for(i=0;i++;i<100)
;
}
void ShortBeep(void)
{
uint i;
for(i=0;i<3;i++)
{
SET_BEEP;
delay_10ms(3);
CLR_BEEP;
delay();
}
}
void LongBeep(void)
{
uint i;
for(i=0;i<20;i++)
{
SET_BEEP;
delay_10ms(5);
CLR_BEEP;
delay();
}
}
*/
void Warn(void)
{
uchar data ii;
for(ii=0;ii<3;ii++)
{
SET_BEEP;//ShortBeep();如果是有源蜂鸣器就一句SET_BEEP就ok了
delay_10ms(5);
CLR_BEEP;
delay_10ms(5);
}
}
void Pass(void)
{
SET_BEEP;//LongBeep();如果是有源蜂鸣器就一句SET_BEEP就ok了
delay_10ms(30);
CLR_BEEP;
}
void CtrlProcess(void)
{
// unsigned char idata Write_First_Data[16];
char string[]=" ";
unsigned char idata Write_Consume_Data[16];
signed long money_value;
float f_money_value;
unsigned char ii;
char status;
status=PcdRequest(PICC_REQIDL,&RevBuffer[0]);//寻天线区内未进入休眠状态的卡,返回卡片类型 2字节
if(status!=MI_OK)
return;
for(ii=0;ii<2;ii++)
{
string[2*ii] = ASCII_NUM[(RevBuffer[ii]>>4)&0x0f];
string[2*ii+1] = ASCII_NUM[RevBuffer[ii]&0x0f];
}
string[4] = '\0';
LCD_PutString(3,1,string);//LCD显示卡类型
status=PcdAnticoll(&RevBuffer[2]);//防冲撞,返回卡的序列号 4字节
if(status!=MI_OK)
return;
memcpy(MLastSelectedSnr,&RevBuffer[2],4);//4字节序列号 放到MLastSelectedSnr
for(ii=0;ii<4;ii++)
{
string[2*ii] = ASCII_NUM[(MLastSelectedSnr[ii]>>4)&0x0f];
string[2*ii+1] = ASCII_NUM[MLastSelectedSnr[ii]&0x0f];
}
string[9] = '\0';
LCD_PutString(3,2,string);// LCD显示序列号
status=PcdSelect(MLastSelectedSnr);//选卡
if(status!=MI_OK)
return;
if(OperationCard==REGCARD)//注册
{
status=PcdAuthState(PICC_AUTHENT1A,7,LastKeyA,MLastSelectedSnr);//
//DelayNS(1);
if(status!=MI_OK)
{
bWarn=1;
return;
}
status=PcdWrite(7,&NewKey[0]);
if(status!=MI_OK)
{
bWarn=1;
return;
}
for(ii=0;ii<16;ii++)
{
Write_Consume_Data[ii]=0xaa;//Write_First_Data
}
memset( Write_Consume_Data, 0, sizeof(Write_Consume_Data) );//Write_First_Data Write_First_Data
money_value = 5000;
memcpy( Write_Consume_Data, ( uchar * )&money_value, 4 ); //Write_First_Data
status=PcdWrite(4,&Write_Consume_Data[0]);//Write_First_Data
if(status!=MI_OK)
{
bWarn=1;
return;
}
LCD_PutString(0,3,"注册: 成功");
bPass=1;
PcdHalt();
}
else if(OperationCard==READCARD)//读卡
{
status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
if(status!=MI_OK)
return;
status=PcdRead(4,Read_Data);
if(status!=MI_OK)
{
bWarn=1;
return;
}
memcpy( (uchar *)&money_value, Read_Data, 4 );
LCD_PutString(0,3,"查询: ");
f_money_value = money_value * 1.0/100;
sprintf(string,"%5.2f",f_money_value);
LCD_PutString(3,4,string);
//ShowFloat816( 4, 5, ( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ) );
if(f_money_value<0)
bWarn=1;
bPass=1;
PcdHalt();
}
else if(OperationCard==CONSUME)//消费
{
status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//
if(status!=MI_OK)
return;
status=PcdRead(4,Read_Data);
if(status!=MI_OK)
{
bWarn=1;
return;
}
memcpy( (uchar *)&money_value, Read_Data, 4 );
if(money_value<-10000)
money_value=-10000;
if(money_value<0)
money_value+=10000;
money_value=money_value-258;
memcpy( Write_Consume_Data, (uchar *)&money_value, 4 );
status=PcdWrite(4,&Write_Consume_Data[0]);
if(status!=MI_OK)
{
bWarn=1;
return;
}
//ShowFloat816(2,5,2.58);
LCD_PutString(0,3,"消费: 2.58 ");
f_money_value = money_value * 1.0/100;
sprintf(string,"%5.2f",f_money_value);
LCD_PutString(3,4,string);
//ShowFloat816(4,5,( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ));
if(money_value<0)
bWarn=1;
else
bPass=1;
PcdHalt();
}
else if(OperationCard==ADDMONEY)//充值
{
status=PcdAuthState(PICC_AUTHENT1A,7,NewKeyA,MLastSelectedSnr);//????KUAI4?
if(status!=MI_OK)
return;
status=PcdRead(4,Read_Data);
if(status!=MI_OK)
{
bWarn=1;
return;
}
memcpy( (uchar *)&money_value, Read_Data, 4 );
if(money_value<-10000)
money_value=-10000;
if(money_value<0)
money_value+=10000;
money_value=money_value+5000;
memcpy( Write_Consume_Data, (uchar *)&money_value, 4 );
status=PcdWrite(4,&Write_Consume_Data[0]);
if(status!=MI_OK)
{
bWarn=1;
return;
}
//ShowFloat816(2,5,50.00);
LCD_PutString(0,3,"充值: 50.00 ");
f_money_value = money_value * 1.0/100;
sprintf(string,"%5.2f",f_money_value);
LCD_PutString(3,4,string);
//ShowFloat816(4,5,( f_money_value >= 0 ) ? ( ( f_money_value+0.5 )/100 ) : ( ( f_money_value-0.5 )/100 ));
bPass=1;
PcdHalt();
}
OperationCard = 0;
}
void iccardcode()
{
unsigned char cmd;
unsigned char status;
cmd = RevBuffer[0];
switch(cmd)
{
case 1: // Halt the card //终止卡的操作
status= PcdHalt();;
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 2: // Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
// 寻卡,防冲突,选择卡 返回卡类型(2 bytes)+ 卡系列号(4 bytes)
status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
if(status!=0)
{
status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
if(status!=0)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
}
RevBuffer[0]=3;
RevBuffer[1]=status;
break;
case 3: // 防冲突 读卡的系列号 MLastSelectedSnr
status = PcdAnticoll(&RevBuffer[2]);
if(status!=0)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
memcpy(MLastSelectedSnr,&RevBuffer[2],4);
RevBuffer[0]=5;
RevBuffer[1]=status;
break;
case 4: // 选择卡 Select Card
status=PcdSelect(MLastSelectedSnr);
if(status!=MI_OK)
{
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
}
RevBuffer[0]=3;
RevBuffer[1]=status;
break;
case 5: // Key loading into the MF RC500's EEPROM
status = PcdAuthState(RevBuffer[1], RevBuffer[3], DefaultKey, MLastSelectedSnr);// 校验卡密码
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 6:
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 7:
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 8: // Read the mifare card
// 读卡
status=PcdRead(RevBuffer[1],&RevBuffer[2]);
if(status==0)
{RevBuffer[0]=17;}
else
{RevBuffer[0]=1;}
RevBuffer[1]=status;
break;
case 9: // Write the mifare card
// 写卡 下载密码
status=PcdWrite(RevBuffer[1],&RevBuffer[2]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 10:
PcdValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
RevBuffer[0]=1;
RevBuffer[1]=status;
break;
case 12: // 参数设置
PcdBakValue(RevBuffer[1], RevBuffer[2]);
RevBuffer[0]=1; //contact
RevBuffer[1]=0;
break;
}
}
/////////////////////////////////////////////////////////////////////
//系统初始化
/////////////////////////////////////////////////////////////////////
void InitializeSystem()
{
P0 = 0xFF; P1 = 0xFF; P3 = 0xFF;
ET2 = 0;
T2CON = 0x04; //TR2=1 LYF
PCON = 0x00;//0x80;
SCON = 0x70;//SMO SM1= 0 1 方式1,对于方式1,SM2=1,接收到有效的停止位时,将RI置1,REN置1时允许接收数据
TMOD = 0x21;//TMOD = 0x22; TIMER1:C/T=0,定时器,M1M0=10,T1为工作模式2,即8位自动重装载模式
//TIMER0: C/T=0,定时器,M1M0=01,16位计数器
TH1 = BAUD_2400;
TL1 = TH1;
TR1 = 1; // T1 作为波特率发生器
TH0 = 0x60;
TL0 = 0x60;
TR0 = 0;
ET0=0;
ET1=0;
EA=1;
//EX0=1;
//IT0 = 1;
TR2=0;
ES = 1;
CmdValid=0;
LED_GREEN = 1;
PcdReset();
PcdAntennaOff();
PcdAntennaOn();
M500PcdConfigISOType( 'A' );
LED_GREEN = 0;
delay_10ms(10);
LED_GREEN = 1;
delay_10ms(10);
LED_GREEN = 0;
}
/////////////////////////////////////////////////////////////////////
//用T2做延时子程序
/////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// 接收和发送中断
///////////////////////////////////////////////////////////////////////
void isr_UART(void) interrupt 4 using 1
{
unsigned char len, i;
unsigned int j=0;
if(RI)
{
len=SBUF;
RI=0;
for(i=0;i<len;i++)
{
while(!RI)
{
j++;
if(j>1000)
{
break;
}
}
if(j<1000)
{
RevBuffer[i]=SBUF;
RI=0;
j=0;
}
else
{
break;
}
}
if(i==len)
{
REN=0;
CmdValid=1;
}
}
else if(!RI && TI)
{
TI=0;
len=RevBuffer[0];
for(i=0;i<len+1;i++)
{
SBUF=RevBuffer[i];
while(!TI);
TI=0;
}
REN=1;
}
}
void UartProcess(void)
{
unsigned char baud;
if(RevBuffer[0]==11) //为了加快相应速度 测试风鸣器
{
RevBuffer[2]=RevBuffer[1];
RevBuffer[0]=1; //contact
RevBuffer[1]=0;
CALL_isr_UART();
LED_GREEN = 1;
delay_10ms(RevBuffer[2]);
LED_GREEN = 0;
}
else if(RevBuffer[0]==13) //设置通讯波特率
{
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;
}
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
6-51读写卡程序(LCD12864).rar
(98.49 KB, 下载次数: 373)
2018-1-2 14:58 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
醒悟
时间:
2019-5-22 16:26
对于1602来说,这个程序适用吗?
作者:
小白H
时间:
2019-6-18 12:13
原理图用什么软件画的
作者:
203385918
时间:
2020-1-1 20:38
小白H 发表于 2019-6-18 12:13
原理图用什么软件画的
AD软件。。。。。。。。
作者:
小颖
时间:
2020-3-8 13:02
感谢分享
作者:
739004020
时间:
2020-4-14 20:03
楼主,怎么没有显示呢?
作者:
池渊
时间:
2020-5-24 01:01
能问一下楼主UartProccess跟iccardcode两个函数的作用吗?什么情况下会调用呢?
作者:
ylshu
时间:
2021-4-22 11:33
谢谢楼主分享。非常感谢,学习中
作者:
tarchen
时间:
2024-10-1 09:20
感谢分享,有空看看.
作者:
QEQWE123
时间:
2025-2-6 16:48
实测刷卡+显示+按键都好用
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1