電路原理圖:
0.jpg (71.81 KB, 下載次數: 156)
下載附件
2018-3-26 03:03 上傳
pcb布線:
0.jpg (84.43 KB, 下載次數: 118)
下載附件
2018-3-26 03:04 上傳
使用說明
一、實現功能:5張卡
1、用戶密碼以及IC卡號和IC卡刷入序列號,保存到STC12C5A60S2的EEPROM中,掉電數據保存功能。
2、支持非接觸式IC卡授權功能,可連續授權(授權需輸入管理員密碼)。
3、支持手動選卡銷卡,支持單卡刷入銷卡,支持注銷所有卡(注銷所有卡需輸入管理員密碼)
4、自動識別非接觸式IC卡功能。如刷授權過的IC卡,提示“歡迎光臨”,顯示卡號并且開門,5秒后自動關門。如果刷未授權的IC卡,提示“該卡未授權”,顯示卡號不開門。
5、如忘記攜帶IC卡,可通過鍵盤手動輸入用戶密碼。密碼輸入錯誤顯示器會出現錯誤提示且繼電器不工作(不開門);若密碼輸入正確則繼電器工作(開門)。
6、支持手動更改用戶密碼(更改用戶密碼需輸入管理員密碼)
7、支持無卡時鐘顯示功能(功能:顯示年月日時分秒周,陰歷,天干地支,生肖,溫度,可改時間,具有掉電走時功能)
二、按鍵定義
如圖示:采用4X4鍵盤輸入,鍵盤對應名稱如下:
1 2 3 A
4 5 6 B
7 8 9 C
* 0 # D
其中, 【0—9】為數字鍵,用于輸入相應的密碼,
【*】號鍵為清除所有卡
【A】鍵為返回功能
|->長按A鍵2秒可調時間,此時按下1鍵為選擇修改項,按下2鍵為加,按下3鍵為減,再次長按A鍵退出時間修改。
【B】鍵為授權IC卡功能->提示輸入管理員密碼->輸入管理員密碼->刷入IC卡號->提示授權成功->是否繼續授權->按A鍵返回
【C】鍵為注銷IC卡功能->提示刷入IC卡號->提示注銷成功->按A鍵返回
|->或按下#鍵 手動選擇卡注銷->按D鍵確認并退出
【D】鍵為確認功能
【#】號鍵為手動輸入密碼功能->提示輸入密碼->輸入密碼
|->改密碼->提示輸入管理員密碼->輸入管理員密碼->改用戶密碼->輸入用戶密碼->確認并再次輸入->修改成功
提示:所有的輸密碼和改密碼功能,輸入三次錯誤后則退出輸入或修改功能,輸入或修改失敗。
0.jpg (24.69 KB, 下載次數: 114)
下載附件
2018-3-26 03:02 上傳
單片機源程序如下:
- /*********************************
- 按鍵分布
- 1 2 3 A
- 4 5 6 B
- 7 8 9 C
- * 0 # D
- 其中, 【0—9】為數字鍵,用于輸入相應的密碼,
- 【*】號鍵為清除所有卡
- 【A】鍵為返回功能
- 【B】鍵為授權IC卡功能
- 【C】鍵為注銷IC卡功能
- 【D】鍵為確認功能
- 【#】號鍵為手動輸入密碼功能
- 時鐘功能調時說明:長按A鍵2秒可調時間,此時按下1鍵為選擇修改項,按下2鍵為加,按下3鍵為減,再次長按A鍵退出時間修改
- ********************************************************************************************************/
- #include <stc12c5a60s2.h>
- #include <stdio.h>
- #include "spi.h"
- #include "12864.h"
- #include "eeprom.h"
- #include "mfrc522.h"
- #include "uart.h"
- #include "KEYBOARD.h"
- #include "clock.h"
- #include "ds1302.h"
- #define IAP_ADDRESS1 0x0100 //用戶密碼起始地址
- #define IAP_ADDRESS 0x0200 //IC卡序列號起始地址
- uchar code administer_key[]={0,0,0,};//管理員卡密碼
- static uchar xdata IC_EEPROM[5][5];//存入EEPROM密碼 每行前4位為卡號 第5位為卡片輸入順序號
- static uchar xdata User_len; //用戶密碼長度
- static uchar xdata Userpassword[16];//用戶密碼
- static uchar xdata ICCODE[4];//返回卡號4位
- static uchar xdata Rec_Buffer[REC_BUFFER_SIZE];//串口接收緩沖區
- static uchar xdata RELAY_NUM=0;//開門計時變量
- static uchar xdata IC_NUM=0;//刷入卡的順序
- static uchar Recvd_Count;//串口已接收數據的個數
- bit lock_ok=0;//密碼匹配標記
- bit shouquan_flag=0;//授權標記
- bit shoudongshuru_flag=0; //手動輸入密碼標記
- bit IC_flag=0; //尋卡標記
- //bit shanshuo;//較表時閃爍用
- void io_init()
- {
- //P0M1=0XFF;//開漏模式
- //P0M0=0XFF;
- P1M1=0XFF;//P1.7-P1.3開漏模式用于RC522;
- P1M0=0XFF;
- P2M1=0X00;//P2.7,P2.0推挽輸出模式
- P2M0=0X81;
- //P3M1=0X00;
- //P3M0=0XFF;
- P4SW=0x70;
- P4M1=0X00;//推挽模式
- P4M0=0XFF;
- }
- /****************************************************
- 函數名稱:bit Auto_Reader(void)
- 入口參數:無
- 出口參數:有卡返回0,無卡返回1
- 功能:尋卡
- 尋卡并在液晶屏上顯示序列號
- ****************************************************/
- bit Auto_Reader(void)
- {
- uchar temp[4];
- // uchar g_ucTempbuf1[16];
- // uchar code DefaultKey[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //初始密碼
- uchar i;
- uchar ID_ASC[8];
- if (MI_OK==PcdRequest(PICC_REQALL,temp))//尋卡,輸出為卡類型//*PICC_REQALL=0x52:尋天線區內所有符合14443A標準的卡 PICC_REQIDL=0x26:只尋未進入休眠狀態的卡
- {
- if (MI_OK==PcdAnticoll(temp))//防沖撞處理,輸出卡片序列號,4字節
- if (MI_OK==PcdSelect(temp)) //選擇卡片,輸入卡片序列號,4字節
- //if (MI_OK==PcdAuthState(PICC_AUTHENT1A, 1, DefaultKey, temp)) //驗證密碼 輸出卡片序列號
- //if(MI_OK==PcdRead(0, g_ucTempbuf1))//卡中第一塊數據內容
- {
- IC_flag=1;
- lcd_clear();
- display_GB2312_string(3,1,"IC序列號:");
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- { ICCODE[i]=temp[i];
- if(temp[i]/16>9) ID_ASC[i*2]=temp[i]/16+'7';
- else ID_ASC[i*2]=temp[i]/16+'0';
- if(temp[i]%16>9) ID_ASC[i*2+1]=temp[i]%16+'7';
- else ID_ASC[i*2+1]=temp[i]%16+'0';
- }
- display_GB2312_string(5,1,ID_ASC);
- }
- return 0;
- }
- else
- {
- BELL=0;return 1;
- }
- }
- /****************************************************
- 函數名稱:bit administer(void)
- 入口參數:無
- 出口參數:密碼正確返回0,錯誤返回1
- 全局變量shouquan_flag :允許授權shouquan_flag=0; 不允許授權shouquan_flag=1;
- 功能:管理員
- 驗證系統密碼 用于授權管理、注銷全部卡管理、修改用戶密碼,三次輸入錯誤返回
- 調用函數:EEPROM.C 12864.c KeyPro(); bit Auto_Reader(void);
- ****************************************************/
- bit administer(void)
- {
- uchar asterisk='*';
- uchar spacing =' ';
- uchar temp=0,error=0,j=0,num=0,i=0,k=0;//
- bit Flag; //比較位置
- unsigned char passwordlength,PLEN; //輸入密碼長度,實際密碼長度
- unsigned char passwordtemp[16]; //最大輸入16個
- PLEN=sizeof(administer_key)/sizeof(administer_key[0]);//用于計算出實際密碼長度
- display_GB2312_string(1,1,"請輸入管理員密碼");
- while(shouquan_flag==1)
- {
- temp=KeyPro();
- if(temp!=0xff)
- {
- if(i==0) //輸入是第一個字符的時候需要把改行清空,方便觀看密碼
- display_GB2312_string(3,1," ");//清除該行
- if((i<16)&&(temp<=9))
- {
- passwordtemp[i]=temp;
- display_GB2312_string(3,i*8+1,&asterisk);//輸入的密碼用"*"代替
- i++; //輸入數值累加
- }
- if('*'==temp&&i>0)
- {
- i--;
- for(k=i;k<16;k++)
- display_GB2312_string(3,k*8,&spacing);//輸入用空格代替
- }
- if('A'==temp)//退出
- {
- display_GB2312_string(3,1," ");//清除該行
- shouquan_flag=1;
- return 0;
- }
- if(('D'==temp)|| (i==16))//輸入按鍵值D或者密碼輸入到最大值16,表示輸入結束,需要進行比對
- {
- passwordlength=i; //計算輸入密碼長度
- i=0; //計數器復位
- if(passwordlength==PLEN)//長度相等則比較,否則直接輸出錯誤
- {
- Flag=1;//先把比較位置1
-
- for(j=0;j<PLEN;j++)//循環比較8個數值,如果有一個不等 則最終Flag值為0
- Flag=Flag&&(passwordtemp[j]==administer_key[j]);//比較輸入值和已有密碼
- }
- if(Flag)//如果比較全部相同,標志位置1
- {
- pass();
- lcd_clear();
- error=0;//輸入正確則次數清零,重新計數
- Flag=0; //清除正確標志
- shouquan_flag=0;
- return 0;
- }
- else
- {
- display_GB2312_string(3,1," ");//清除該行
- display_GB2312_string(3,1,"Wrong! Retry!");//密碼錯誤,提示重新輸入
- error++;//連續輸入錯誤,則次數累加
- if(error==3)
- {
- display_GB2312_string(3,1," ");//清除該行
- display_GB2312_string(3,1,"Wrong 3 times!");//密碼錯誤,提示重新輸入
- delayms(1500);
- shouquan_flag=1;
- return 0;
- //while(1);//停止該位置,重啟電源后才能輸入,實際實用中則需要等到一定時間后才能再次輸入。
- }
- }
- }
- }
- }
- }
- /****************************************************
- 函數名稱:void shouquan(uchar key)
- 入口參數:key->按鍵值
- 出口參數:無
- 功能:授權
- 按下B鍵進入授權
- 流程->提示輸入系統密碼->輸入系統密碼->刷入IC卡號->提示是否繼續授權->按A鍵返回 (授權期間均可按A鍵返回)
- 調用函數:EEPROM.C 12864.c KeyPro(); bit administer(); bit Auto_Reader(void);
- ****************************************************/
- void shouquan(uchar key)
- {
- uchar j=0,k=0,flag,flag1;
- if(key=='B')//授權檢測
- {
- lcd_clear();
- //Sent_Byte(IC_NUM);
- shouquan_flag=1;
- while(administer()); //管理員返回0,密碼正確shouquan_flag=0
- display_GB2312_string(1,1,"請刷入授權IC卡號");//密碼正確顯示的信息
- if(IC_EEPROM[4][4]==5&&(shouquan_flag==0))//如果最后一位不是0XFF說明有卡刷入
- {
- display_GB2312_string(1,1,"IC卡超出5張請按C");
- display_GB2312_string(3,1,"IC卡超出5張請按*");
- shouquan_flag=1;
- delayms(2000);
- }
- else if(shouquan_flag==0) //刷卡授權
- {
- flag1=1;
- while(IC_NUM<5&&flag1==1)
- {
- flag=1;
- while(flag) //刷入卡號,正確返回0,退出 并在LCD顯示
- {
- flag=Auto_Reader();
- if('A'==KeyPro())//退出
- {
- flag=1;
- flag1=0;
- break;
- }
- }
- if(flag==0)
- {
- //delayms(1000);
- IC_NUM++;
- for(j=0;j<5;j++)
- {
- if(j<4)IC_EEPROM[IC_NUM-1][j]=ICCODE[j];//卡號
- else IC_EEPROM[IC_NUM-1][j]=IC_NUM;//刷入的順序
- //Sent_Byte(IC_EEPROM[IC_NUM-1][j]);
- }
- IapEraseSector(IAP_ADDRESS);//清除數據
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IapProgramByte(IAP_ADDRESS+j*5+k,IC_EEPROM[j][k]);//寫入數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- pass();
- if(IC_NUM<5)
- {
- delayms(1000);
- lcd_clear();
- display_GB2312_string(1,1,"IC卡授權成功 ");
- display_GB2312_string(3,1,"是否繼續刷入 ");
- display_GB2312_string(5,1,"繼續請刷卡 ");
- display_GB2312_string(7,1,"停止請按’A‘鍵 ");
- }
- else
- {
- delayms(1000);
- lcd_clear();
- display_GB2312_string(1,1,"IC卡存儲到5張 ");
- delayms(2000);
- }
- }
- }
- }
- }
- }
- /****************************************************
- 函數名稱:void zhuxiao_all(uchar key)
- 入口參數:key->按鍵值
- 出口參數:無
- 功能:注銷所有IC卡
- 按下*鍵為注銷IC卡功能->提示輸入系統密碼->輸入系統密碼->確定注銷全部卡->注銷成功->自動返回 (注銷期間均可按A鍵返回)
- 調用函數:EEPROM.C 12864.c KeyPro(); administer();
- ****************************************************/
- void zhuxiao_all(uchar key)
- {
- uchar j,k;
- if(key=='*')
- {
- lcd_clear();
- shouquan_flag=1;
- while(administer()); //管理員返回0,密碼正確shouquan_flag=0
- key=0xff;
- while(key!='*'&&shouquan_flag==0)
- {
- if(key=='A') break;
- key=KeyPro();
- display_GB2312_string(1,1,"是否注銷所有IC卡");
- display_GB2312_string(3,1,"確定請按'*'號鍵");
- }
- if(shouquan_flag==0&&key=='*')
- { lcd_clear();
- IC_NUM=0;
- pass();
- display_GB2312_string(1,1,"注銷所有IC卡 ");
- delayms(1000);
- IapEraseSector(IAP_ADDRESS);//清除數據
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//4列
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*4+k);//讀出數據
- display_GB2312_string(1,1,"注銷成功 ");
- delayms(1000);
- }
- }
- }
- /****************************************************
- 函數名稱:void shoudong_zhuxiao_one(uchar key)
- 入口參數:key->按鍵值
- 出口參數:無
- 功能:手動注銷單張IC卡
- 按#號鍵手動銷卡
- 流程->提示按下對應刷入的卡順序號->按下1-5按鍵選擇對應卡->提示確認注銷按相應按鍵->按D鍵確認并返回 (期間按A鍵不可退出手動銷卡模式)
- 調用函數:EEPROM.C 12864.c KeyPro();
- ****************************************************/
- void shoudong_zhuxiao_one(uchar key)
- {
- uchar key2,j,k,v,i;
- uchar ID_ASC[9]={1,1,};
- if(key=='#')
- {
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- lcd_clear();
- key2=0xff;
- display_GB2312_string(1,1,"按對應順序號銷卡");
- while(key2!='D')//確認
- {
- display_GB2312_string(3,1,"確認并退出請按D");
- key2=KeyPro();
- if(key2==1)
- {
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- {
- if(IC_EEPROM[0][i]/16>9) ID_ASC[i*2]=IC_EEPROM[0][i]/16+'7';
- else ID_ASC[i*2]=IC_EEPROM[0][i]/16+'0';
- if(IC_EEPROM[0][i]%16>9) ID_ASC[i*2+1]=IC_EEPROM[0][i]%16+'7';
- else ID_ASC[i*2+1]=IC_EEPROM[0][i]%16+'0';
- }
- //Sent_Buffer(ID_ASC,8);
- display_GB2312_string(5,1,ID_ASC);
- display_GB2312_string(7,1,"注銷按1,返回按A ");
- key2=0xff;
- while(key2!=1)
- {
- key2=KeyPro();
- if(key2=='A')break;//退出
- }
- pass();
- if(key2==1)for(j=0;j<5;j++)IC_EEPROM[0][j]=0xff;
- }
- else if(key2==2)
- {
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- {
- if(IC_EEPROM[1][i]/16>9) ID_ASC[i*2]=IC_EEPROM[1][i]/16+'7';
- else ID_ASC[i*2]=IC_EEPROM[1][i]/16+'0';
- if(IC_EEPROM[1][i]%16>9) ID_ASC[i*2+1]=IC_EEPROM[1][i]%16+'7';
- else ID_ASC[i*2+1]=IC_EEPROM[1][i]%16+'0';
- }
- //Sent_Buffer(ID_ASC,8);
- display_GB2312_string(5,1,ID_ASC);
- display_GB2312_string(7,1,"注銷按2,返回按A ");
- key2=0xff;
- while(key2!=2)
- {
- key2=KeyPro();
- if(key2=='A')break;//退出
- }
- pass();
- if(key2==2)for(j=0;j<5;j++)IC_EEPROM[1][j]=0xff;
- }
- else if(key2==3)
- {
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- {
- if(IC_EEPROM[2][i]/16>9) ID_ASC[i*2]=IC_EEPROM[2][i]/16+'7';
- else ID_ASC[i*2]=IC_EEPROM[2][i]/16+'0';
- if(IC_EEPROM[2][i]%16>9) ID_ASC[i*2+1]=IC_EEPROM[2][i]%16+'7';
- else ID_ASC[i*2+1]=IC_EEPROM[2][i]%16+'0';
- }
- //Sent_Buffer(ID_ASC,8);
- display_GB2312_string(5,1,ID_ASC);
- display_GB2312_string(7,1,"注銷按3,返回按A ");
- key2=0xff;
- while(key2!=3)
- {
- key2=KeyPro();
- if(key2=='A')break;//退出
- }
- pass();
- if(key2==3)for(j=0;j<5;j++)IC_EEPROM[2][j]=0xff;
- }
- else if(key2==4)
- {
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- {
- if(IC_EEPROM[3][i]/16>9) ID_ASC[i*2]=IC_EEPROM[3][i]/16+'7';
- else ID_ASC[i*2]=IC_EEPROM[3][i]/16+'0';
- if(IC_EEPROM[3][i]%16>9) ID_ASC[i*2+1]=IC_EEPROM[3][i]%16+'7';
- else ID_ASC[i*2+1]=IC_EEPROM[3][i]%16+'0';
- }
- //Sent_Buffer(ID_ASC,8);
- display_GB2312_string(5,1,ID_ASC);
- display_GB2312_string(7,1,"注銷按4,返回按A ");
- key2=0xff;
- while(key2!=4)
- {
- key2=KeyPro();
- if(key2=='A')break;//退出
- }
- pass();
- if(key2==4)for(j=0;j<5;j++)IC_EEPROM[3][j]=0xff;
- }
- else if(key2==5)
- {
- for(i=0;i<4;i++) //卡ID號轉化成ASCII
- {
- if(IC_EEPROM[4][i]/16>9) ID_ASC[i*2]=IC_EEPROM[4][i]/16+'7';
- else ID_ASC[i*2]=IC_EEPROM[4][i]/16+'0';
- if(IC_EEPROM[4][i]%16>9) ID_ASC[i*2+1]=IC_EEPROM[4][i]%16+'7';
- else ID_ASC[i*2+1]=IC_EEPROM[1][i]%16+'0';
- }
- //Sent_Buffer(ID_ASC,8);
- display_GB2312_string(5,1,ID_ASC);
- display_GB2312_string(7,1,"注銷按5,返回按A ");
- key2=0xff;
- while(key2!=5)
- {
- key2=KeyPro();
- if(key2=='A')break;//退出
- }
- pass();
- if(key2==5)for(j=0;j<5;j++)IC_EEPROM[4][j]=0xff;
- }
- display_GB2312_string(5,1," ");
- display_GB2312_string(7,1," ");
- }
- for(v=0,j=0;j<5;j++)//得到刷入的卡順序號
- {
- if(0xff!=IC_EEPROM[j][4])
- {
- for(k=0;k<5;k++)
- {
- IC_EEPROM[v][k]=IC_EEPROM[j][k];//重新排列卡號
- //Sent_Byte(IC_EEPROM[v][k]);
- }
- v++;
- }
- }
- IC_NUM=v;//Sent_Byte(IC_NUM);
- for(j=0;j<5;j++)
- for(k=0;k<5;k++)
- {
- if(j>=IC_NUM)IC_EEPROM[j][k]=0XFF;
- else IC_EEPROM[j][4]=j+1;
- }
- IapEraseSector(IAP_ADDRESS);//清除數據
- delayms(10);
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IapProgramByte(IAP_ADDRESS+j*5+k,IC_EEPROM[j][k]);//寫入數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- delayms(10);
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出卡數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- pass();
- }
- }
- /****************************************************
- 函數名稱:void zhuxiao_one(uchar key)
- 入口參數:key->按鍵值
- 出口參數:無
- 功能:持卡或手動注銷單張IC卡
- 按下C鍵進入持卡或手動注銷單張IC卡
- 調用函數:EEPROM.C 12864.c KeyPro(); shoudong_zhuxiao_one();
- ****************************************************/
- void zhuxiao_one(uchar key)
- {
- uchar i,j,k,ok,flag,m=0,key1;
- if(key=='C')
- {
- // while(administer()); //管理員返回0,密碼正確shouquan_flag=0
- lcd_clear();
- display_GB2312_string(1,1," 刷入注銷卡 ");
- display_GB2312_string(3,1,"或按#鍵手動注銷 ");
- flag=1;
- key1=0xff;
- while(flag==1&&key1!='A'&&key1!='#') //刷入卡號,正確返回0,退出 并在LCD顯示
- {
- flag=Auto_Reader();
- key1=KeyPro();
- if('A'==key1&&key1=='#')//退出
- {
- flag=1;
- break;
- }
- }
- if(key1=='#')
- {
- shoudong_zhuxiao_one(key1);
- key1=0xff;
- }
- if(flag==0)//刷卡標記
- {
- //IC_flag=0;
- for(j=0;j<5;j++)//5行///比較刷入的是哪張卡
- {
- ok=1;
- for(k=0;k<4;k++)//4列
- {
- ok=ok&&(IC_EEPROM[j][k]==ICCODE[k]);
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- if(ok==1)
- {
- ok=0;
- m=IC_EEPROM[j][4]+0X30;
- display_GB2312_string(7,1,"注銷卡序列號: ");
- display_GB2312_string(7,105,&m);
- pass();
- delayms(1000);
- m=IC_EEPROM[j][4];
- //Sent_Byte(n);
- break;
- //goto addr1;
- }
- }
- //addr1:
- if(ok==0) //重新排列對齊數據
- {
- ok=1;
- i=0;
- //Sent_Byte(n);
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- if(m==5)//如果是最后一張卡直接替換最后一個數據 前4個不用移位
- for(j=0;j<5;j++)
- IC_EEPROM[4][j]=0xff;//最后一個數據補oxff
- else //不是最后一個卡 則進行數據移位
- {
- for(j=0;j<5;j++)//得到刷入的卡順序號
- {
- if(m==IC_EEPROM[j][4])i+=1;
- for(k=0;k<5;k++)
- {
- IC_EEPROM[j][k]=IC_EEPROM[i][k];//重新排列卡號
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- i++;
- }
- for(j=0;j<5;j++)IC_EEPROM[4][j]=0xff;//最后一個數據補oxff
- ok=1;
- for(j=0;j<5;j++)
- {
- ok=1;
- for(k=0;k<4;k++)
- ok=ok&&(IC_EEPROM[j][k]==0xff);
- if(ok==1) IC_NUM=IC_EEPROM[j][4]=0xff;//無數據的存儲地址卡序號初始為0xff
- else IC_NUM=IC_EEPROM[j][4]=j+1;
- }
- }
- IapEraseSector(IAP_ADDRESS);//清除數據
- delayms(10);
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IapProgramByte(IAP_ADDRESS+j*5+k,IC_EEPROM[j][k]);//寫入數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- delayms(10);
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//5列
- {
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出卡數據
- //Sent_Byte(IC_EEPROM[j][k]);
- }
- for(j=0;j<5;j++)
- if(IC_EEPROM[j][4]!=0xff) IC_NUM=IC_EEPROM[j][4];//讀出卡刷入順序
- if(IC_NUM==0xff)IC_NUM=0;
- //Sent_Byte(IC_NUM);
- }
- }
- }
- }
- /****************************************************
- 函數名稱:bit shudongshuru(uchar key)
- 入口參數:key->按鍵值
- 出口參數:正確返回0,錯誤返回1
- 功能:手動輸入用戶密碼、可改用戶密碼
- 按#鍵手動輸入密碼 *鍵后退清除一位 D鍵確定 A鍵退出 改用戶密碼時按B鍵授權后 方可更改
- 調用函數:EEPROM.C 12864.c KeyPro();
- ***************************************************/
- bit shudongshuru(uchar key)
- {
- uchar asteris='*';
- uchar spacin =' ';
- uchar key2=0,error=0,j=0,num=0,i=0,k=0,n=0;
- bit Flag; //比較相等標記
- unsigned char passwordlength; //輸入密碼長度,實際密碼長度
- unsigned char passwordtemp[16]; //最大輸入16個
- unsigned char passwordlast[16];
- if(key=='#')
- {
- lcd_clear();
- display_GB2312_string(1,1," 請輸入密碼 ");
- display_GB2312_string(3,1,"或按B授權改密碼 ");
- shoudongshuru_flag=1;
- while(shoudongshuru_flag==1)
- {
- key2=KeyPro();
- if(key2=='A') return 1;
- if(key2!=0xff)
- {
- if(i==0) //輸入是第一個字符的時候需要把改行清空,方便觀看密碼
- display_GB2312_string(5,1," ");//清除該行
- if((i<16)&&(key2<=9))
- {
- passwordtemp[i]=key2;
- // Sent_Byte(key2);
- //display_graphic_5x7(5,i*8+1,xing);//輸入的密碼用"*"代替
- display_GB2312_string(5,i*8+1,&asteris);//輸入的密碼用"*"代替
- i++; //輸入數值累加
- }
- if('*'==key2&&i>0)
- {
- i--;
- for(k=i;k<16;k++)
- display_GB2312_string(5,k*8,&spacin);//輸入用空格代替
- }
- if('A'==key2)//退出
- {
- lcd_clear();
- shoudongshuru_flag=0;
- return 0;
- }
- if(('D'==key2)|| (i==16))//輸入按鍵值15或者密碼輸入到最大值16,表示輸入結束,需要進行比對
- {
- passwordlength=i; //計算輸入密碼長度
- if(passwordlength==User_len)//長度相等則比較,否則直接輸出錯誤
- {
- Flag=1;//先把比較位置1
- for(j=0;j<User_len;j++)//循環比較數值,如果有一個不等 則最終Flag值為0
- {
- Flag=Flag&&(passwordtemp[j]==Userpassword[j]);//比較輸入值和已有密碼
- }
- }
- i=0; //計數器復位
- if(Flag)//如果比較全部相同,標志位置1
- {
- pass();
- display_GB2312_string(5,1," ");//清除該行
- TR0=1;
- RELAY=0;
- error=0;//輸入正確則次數清零,重新計數
- Flag=0; //清除正確標志
- shoudongshuru_flag=1;
- return 0;
- }
- else
- {
- display_GB2312_string(5,1," ");//清除該行
- display_GB2312_string(5,1,"Wrong! Retry! ");//密碼錯誤,提示重新輸入
- error++;//連續輸入錯誤,則次數累加
- if(error==3)
- {
- error=0;
- lcd_clear();
- display_GB2312_string(5,1,"禁止入內 ");//密碼錯誤,提示重新輸入
- delayms(1500);
- shoudongshuru_flag=0;
- return 1;
- }
- }
- }
- if(key2=='B') //授權修改用戶密碼
- {
- shouquan_flag=1;
- lcd_clear();
- while(administer()) //管理員返回0,密碼正確shouquan_flag=0
- {
- if(KeyPro()=='A')
- {
- shoudongshuru_flag=0;
- return 1;
- }
- }
- if(shouquan_flag==0)display_GB2312_string(1,1," 請輸入新密碼 ");//管理員密碼正確后的提示
- if(shouquan_flag==1)//管理員密碼錯誤,或退出管理員時的提示
- {
- display_GB2312_string(1,1," 請輸入密碼 ");
- display_GB2312_string(3,1,"或按B授權改密碼 ");
- }
- num=0;//輸入次數計數清零
- n=0; //輸入密碼長度計數清零
- while(shouquan_flag==0)//管理員密碼正確進入密碼修改
- {
- key2=KeyPro();
- if(key2=='A')return 1;
- if(key2!=0xff)
- {
- if(n==0&&num==0)//第一次輸入并且是第一位密碼
- {
- display_GB2312_string(1,1," 請輸入新密碼 ");
- display_GB2312_string(3,1," ");
- }
- if((n<16)&&(key2<=9))//按鍵為1-9 且密碼長度小于16位
- {
- passwordtemp[n]=key2;
- Sent_Byte(key2);
- display_GB2312_string(3,n*8+1,&asteris);//輸入的密碼用"*"代替
- n++; //輸入數值累加
- }
- if('*'==key2&&n>0)//清除、后退一位
- {
- n--;
- for(k=n;k<16;k++)
- display_GB2312_string(3,k*8,&spacin);//輸入用空格代替
- }
- if(('D'==key2)||(n==16))//輸入按鍵值D或者密碼輸入到最大值16,表示輸入結束,需要進行比對
- {
- if(num==0) //第一次輸入密碼
- {
- passwordlength=n; //計算輸入密碼長度
- for(n=0;n<passwordlength;n++)//暫時存儲
- {
- passwordlast[n]=passwordtemp[n];//轉存密碼
- passwordtemp[n]=0;//清空當前
- }
- n=0;//計數器復位
- display_GB2312_string(1,1," 請再次輸入密碼 ");
- display_GB2312_string(3,1," ");//清除
- num++;
- }
- else if(passwordlength==n&&num==1)//第二次輸入密碼 長度相等則比較,否則直接輸出錯誤
- {
- Flag=1;//先把比較位置1
- for(j=0;j<passwordlength;j++)//循環比較數值,如果有一個不等 則最終Flag值為0
- Flag=Flag&&(passwordlast[j]==passwordtemp[j]);//比較上次輸入值和現在密碼是否一樣
- if(Flag==1)
- {
- //pass();
- num=0;
- shouquan_flag=0;
- IapEraseSector(IAP_ADDRESS1); //清除
- delayms(10);
- IapProgramByte(IAP_ADDRESS1,n);//寫入密碼個數
- for(n=1;n<=passwordlength;n++)//存儲
- {
- IapProgramByte(IAP_ADDRESS1+n,passwordtemp[n-1]);//寫入密碼
- Sent_Byte(passwordtemp[n-1]);
- }
- delayms(10);
- User_len=IapReadByte(IAP_ADDRESS1);//讀取密碼個數
- Sent_Byte(User_len);
- for(n=1;n<=User_len;n++)
- {
- Userpassword[n-1]=IapReadByte(IAP_ADDRESS1+n); //讀取 密碼
- Sent_Byte(Userpassword[n-1]);
- }
- n=0;
- display_GB2312_string(1,1," 修改密碼成功 ");
- delayms(1500);
- num=0;
- return 0;
- }
- else if(Flag==0)
- {
- display_GB2312_string(3,1," 請重新輸入 ");//清除
- display_GB2312_string(1,1," 兩次輸入不同 ");//清除該行
- num=0;
- n=0;
- error++;//連續輸入錯誤,則次數累加
- if(error==3)
- {
- display_GB2312_string(3,1," ");//清除
- display_GB2312_string(1,1,"錯誤3次,修改失敗");//密碼錯誤,返回界面
- delayms(1500);
- shouquan_flag=1;
- return 1;
- //while(1);//停止該位置,重啟電源后才能輸入,實際實用中則需要等到一定時間后才能再次輸入。
- }
- }
- }
- else if(num==1)
- {
- display_GB2312_string(3,1," 請重新輸入 ");//清除
- display_GB2312_string(1,1," 兩次輸入不同 ");//清除該行
- num=0;
- n=0;
- error++;//連續輸入錯誤,則次數累加
- if(error==3)
- {
- display_GB2312_string(3,1," ");//清除
- display_GB2312_string(1,1,"錯誤3次,修改失敗");//密碼錯誤,返回界面
- delayms(1500);
- shouquan_flag=1;
- return 1;
- //while(1);//停止該位置,重啟電源后才能輸入,實際實用中則需要等到一定時間后才能再次輸入。
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
- /****************************************************
- 函數名稱:Timer0Init(void)
- 入口參數:無
- 出口參數:無
- 功能: 用于定時關閉門
- 調用函數:無
- ****************************************************/
- void Timer0Init(void) //50毫秒@11.0592MHz
- {
- AUXR &= 0x7F; //定時器時鐘12T模式
- TMOD &= 0xF0; //設置定時器模式
- TMOD |= 0x01; //設置定時器模式
- TL0 = 0x00; //設置定時初值
- TH0 = 0x4C; //設置定時初值
- TF0 = 0; //清除TF0標志
- ET0 = 1; //允許定時器0中斷
- TR0 = 0; //定時器0開始計時
- }
- void Timer1Init(void) //50毫秒@11.0592MHz
- {
- AUXR &= 0xBF; //定時器時鐘12T模式
- TMOD &= 0x0F; //設置定時器模式
- TMOD |= 0x10; //設置定時器模式
- TL1 = 0x00; //設置定時初值
- TH1 = 0x4C; //設置定時初值
- TF1 = 0; //清除TF1標志
- ET1 = 1; //允許定時器0中斷
- TR1 = 0; //定時器1開始計時
- }
- /****************************************************
- 函數名稱:主函數
- ****************************************************/
- main()
- {
- uchar key,j=0,k=0,n,i,sel=0;
- unsigned long int display_data=0;
- BELL=0;//關閉
- RELAY=1;
- io_init();//初始化引腳
- UART_Init();//初始化UART通訊
- rom_cs=1;
- lcd_init();//初始化液晶屏
- init_spi();//初始化SPI通訊
- Timer0Init();//初始化定時器0關門用
- Timer1Init();//初始化定時器1時鐘閃爍用
- Ds1302_Init();
- EA =1; //單片機中斷允許
- //IapEraseSector(IAP_ADDRESS);//清除數據 卡數據
- //IapEraseSector(IAP_ADDRESS1);//清除數據 用戶密碼
- for(j=0;j<5;j++)//5行
- for(k=0;k<5;k++)//4列
- IC_EEPROM[j][k]=IapReadByte(IAP_ADDRESS+j*5+k);//讀出卡數據
- for(j=0;j<5;j++)
- if(IC_EEPROM[j][4]!=0xff) IC_NUM=IC_EEPROM[j][4];//讀出卡刷入順序
- User_len=IapReadByte(IAP_ADDRESS1);//讀取用戶密碼個數
- //Sent_Byte(User_len);
- if(User_len==0xff)User_len=6;//初始化用戶密碼長度6位
- //Sent_Byte(User_len);
- for(k=1;k<=User_len;k++) //讀取用戶密碼
- {
- i=IapReadByte(IAP_ADDRESS1+k); //讀取用戶密碼
- if(i==0xff)Userpassword[k-1]=0;//初始話用戶密碼為000000
- else Userpassword[k-1]=i;
- }
- // for(j=0;j<6;j++)Sent_Byte(Userpassword[j]);
- PcdReset(); //初始化射頻芯片
- PcdAntennaOff();
- PcdAntennaOn();
- delayms(100);
- PcdReset();//復位芯片,打開天線
- PcdAntennaOff();
- PcdAntennaOn();
- //M500PcdConfigISOType( 'A' );//設置RC632的工作方式
- //Delay_ms(100);
- lcd_clear();
- while(1)
- {
- key=KeyPro();//按鍵檢測
- if(key!=0xff)
- {
- IC:if(key=='#')shudongshuru(key);//手動輸入密碼
- if(key=='C')zhuxiao_one(key);//注銷單張卡 持卡注銷
- if(key=='*')zhuxiao_all(key);//注銷所有卡
- if(key=='B')shouquan(key);//授權卡
- IC_flag=0;
- lcd_clear();
- }
- Auto_Reader();
- if(IC_flag==1)//刷卡標記
- {
- display_GB2312_string(1,1," 歡迎光臨 ! ");
- IC_flag=0;
- //for(n=0;n<4;n++)Sent_Byte(ICCODE[n]);
- for(j=0;j<5;j++)//5行
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
代碼.rar
(197.69 KB, 下載次數: 516)
2018-3-25 14:42 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
RFID.pdf
(626.12 KB, 下載次數: 325)
2018-3-25 14:44 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|