找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4242|回复: 4
收起左侧

MSP430F149单片机实现公交卡/饭卡充值功能模块(RFID+RC522源程序)

[复制链接]
ID:594608 发表于 2019-9-23 14:56 | 显示全部楼层 |阅读模式
实验目的
1.   最基础实现刷卡后显示冲值/扣款说明
2.   实现芯片内部寄存器的读写,实现可记忆性。
设计思路
根据M1射频卡与读写器的通讯过程,程序设计基本流程如下:
1569221583(1).jpg
主函数架构:
  1. void main(void)
  2. {
  3.   WDTCTL = WDTPW + WDTHOLD; // 关看门狗
  4.   int i = 0;
  5.   unsigned char status;
  6.   BoardConfig(0xf0);
  7.   Init_Port();
  8.   InitUART();
  9.   Port_init();   //系统初始化,设置IO口属性
  10.   delay_ms(100); //延时100ms
  11.   LCD_init();    //液晶参数初始化设置
  12.   LCD_clear();   //清屏
  13.   LCD_Desk1();
  14.   _EINT();
  15.   PcdReset();     //复位RC522
  16.   PcdAntennaOn(); //开启天线发射
  17.   while (1)
  18.   {
  19.     status = PcdRequest(PICC_REQIDL, Temp); ////寻卡,输出为卡类型
  20.     if (status == MI_OK)
  21.       status = PcdAnticoll(UD); //防冲撞处理,输出卡片序列号,4字节
  22.     if (status == MI_OK)
  23.       status = PcdSelect(UD); //选择卡片,输入卡片序列号,4字节
  24.     if (status == MI_OK)
  25.       status = PcdAuthState(PICC_AUTHENT1A, 1, Password_Buffer, UD); //在进行读写操作之前需要先进行认证
  26.     if (status == MI_OK)
  27.       status == incharg();//读
  28.     if (status == MI_OK)
  29.     {
  30.       status = PcdWrite(1,money_ok);//充钱
  31.       memset(money_ok,0,sizeof(money_ok));
  32.       break;
  33.      }
  34.     }
  35.       LCD_clear(); //清屏
  36.       LCD_Desk3();  
  37.       led();
  38.   }
复制代码
其中
status == incharg();//读
incharg 函数
这一部分是自己编写用于读写存储器内容,并且进行数据类型转换功能的函数。
  1. char incharg(void)
  2. {
  3.   unsigned char g_ucTempbuf[20];
  4.   unsigned char num;
  5.   unsigned char temp1[10];
  6.   unsigned char temp2[5];
  7.   unsigned char status2;
  8.   long int sum = 0;               //充值后整数部分的额度
  9.   long int re;

  10.   temp1[0] = '\0';
  11.   temp2[0] = '\0';
  12.   memset(money, 0, sizeof(money)); //清空钱包临时数组
  13.   status2 = PcdRead(1, g_ucTempbuf);//读块2部分
  14.   if (status2 == MI_OK)
  15.   {
  16.     for (num = 0; num < 2; num++)
  17.     {
  18.       money[num] = g_ucTempbuf[1 - num];//存储芯片寄存器读出来的内容,并且调换高低位(因为存储的时候,按照低位在前的顺序)
  19.     }
  20.     itoa(money[0], temp1, 16);       //十六进制数值转十六进制字符串(字符串无法进行计算)
  21.     itoa(money[1], temp2, 16);       //十六进制数值转十六进制字符串(字符串无法进行计算)
  22.     strcat(temp1, temp2);            //将两个char类型连接。输出temp1=temp1temp2
  23.     inteDec = str_dec(temp1);        //余额整数 十六进制字符串转十进制数
  24.     temp1[0] = '\0';                 // 字符常量占一个字节的内存空间
  25.     temp2[0] = '\0';                 // 字符常量占一个字节的内存空间
  26.     memset(money, 0, sizeof(money)); //将money中当前位置后面清零 。
  27.     sum = inputnum + inteDec; //充值后余额整数部分之和
  28.     re = sum;
  29.     Int_char(re);            //十进制转字符串
  30.     led();                   //led灯亮
  31.     LCD_clear();             //清屏
  32.     LCD_Desk2();             //lcd显示正在充值
  33.     while (Result[i] != '\0')
  34.     {
  35.      LCD_write_str(Result); //lcd显示10进制字符串
  36.      i++;
  37.     }
  38.     delay_ms(1800);
  39.   }
  40.     if(sum<65536)              //将充值完毕的余额总数再次存储到寄存器内。
  41.   {
  42.     itoa(sum,money_inch_hex,16);     //10进制数值转为16进制字符串,整数部分
  43.     i=strlen(money_inch_hex);
  44.     switch(i)
  45.     {
  46.     case 0:
  47.       for(num=0;num<4;num++)
  48.       {
  49.         money_inch_hex[num]='0';
  50.       }
  51.       money_inch_hex[4]='\0';
  52.       break;
  53.     case 1:
  54.       money_inch_hex[4]='\0';
  55.       money_inch_hex[3]=money_inch_hex[0];
  56.       money_inch_hex[2]='0';
  57.       money_inch_hex[1]='0';
  58.       money_inch_hex[0]='0';
  59.       break;
  60.     case 2:
  61.       money_inch_hex[4]='\0';
  62.       money_inch_hex[3]=money_inch_hex[1];
  63.       money_inch_hex[2]=money_inch_hex[0];
  64.       money_inch_hex[1]='0';
  65.       money_inch_hex[0]='0';
  66.       break;
  67.     case 3:
  68.       money_inch_hex[4]='\0';
  69.       money_inch_hex[3]=money_inch_hex[2];
  70.       money_inch_hex[2]=money_inch_hex[1];
  71.       money_inch_hex[1]=money_inch_hex[0];
  72.       money_inch_hex[0]='0';
  73.       break;
  74.     }
  75.     StringToHex(money_i, money_inch_hex);   //16进制字符串转为16进制字节数组
  76.     for(num=0;num<2;num++)         //置高位在前
  77.     {
  78.       money_ok[num]=money_i[1-num];
  79.     }
  80.   }

  81.     return status2;  //返回判断值
复制代码
函数功能基本实现,因为是实现充值功能,所以为了防止连续多次充值,在主函数最后设置了break环节。
在实际操作过程中,在刷卡充值的时候,不能过早的移开卡片,否则会导致充卡失败。

0.png

全部资料51hei下载地址:
4.公交卡充值功能实现.rar (90.19 KB, 下载次数: 31)

评分

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

查看全部评分

回复

使用道具 举报

ID:594608 发表于 2019-9-23 15:01 | 显示全部楼层
讲述的不够仔细,如果有什么问题,欢迎前来讨论,也希望能发现更好的程序,因为是初学者,我这个程序实际运行会有一些问题。
例如汉字显示偶尔出现问题
偶尔出现闪屏
刷卡周期过长
如果有更佳的程序,希望你也会和我分享
请联系我的QQ

欢迎讨论!
回复

使用道具 举报

ID:594608 发表于 2019-9-23 15:02 | 显示全部楼层
待会还会更新一个扣费模块的,主要是希望实现连续扣费
回复

使用道具 举报

ID:429156 发表于 2019-9-26 14:36 | 显示全部楼层
公交卡充值是不是数据有加密保护,不然别人搞个同样的机器也能冲
回复

使用道具 举报

ID:594608 发表于 2019-9-26 16:54 | 显示全部楼层
xiaomi_51hei 发表于 2019-9-26 14:36
公交卡充值是不是数据有加密保护,不然别人搞个同样的机器也能冲

是的,我猜测是可以修改卡片内的密码在和充值机器密码校验。刚刚学习单片机,有许多不完善的地方
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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