#include "reg52.h"
#include "main.h"
#include "mfrc522.h"
#include //函数处理头文件
#include //字符串处理头文件
#include // 输入输出函数头文件
unsigned char code data1[16] = {0x00,0x00,0x00,0x00,0xff,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0xFE,0x01,0xFE};
//M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
unsigned char data2[4]= {0x00,0x00,0x00,0x00};//存值减值金额
unsigned char code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //密码
unsigned char TYPE_DATA[2];//类型
unsigned char ID_DATA[4];//ID地址
unsigned char value_DATA[4];//卡里面的值
unsigned char g_ucTempbuf[20];//卡号
unsigned char code dis0[] = {"S50"};
unsigned char code dis1[] = {"S70"};
unsigned char code dis2[] = {"X"};
unsigned char code dis3[] = {"44"};
unsigned char code dis4[] = {"ID:"};
unsigned char code dis5[] = {"RMB:"};
unsigned char code dis6[] = {"0123456789ABCDEF"};
unsigned int tt=0,a=2,b,falg_pro; //falg_pro声音提示标志
void main( )
{
unsigned char status;
InitializeSystem( );//初始化
PcdReset();//复位RC522
PcdAntennaOff(); //关闭天线
PcdAntennaOn(); //开启天线
data2[1]=a/256;
data2[0]=a%256;
while ( 1 )
{
status = PcdRequest(PICC_REQALL, g_ucTempbuf); //返回卡片类型#define PICC_REQIDL 0x26 寻天线区内未进入休眠状态
if(status!= MI_OK) //读不到卡,显示清0;
{
TYPE_DATA[0]=0;
TYPE_DATA[1]=0;
ID_DATA[0]=0;
ID_DATA[1]=0;
ID_DATA[2]=0;
ID_DATA[3]=0;
value_DATA[0]=0;
value_DATA[1]=0;
value_DATA[2]=0;
value_DATA[3]=0;
falg_pro=0;
b=0;
}
if (status == MI_OK)
{
TYPE_DATA[0]=g_ucTempbuf[0];
TYPE_DATA[1]=g_ucTempbuf[1];
status = PcdAnticoll(g_ucTempbuf); //防冲撞 ,返回卡片ID号 4字节
if (status == MI_OK)
{
status = PcdSelect(g_ucTempbuf); //选定卡片,输入卡片ID号
if (status == MI_OK)
{
if(falg_pro==0)//声音提示标志
{
falg_pro=1;
pro();
}
ID_DATA[0]=g_ucTempbuf[0];
ID_DATA[1]=g_ucTempbuf[1];
ID_DATA[2]=g_ucTempbuf[2];
ID_DATA[3]=g_ucTempbuf[3];
init_k();//初始化卡
writek();//写卡
readk();
}
}
}
LCD1206();//显示处理
PcdHalt();//命令卡片进入休眠状态
}
}
/
//系统初始化
/
void InitializeSystem()
{
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
P3 = 0xFF;
fmq=0;//fmp喇叭
fmq=1;
lcd_init();// 初始化LCD
Delay(1);
}
void Delay(unsigned int time)
{
unsigned int i,k;
for(i=0;i<150;i++)
for(k=0;k
_nop_();
}
void Delay2(unsigned int time2)
{
unsigned int i,k;
for(i=0;i<5;i++)
for(k=0;k
_nop_();
}
显示处理函数
bit lcd_bz()// 测试LCD忙碌状态
{
bit result;
rs = 0;
rw = 1;
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0 & 0x80);
ep = 0;
return result;
}
lcd_wcmd(unsigned char cmd)// 写入指令数据到LCD
{
while(lcd_bz());
rs = 0;
rw = 0;
ep = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
return 0;
}
lcd_pos(unsigned char pos)
{ //设定显示位置
lcd_wcmd(pos | 0x80);
return 0;
}
lcd_wdat(unsigned char dat)
{ //写入字符显示数据到LCD
while(lcd_bz());
rs = 1;
rw = 0;
ep = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 1;
_nop_();
_nop_();
_nop_();
_nop_();
ep = 0;
return 0;
}
lcd_init() //LCD初始化设定
{
lcd_wcmd(0x38); //
Delay(1);
lcd_wcmd(0x0c); //
Delay(1);
lcd_wcmd(0x06); //
Delay(1);
lcd_wcmd(0x01); //清除LCD的显示内容
Delay(1);
return 0;
}
LCD1206()
{
unsigned char i;
lcd_pos(0x01);// 设置显示位置为第一行的第0个字符
i = 0;
switch(TYPE_DATA[0])
{
case 0x04:
lcd_wdat(dis0[0]); //dis0[] = {"S50"};
lcd_wdat(dis0[1]);
lcd_wdat(dis0[2]);
break;
case 0x02:
lcd_wdat(dis1[0]); //dis1[] = {"S70"};
lcd_wdat(dis1[1]);
lcd_wdat(dis1[2]);
break;
case 0x08: //dis2[] = {"X"};
lcd_wdat(dis2[0]);
break;
case 0x44:
lcd_wdat(dis3[0]); //dis3[] = {"44"};
lcd_wdat(dis3[1]);
break;
}
lcd_pos(0x05); // 设置显示位置为第一行的第5个字符
lcd_wdat(dis4[0]);//dis4[] = {"ID:"};
lcd_wdat(dis4[1]);
lcd_wdat(dis4[2]);
lcd_pos(0x08); // 设置显示位置为第一行的第5个字符
lcd_wdat(dis6[ID_DATA[0]/16]); //dis6[] = {"0123456789ABCDEF"};
lcd_wdat(dis6[ID_DATA[0]%16]);
lcd_wdat(dis6[ID_DATA[1]/16]);
lcd_wdat(dis6[ID_DATA[1]%16]);
lcd_wdat(dis6[ID_DATA[2]/16]);
lcd_wdat(dis6[ID_DATA[2]%16]);
lcd_wdat(dis6[ID_DATA[3]/16]);
lcd_wdat(dis6[ID_DATA[3]%16]);
lcd_pos(0x40); // 设置显示位置为第二行第二个字符
lcd_wdat(dis5[0]);//dis5[] = {"RMB:"};
lcd_wdat(dis5[1]);
lcd_wdat(dis5[2]);//
lcd_wdat(dis5[3]);// 人民币
lcd_wdat(dis6[0]);
lcd_wdat(dis6[2]);
lcd_pos(0x47); // 设置显示位置为第二行第二个字符
lcd_wdat(dis5[0]);
lcd_wdat(dis5[1]);
lcd_wdat(dis5[2]);//
lcd_wdat(dis5[3]);// 人民币
lcd_pos(0x4b);
lcd_wdat(dis6[b/10000]);
lcd_wdat(dis6[b%10000/1000]);
lcd_wdat(dis6[b%10000%1000/100]);
lcd_wdat(dis6[b%10000%1000%100/10]);
lcd_wdat(dis6[b%10000%1000%100%10]);
return 0;
}
void pro()
{
fmq=0;
TMOD=0x11;//设置定时器0为工作方式1
TH0=(65536-50000)/256;//给定时器装初值 高八位
TL0=(65536-50000)%256;//给定时器装初值 低八位
EA=1; //开总中断
ET0=1;//开定时器0中断
TR0=1;//启动定时器0
}
void time0() interrupt 1// 中断服务子程序 声音时间一致
{
TH0=(65536-50000)/256;//给定时器装初值 高八位
TL0=(65536-50000)%256;//给定时器装初值 低八位
tt++;
if(tt==3)
{
tt=0;
fmq=1;
EA=0; //关总中断
ET0=0;//关定时器0中断
TR0=0;//关定时器0
}
}
void readk()//读卡
{
unsigned char status;
status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
if (status == MI_OK) //验证密码
{
status = PcdRead(1, g_ucTempbuf);//读块地址“1”的数据,返回值存在 g_ucTempbuf
if (status == MI_OK)
{
value_DATA[0]=g_ucTempbuf[0];
value_DATA[1]=g_ucTempbuf[1];
value_DATA[2]=g_ucTempbuf[2];
value_DATA[3]=g_ucTempbuf[3];
b=value_DATA[0]+value_DATA[1]*256;
}
}
}
void writek()//写卡 存值或减值
{
unsigned char status;
status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
if (status == MI_OK) //验证密码
{
if(1)//扣款
{
if(b>1)
{
status = PcdValue(PICC_DECREMENT,1,data2);//扣款存值命令,钱包地址,金额 低位在前PICC_INCREMENT 充值
if (status == MI_OK)
{
pro();
}
status = PcdBakValue(1, 2); //备份钱包 “1”源地址“2”目标地址
Delay(1000);
b=b-2;
}
else
{
unsigned int x;
for(x=1;x<4000;x++)
{
fmq=1;
Delay2(1);
fmq=0;
}
}
}
}
}
void init_k()//初始化卡
{
unsigned char status;
if(key1==0)//充值
{
status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
if (status == MI_OK) //验证密码
{
status = PcdWrite(1, data1);//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
if (status == MI_OK)
{
pro();
}
}
}
}