基于stm32的IC卡识别,做的是个门禁系统,用的rc522模块,设别IC卡卡号,判断卡号为管理员还是员工,进行开门操作,用的12v电磁锁,添加了时钟,来分开上班时间和下班时间,以及假日模式,假日模式管理员卡和密码同时正确才可打开门,下班时间管理员就可以打开。最后加了电池,当外部电源断开,电池自动供电,由外部电源电池不供电。
制作出来的实物图如下:
单片机源程序如下:
- #include "delay.h"
- #include "sys.h"
- #include "rc522.h"
- #include "key.h" //矩阵键盘模块
- #include "usart.h"
- #include "string.h"
- #include "suo.h"
- #include "rtc.h"
- #include "oled.h"
- #include "adc.h"
- u8 key;
- extern u8 F8X16[];
- u8 data_out[16];
- unsigned char CT[2];//卡类型
- unsigned char SN[4]; //卡号
- unsigned char RFID[16]; //存放RFID
- unsigned char lxl_bit=0;
- unsigned char card_bit=0;
- unsigned char total=0;
- unsigned char card[30]={153,172,26,163,71,133,84,59,102,94,109,37};
- unsigned char KEY[4];
- unsigned char MI[4]={3,9,1,8};
- u8 status,flags=0,weeks=0,power=0,suo=0;
- u8 xianshi[17]={1,2,3,10,4,5,6,11,7,8,9,12,13,0,14,15,16};
- u8 str[6];
- u8 plen=0;
- u8 s;
- u8 T=100,TT=100;
- /*函数声明*/
- typedef struct
- {
- vu8 hour;
- vu8 min;
- vu8 sec;
- //公历日月年周
- vu16 w_year;
- vu8 w_month;
- vu8 w_date;
- vu8 week;
- }set_calendar_obj;
- set_calendar_obj set_time;
- u8 jiance(void)
- {
- u8 i,j,turns=0,m=0;
- for(i=0;i<50;i++)
- {
- for(j=0;j<4;j++)
- {
- if(SN[j]==card[j+i*4])
- {turns=1;m++;}
- else{m=0; turns=0;}
- }
- if(m==4)break;
- }
- if(turns==1)return i;
- return 255;
-
- }
- u8 panduan()
- {
- u8 i,t=0;
- for(i=0;i<4;i++){
- if(KEY[i]==MI[i])
- t=1;
- else t=0;
- }
- if(t==1)return 1;
- else return 0;
-
- }
- u8 shuru()
- {
- u32 m=0,num=0;
- key=16;
- plen=0;
- LCD_Fill(0x00);
- LCD_Print(20, 16, "请输入密码",TYPE16X16,TYPE8X16);
- while(1)
- {
- key_load();
- //请输入密码
- if(key<16){
- num=0;
- if(key==3){plen--;m/=10;}//删减输入的密码
- else{ plen++;
- m=m*10+xianshi[key];
- LCD_Print(24, 32, " ",TYPE16X16,TYPE8X16);
- KEY[plen-1]=xianshi[key];
- }
- LCD_Print(35, 32, " ",TYPE16X16,TYPE8X16);
- LCD_ShowNum(35,32,m,6,16);
- }//将输入的密码添加到KEY数组
- //显示输入的密码
- if(plen==4) {//达到4位数密码,进行密码对比
- LCD_Fill(0x00);
- if(panduan()==1){LCD_Print(24, 24, "密码正确",TYPE16X16,TYPE8X16);flags=1;}
- else LCD_Print(24, 32, "密码错误",TYPE16X16,TYPE8X16);
- delay_ms(2000);
- break;
- }
- num++;if(num>300)break;
- delay_ms(100);
- key=16;
- }
- LCD_Fill(0x00);
- T=100,TT=100;
- }
- void TIME()
- {
- if(T!=calendar.min)
- {
- LCD_P32x32STR(52,16,640);
- if(calendar.hour>7&&calendar.hour<18)power=1;
- else power=0;
- if(calendar.week==6||calendar.week==0)weeks=1;
- else weeks=0;
- T=calendar.min;
- if(TT!=calendar.w_date)
- {
- LCD_Print(56, 0, "- -",TYPE16X16,TYPE8X16);
- LCD_Print(37, 48, "星期",TYPE16X16,TYPE8X16);
- LCD_ShowNum(24,0,calendar.w_year,4,16);
- LCD_ShowNum(64,0,calendar.w_month,2,16);
- LCD_ShowNum(88,0,calendar.w_date,2,16);
- TT=calendar.w_date;
- switch(calendar.week)
- {
- case 0:
- LCD_Print(69,48,"日",TYPE16X16,TYPE8X16);
- break;
- case 1:
- LCD_Print(69,48,"一",TYPE16X16,TYPE8X16);
- break;
- case 2:
- LCD_Print(69,48,"二",TYPE16X16,TYPE8X16);
- break;
- case 3:
- LCD_Print(69,48,"三",TYPE16X16,TYPE8X16);
- break;
- case 4:
- LCD_Print(69,48,"四",TYPE16X16,TYPE8X16);
- break;
- case 5:
- LCD_Print(69,48,"五",TYPE16X16,TYPE8X16);
- break;
- case 6:
- LCD_Print(69,48,"六",TYPE16X16,TYPE8X16);
- break;
- }
- }
- LCD_ShowNum(16,16,calendar.hour,2,32);
- LCD_ShowNum(70,16,calendar.min,2,32);
- }
- }
- u8 jianpan(u8 x,u8 y,u8 flagm)
- {
- key_load();
- if(xianshi[key]>=0&&xianshi[key]<=9)
- {
- //Gui_DrawFont_GBK16(x+plen*8,y,BLACK,WHITE,zhuanhuan(xianshi[key]));
- s=xianshi[key];
- plen++;
- return 1;
- }
- return 0;
- }
- void IC()
- {
- u8 j;
- status = PcdRequest(PICC_REQALL,CT);
- if(status==MI_OK)//尋卡成功
- {
- status=MI_ERR;
- status = PcdAnticoll(SN);
- for(j=0;j<4;j++)
- printf("%d ",SN[j]);
- printf("\r\n");
- }
- if (status==MI_OK)//防衝撞成功
- {
- total=jiance();
- if(weeks)
- {if(total==0) {
- if(shuru()==1)flags=1;
- }
- }
- else{
- if(total==0) flags=1;
- if(total&&power)flags=1;
- }
- printf("22\r\n");
- }
- }
-
- int main(void)
- {
- u8 num=0,i;
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- delay_init(); //延时函数初始化
- RTC_Init(); //RTC初始化
- //RTC_Set(2020,5,1,14,20,0);
- uart_init(115200);
- LCD_Init();
- SUO_Init();
- key_Init(); //矩阵键盘利用外部中断和输出引脚构成,先把输出引脚低电平,按键闭合触发检测行,在出现一个下降沿,再次触发,检测列
- InitRc522(); //初始化射频卡模块
- while(1)
- {
- num++;
- if(num>50)
- break;
- if(key==15)
- {GPIO_SetBits(GPIOA,GPIO_Pin_4);break;}
- delay_ms(100);
- key_load();
- }
- key=16;
- while(1)
- {
- IC();
- TIME();//更新时间
- key_load(); //键盘键值检测
- if(flags==1)
- {
- SUO=1;
- for(i=0;i<9;i++)
- delay_ms(1000);
- SUO=0;num=0;
- delay_ms(1000);
- T=100,TT=100;
- flags=0;
- LCD_Init();
- } //开锁
- if(key==11)weeks=~weeks;//假期模式选择
- if(weeks)LCD_Print(96, 48, "假日",TYPE16X16,TYPE8X16);
- else LCD_Print(96, 48, " ",TYPE16X16,TYPE8X16);
- if(key==12)flags=1; //紧急按键
- if(weeks==0)
- {
- if(key==7)
- {
- if(shuru()==1)flags=1; //输入密码开锁
- }
- }
- delay_ms(100);
- key=16;
- }
- }
复制代码
所有资料51hei提供下载:
门禁.7z
(213.59 KB, 下载次数: 143)
|