|
本設(shè)計包括兩個終端,包括負(fù)責(zé)水卡充值(可選擇金額)的充值終端和每次刷卡扣費(fèi)兩元的付費(fèi)終端。制作成品時建議兩個終端做在一塊板子上,用跳帽切換兩個51單片機(jī)的電源。
主控芯片51單片機(jī)
射頻模塊RC522
射頻卡M1卡S50
以下是付費(fèi)終端的程序,其他詳見附件
- #include "reg52.h"
- #include "main.h"
- #include "mfrc522.h"
- #include<intrins.h> //函數(shù)處理頭文件
- #include<string.h> //字符串處理頭文件
- #include<stdio.h> // 輸入輸出函數(shù)頭文件
- unsigned char code data1[16] = {0x00,0x00,0x00,0x00,0xff,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x01,0xFE,0x01,0xFE};
- //M1卡的某一塊寫為如下格式,則該塊為錢包,可接收扣款和充值命令
- //4字節(jié)金額(低字節(jié)在前)+4字節(jié)金額取反+4字節(jié)金額+1字節(jié)塊地址+1字節(jié)塊地址取反+1字節(jié)塊地址+1字節(jié)塊地址取反
- 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聲音提示標(biāo)志
- void main( )
- {
- unsigned char status;
- InitializeSystem( ); //初始化
- PcdReset(); //復(fù)位RC522
- PcdAntennaOff(); //關(guān)閉天線
- PcdAntennaOn(); //開啟天線
- data2[1]=a/256;
- data2[0]=a%256;
- while ( 1 )
- {
- status = PcdRequest(PICC_REQALL, g_ucTempbuf); //返回卡片類型#define PICC_REQIDL 0x26 尋天線區(qū)內(nèi)未進(jìn)入休眠狀態(tài)
- 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字節(jié)
- if (status == MI_OK)
- {
- status = PcdSelect(g_ucTempbuf); //選定卡片 ,輸入卡片ID號
- if (status == MI_OK)
- {
- if(falg_pro==0)//聲音提示標(biāo)志
- {
- 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();//命令卡片進(jìn)入休眠狀態(tài)
- }
- }
- /////////////////////////////////////////////////////////////////////
- //系統(tǒng)初始化
- /////////////////////////////////////////////////////////////////////
- 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_();
- }
- ////////////////////////顯示處理函數(shù)////////////////////////////////
- bit lcd_bz() // 測試LCD忙碌狀態(tài)
- {
- 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)// 寫入指令數(shù)據(jù)到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)
- { //設(shè)定顯示位置
- lcd_wcmd(pos | 0x80);
- return 0;
- }
- lcd_wdat(unsigned char dat)
- { //寫入字符顯示數(shù)據(jù)到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初始化設(shè)定
- {
- lcd_wcmd(0x38); //
- Delay(1);
- lcd_wcmd(0x0c); //
- Delay(1);
- lcd_wcmd(0x06); //
- Delay(1);
- lcd_wcmd(0x01); //清除LCD的顯示內(nèi)容
- Delay(1);
- return 0;
- }
- LCD1206()
- {
- unsigned char i;
- lcd_pos(0x01); // 設(shè)置顯示位置為第一行的第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); // 設(shè)置顯示位置為第一行的第5個字符
- lcd_wdat(dis4[0]); //dis4[] = {"ID:"};
- lcd_wdat(dis4[1]);
- lcd_wdat(dis4[2]);
- lcd_pos(0x08); // 設(shè)置顯示位置為第一行的第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); // 設(shè)置顯示位置為第二行第二個字符
- 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); // 設(shè)置顯示位置為第二行第二個字符
- 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;//設(shè)置定時器0為工作方式1
- TH0=(65536-50000)/256;//給定時器裝初值 高八位
- TL0=(65536-50000)%256;//給定時器裝初值 低八位
- EA=1; //開總中斷
- ET0=1; //開定時器0中斷
- TR0=1; //啟動定時器0
- }
- void time0() interrupt 1// 中斷服務(wù)子程序 聲音時間一致
- {
- TH0=(65536-50000)/256;//給定時器裝初值 高八位
- TL0=(65536-50000)%256;//給定時器裝初值 低八位
- tt++;
- if(tt==3)
- {
- tt=0;
- fmq=1;
- EA=0; //關(guān)總中斷
- ET0=0; //關(guān)定時器0中斷
- TR0=0; //關(guān)定時器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”的數(shù)據(jù),返回值存在 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”目標(biāo)地址
- 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字節(jié)金額(低字節(jié)在前)+4字節(jié)金額取反+4字節(jié)金額+1字節(jié)塊地址+1字節(jié)塊地址取反+1字節(jié)塊地址+1字節(jié)塊地址取反
- if (status == MI_OK)
- {
- pro();
- }
- }
- }
- }
復(fù)制代碼 全部程序51hei下載地址:
注冊程序.rar
(90.98 KB, 下載次數(shù): 84)
2019-8-15 10:47 上傳
點(diǎn)擊文件名下載附件
刷卡程序.rar
(88.79 KB, 下載次數(shù): 106)
2019-8-15 10:47 上傳
點(diǎn)擊文件名下載附件
|
評分
-
查看全部評分
|