找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机水卡充值扣费系统 RC522+S50卡源程序

[复制链接]
跳转到指定楼层
楼主
ID:437557 发表于 2019-8-15 10:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本设计包括两个终端,包括负责水卡充值(可选择金额)的充值终端和每次刷卡扣费两元的付费终端。制作成品时建议两个终端做在一块板子上,用跳帽切换两个51单片机的电源。

主控芯片51单片机
射频模块RC522
射频卡M1卡S50
以下是付费终端的程序,其他详见附件
  1. #include "reg52.h"
  2. #include "main.h"
  3. #include "mfrc522.h"
  4. #include<intrins.h>         //函数处理头文件        
  5. #include<string.h>          //字符串处理头文件  
  6. #include<stdio.h>           // 输入输出函数头文件

  7. unsigned char code data1[16] = {0x00,0x00,0x00,0x00,0xff,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0xFE,0x01,0xFE};
  8. //M1卡的某一块写为如下格式,则该块为钱包,可接收扣款和充值命令
  9. //4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
  10. unsigned char data2[4]  = {0x00,0x00,0x00,0x00};//存值减值金额
  11. unsigned char code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //密码
  12. unsigned char TYPE_DATA[2];                                              //类型
  13. unsigned char ID_DATA[4];                                                //ID地址
  14. unsigned char value_DATA[4];                                             //卡里面的值                                                                                                                                 
  15. unsigned char g_ucTempbuf[20];                                           //卡号
  16. unsigned char code dis0[] = {"S50"};
  17. unsigned char code dis1[] = {"S70"};
  18. unsigned char code dis2[] = {"X"};
  19. unsigned char code dis3[] = {"44"};        
  20. unsigned char code dis4[] = {"ID:"};  
  21. unsigned char code dis5[] = {"RMB:"};   
  22. unsigned char code dis6[] = {"0123456789ABCDEF"};  
  23. unsigned int tt=0,a=2,b,falg_pro;                                    //falg_pro声音提示标志         
  24. void main( )
  25. {     
  26.      unsigned char status;
  27.      InitializeSystem( );                 //初始化
  28.      PcdReset();                                //复位RC522
  29.      PcdAntennaOff();                     //关闭天线
  30.      PcdAntennaOn();                      //开启天线
  31.            data2[1]=a/256;
  32.                  data2[0]=a%256;
  33.      while ( 1 )
  34.      {                           
  35.                status = PcdRequest(PICC_REQALL, g_ucTempbuf); //返回卡片类型#define PICC_REQIDL 0x26 寻天线区内未进入休眠状态
  36.                                  if(status!= MI_OK)         //读不到卡,显示清0;
  37.                                  {
  38.                                                 TYPE_DATA[0]=0;         
  39.                                                 TYPE_DATA[1]=0;
  40.                                                 ID_DATA[0]=0;
  41.                                                 ID_DATA[1]=0;
  42.                                                 ID_DATA[2]=0;
  43.                                                 ID_DATA[3]=0;
  44.                                                 value_DATA[0]=0;
  45.                                                 value_DATA[1]=0;
  46.                                                 value_DATA[2]=0;
  47.                                                 value_DATA[3]=0;
  48.                                                 falg_pro=0;
  49.                                                 b=0;
  50.                                  }
  51.          if (status == MI_OK)
  52.          {         
  53.                                                  TYPE_DATA[0]=g_ucTempbuf[0];
  54.                                                  TYPE_DATA[1]=g_ucTempbuf[1];
  55.                                                   status = PcdAnticoll(g_ucTempbuf);       //防冲撞 ,返回卡片ID号 4字节
  56.                          if (status == MI_OK)
  57.                          {
  58.                                                            status = PcdSelect(g_ucTempbuf);    //选定卡片  ,输入卡片ID号
  59.                                          if (status == MI_OK)
  60.                                          {         
  61.                                                                      if(falg_pro==0)//声音提示标志
  62.                                                                                  {
  63.                                                                                          falg_pro=1;
  64.                                                                                          pro();
  65.                                                                                  }        
  66.                                                                          ID_DATA[0]=g_ucTempbuf[0];
  67.                                                                          ID_DATA[1]=g_ucTempbuf[1];
  68.                                                                          ID_DATA[2]=g_ucTempbuf[2];
  69.                                                                          ID_DATA[3]=g_ucTempbuf[3];
  70.                                                                          init_k();//初始化卡
  71.                                                                          writek();//写卡
  72.                                                                    readk();
  73.                                                                         
  74.                                          }           
  75.                          }
  76.                  }            
  77.                         LCD1206();//显示处理        
  78.                         PcdHalt();//命令卡片进入休眠状态        
  79.          }      
  80. }
  81. /////////////////////////////////////////////////////////////////////
  82. //系统初始化
  83. /////////////////////////////////////////////////////////////////////
  84. void InitializeSystem()
  85. {     
  86.    P0 = 0xFF;
  87.          P1 = 0xFF;
  88.          P2 = 0xFF;
  89.          P3 = 0xFF;
  90.          fmq=0;             //fmp喇叭
  91.          fmq=1;
  92.          lcd_init();                                // 初始化LCD                        
  93.          Delay(1);
  94. }
  95. void Delay(unsigned int time)
  96. {
  97.   unsigned int i,k  ;
  98.   for(i=0;i<150;i++)
  99.     for(k=0;k<time;k++)
  100.       _nop_();         
  101. }

  102. void Delay2(unsigned int time2)
  103. {
  104.   unsigned int i,k  ;
  105.   for(i=0;i<5;i++)
  106.     for(k=0;k<time2;k++)
  107.       _nop_();         
  108. }
  109. ////////////////////////显示处理函数////////////////////////////////
  110. bit lcd_bz()                            // 测试LCD忙碌状态
  111. {                                                
  112.         bit result;
  113.         rs = 0;
  114.         rw = 1;
  115.         ep = 1;
  116.         _nop_();
  117.         _nop_();
  118.         _nop_();
  119.         _nop_();
  120.         result = (bit)(P0 & 0x80);
  121.         ep = 0;
  122.         return result;        
  123. }
  124. lcd_wcmd(unsigned char cmd)// 写入指令数据到LCD
  125. {                                                        
  126.         while(lcd_bz());
  127.         rs = 0;
  128.         rw = 0;
  129.         ep = 0;
  130.         _nop_();
  131.         _nop_();        
  132.         P0 = cmd;
  133.         _nop_();
  134.         _nop_();
  135.         _nop_();
  136.         _nop_();
  137.         ep = 1;
  138.         _nop_();
  139.         _nop_();
  140.         _nop_();
  141.         _nop_();
  142.         ep = 0;
  143.         return 0;
  144. }

  145. lcd_pos(unsigned char pos)
  146. {                                                        //设定显示位置
  147.         lcd_wcmd(pos | 0x80);
  148.         return 0;
  149. }

  150. lcd_wdat(unsigned char dat)        
  151. {                                                        //写入字符显示数据到LCD
  152.         while(lcd_bz());
  153.         rs = 1;
  154.         rw = 0;
  155.         ep = 0;
  156.         P0 = dat;
  157.         _nop_();
  158.         _nop_();
  159.         _nop_();
  160.         _nop_();
  161.         ep = 1;
  162.         _nop_();
  163.         _nop_();
  164.         _nop_();
  165.         _nop_();
  166.         ep = 0;        
  167.         return 0;
  168. }
  169. lcd_init()                                         //LCD初始化设定
  170. {                                                        
  171.         lcd_wcmd(0x38);                        //
  172.         Delay(1);
  173.         lcd_wcmd(0x0c);                        //
  174.         Delay(1);
  175.         lcd_wcmd(0x06);                        //
  176.         Delay(1);
  177.         lcd_wcmd(0x01);                        //清除LCD的显示内容
  178.         Delay(1);
  179.         return 0;
  180. }
  181. LCD1206()
  182. {
  183.         unsigned char i;
  184.         lcd_pos(0x01);                                // 设置显示位置为第一行的第0个字符
  185.         i = 0;
  186.         switch(TYPE_DATA[0])
  187.                  {
  188.                  case 0x04:
  189.            lcd_wdat(dis0[0]);                     //dis0[] = {"S50"};
  190.                  lcd_wdat(dis0[1]);
  191.                  lcd_wdat(dis0[2]);
  192.                  break;
  193.                  case 0x02:
  194.                  lcd_wdat(dis1[0]);                     //dis1[] = {"S70"};
  195.                  lcd_wdat(dis1[1]);
  196.                  lcd_wdat(dis1[2]);
  197.                  break;
  198.                  case 0x08:                             //dis2[] = {"X"};
  199.            lcd_wdat(dis2[0]);
  200.                  break;
  201.                  case 0x44:
  202.                  lcd_wdat(dis3[0]);                     //dis3[] = {"44"};  
  203.                  lcd_wdat(dis3[1]);
  204.                  break;   
  205.                  }
  206.                         lcd_pos(0x05);                                            // 设置显示位置为第一行的第5个字符
  207.                         lcd_wdat(dis4[0]);                //dis4[] = {"ID:"};  
  208.                         lcd_wdat(dis4[1]);
  209.                         lcd_wdat(dis4[2]);
  210.                         lcd_pos(0x08);                                            // 设置显示位置为第一行的第5个字符
  211.                   lcd_wdat(dis6[ID_DATA[0]/16]);    //dis6[] = {"0123456789ABCDEF"};
  212.                         lcd_wdat(dis6[ID_DATA[0]%16]);
  213.                         lcd_wdat(dis6[ID_DATA[1]/16]);
  214.                         lcd_wdat(dis6[ID_DATA[1]%16]);
  215.                         lcd_wdat(dis6[ID_DATA[2]/16]);
  216.                         lcd_wdat(dis6[ID_DATA[2]%16]);
  217.                         lcd_wdat(dis6[ID_DATA[3]/16]);
  218.                         lcd_wdat(dis6[ID_DATA[3]%16]);
  219.                         lcd_pos(0x40);                                      // 设置显示位置为第二行第二个字符
  220.                         lcd_wdat(dis5[0]);                //dis5[] = {"RMB:"};
  221.                         lcd_wdat(dis5[1]);
  222.                         lcd_wdat(dis5[2]);//
  223.                         lcd_wdat(dis5[3]);//        人民币
  224.                         lcd_wdat(dis6[0]);
  225.                         lcd_wdat(dis6[2]);
  226.                
  227.                         lcd_pos(0x47);                        // 设置显示位置为第二行第二个字符
  228.                         lcd_wdat(dis5[0]);
  229.                         lcd_wdat(dis5[1]);
  230.                         lcd_wdat(dis5[2]);//
  231.                         lcd_wdat(dis5[3]);//        人民币
  232.                         lcd_pos(0x4b);
  233.                         lcd_wdat(dis6[b/10000]);
  234.                         lcd_wdat(dis6[b%10000/1000]);
  235.                         lcd_wdat(dis6[b%10000%1000/100]);
  236.                         lcd_wdat(dis6[b%10000%1000%100/10]);
  237.                         lcd_wdat(dis6[b%10000%1000%100%10]);
  238.                         return 0;
  239. }  
  240. void pro()
  241. {
  242.         fmq=0;
  243.         TMOD=0x11;//设置定时器0为工作方式1
  244.         TH0=(65536-50000)/256;//给定时器装初值 高八位
  245.         TL0=(65536-50000)%256;//给定时器装初值 低八位
  246.         EA=1;   //开总中断
  247.         ET0=1;  //开定时器0中断
  248.         TR0=1;  //启动定时器0
  249. }

  250. void time0() interrupt 1// 中断服务子程序 声音时间一致
  251. {

  252. TH0=(65536-50000)/256;//给定时器装初值 高八位
  253. TL0=(65536-50000)%256;//给定时器装初值 低八位
  254. tt++;
  255. if(tt==3)
  256.         {        
  257.     tt=0;
  258.                 fmq=1;
  259.                 EA=0;   //关总中断
  260.                 ET0=0;  //关定时器0中断
  261.                 TR0=0;  //关定时器0
  262.         }        
  263. }

  264. void readk()//读卡
  265. {        
  266. unsigned char status;
  267. status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
  268.          if (status == MI_OK) //验证密码
  269.          {                                                                                                                                                                                                                                                                                                                                                                                          
  270.     status = PcdRead(1, g_ucTempbuf);//读块地址“1”的数据,返回值存在        g_ucTempbuf
  271.                           if (status == MI_OK)
  272.                           {
  273.                                 value_DATA[0]=g_ucTempbuf[0];
  274.                                 value_DATA[1]=g_ucTempbuf[1];
  275.                                 value_DATA[2]=g_ucTempbuf[2];
  276.                                 value_DATA[3]=g_ucTempbuf[3];        
  277.                                 b=value_DATA[0]+value_DATA[1]*256;                                                                                    
  278.                           }   
  279.      }
  280. }        
  281. void writek()//写卡        存值或减值
  282. {
  283.     unsigned char status;
  284.     status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
  285.           if (status == MI_OK) //验证密码
  286.           {        

  287.                          if(1)                              //扣款
  288.                          {
  289.                                  if(b>1)
  290.                                  {
  291.                                          status = PcdValue(PICC_DECREMENT,1,data2);//扣款存值命令,钱包地址,金额 低位在前  PICC_INCREMENT 充值
  292.                                          if (status == MI_OK)
  293.                                          {
  294.                                          pro();
  295.                                          }      
  296.                                          status = PcdBakValue(1, 2);              //备份钱包          “1”源地址“2”目标地址
  297.                                          Delay(1000);
  298.                                          b=b-2;
  299.                                  }
  300.                                  else
  301.                                  {
  302.                                          unsigned int x;
  303.                                          for(x=1;x<4000;x++)
  304.                                          {
  305.                                          fmq=1;
  306.            Delay2(1);
  307.                                          fmq=0;
  308.                                          }
  309.                                  }
  310.                                 
  311.                          }
  312.                 }

  313. }        
  314. void init_k()//初始化卡
  315. {
  316.     unsigned char status;
  317.                 if(key1==0)                              //充值
  318.                 {
  319.             status = PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, g_ucTempbuf);//PICC_AUTHENT1A 验证密码模式60A密码 61B密码,“1”块地址,DefaultKey初始密码,g_ucTempbuf ID号
  320.                   if (status == MI_OK) //验证密码
  321.                   {                                                                                                                                                                                                                                                                                                                                          
  322.                                   status = PcdWrite(1, data1);//4字节金额(低字节在前)+4字节金额取反+4字节金额+1字节块地址+1字节块地址取反+1字节块地址+1字节块地址取反
  323.                                   if (status == MI_OK)
  324.                                          {
  325.                                                   pro();
  326.                                          }
  327.                         }
  328.                 }
  329. }         
复制代码
全部程序51hei下载地址:
注册程序.rar (90.98 KB, 下载次数: 84)
刷卡程序.rar (88.79 KB, 下载次数: 106)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:828714 发表于 2020-10-13 09:23 来自手机 | 只看该作者
这个程序最多能注册多少个会员?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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