标题:
51单片机水卡充值扣费系统 RC522+S50卡源程序
[打印本页]
作者:
xianxianhh
时间:
2019-8-15 10:48
标题:
51单片机水卡充值扣费系统 RC522+S50卡源程序
本设计包括两个终端,包括负责水卡充值(可选择金额)的充值终端和每次刷卡扣费两元的付费终端。制作成品时建议两个终端做在一块板子上,用跳帽切换两个51单片机的电源。
主控芯片51单片机
射频模块RC522
射频卡M1卡S50
以下是付费终端的程序,其他详见附件
#include "reg52.h"
#include "main.h"
#include "mfrc522.h"
#include<intrins.h> //函数处理头文件
#include<string.h> //字符串处理头文件
#include<stdio.h> // 输入输出函数头文件
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<time;k++)
_nop_();
}
void Delay2(unsigned int time2)
{
unsigned int i,k ;
for(i=0;i<5;i++)
for(k=0;k<time2;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();
}
}
}
}
复制代码
全部程序51hei下载地址:
注册程序.rar
(90.98 KB, 下载次数: 84)
2019-8-15 10:47 上传
点击文件名下载附件
下载积分: 黑币 -5
刷卡程序.rar
(88.79 KB, 下载次数: 106)
2019-8-15 10:47 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
youluping520
时间:
2020-10-13 09:23
这个程序最多能注册多少个会员?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1