最近做了个基于51单片机的模拟门禁的DIY小作品。工作原理大致是:当IC卡放在读卡器可以识别的范围内时,读卡器读取信息传给单片机进行处理,如果识别为有效卡则继电器闭合(模拟门锁打开),开门指示灯亮,12864液晶上会进行简单的提示表示刷卡成功等。如果该卡为无效卡则报警指示灯亮,蜂鸣器报警,同时可以通过按键进行时间的设置以及对IC卡进行注册和注销。。。总之自己也是一个小菜鸡,这个小作品也是一个很简单的设计,也没有什么创新的地方,主要是自己独立的找资料,动手DIY的。板子上一个485模块电路,本来打算是想通过MODBUS协议和MCGS进行通信的,最后数据也没有传上去(可以在组态上发命令,但无法把下位机数据传上去),所以这一部分功能搁浅了,希望有大神可以试一下单片机与MCGS的通讯,比如把实时温度显示在MCGS组态界面上。附上完整的PCB和程序
制作出来的实物图如下:
Altium Designer画的单片机RFID模拟门禁系统电路原理图和PCB图如下:(51hei附件中可下载工程文件)
单片机源程序如下:
- #include "led.h"
- #include "beep.h"
- #include "12864.h"
- #include "rc522.h"
- #include "key.h"
- #include "STCEEPROM.h"
- #include "DS1302.h"
- unsigned char idata RevBuffer[30];
- unsigned char Card_Num;
- unsigned char idata UID[4],Temp[4];
- unsigned char Table[3];
- unsigned char Num;
- uchar DS1302_Table[7]={0}; //读取时间值
- unsigned char Count,Countf,Count1,Count2,Count3,Count4,Count5,C_flag;
- unsigned char T0RH = 0; //T0重载值的高字节
- unsigned char T0RL = 0; //T0重载值的低字节
- //unsigned char table1[20]= "刷卡成功!\r\n";
- void ConfigTimer0(unsigned int ms);
- extern void UartDriver();
- extern void ConfigUART(unsigned int baud);
- extern void UartRxMonitor(unsigned char ms);
- extern void UartWrite(unsigned char *buf, unsigned char len);
- //void delay_ms(unsigned int t)
- //{
- // unsigned char a,b;
- // while(t--)
- // {
- // for(b=102;b>0;b--)
- // for(a=3;a>0;a--);
- // }
- //}
- void iccardcode();
- void InitializeSystem();
- void Auto_Reader(void);
- void Display_LCD2(uchar Dis_Hour,uchar Dis_Min,uchar Dis_Sec);
- void Run_DS1302(void);
- void main()
- {
-
- EA = 1; //开总中断
- ConfigTimer0(1); //配置T0定时1ms
- ConfigUART(9600); //配置波特率为9600
- led_init();
- beep_init();
- InitializeSystem();
- InitLcd12864();
- LcdShowString(8,8,"智能门禁考勤系统");
-
- while(1)
- {
- //UartDriver();
- iccardcode();
- Auto_Reader();
- Run_DS1302();
- if(!KEY1)
- {
- delay_10ms(50);
- if(!KEY1)
- {
- DS1302_Table[4]++;
- Write_DS1302Init(0,0,0,0,DS1302_Table[4],DS1302_Table[5],0);
- }
-
-
-
- }
-
-
- if(!KEY2)
- {
- delay_10ms(50);
- if(!KEY2)
- {
- DS1302_Table[4]--;
- Write_DS1302Init(0,0,0,0,DS1302_Table[4],DS1302_Table[5],0);
- }
- }
-
-
- if(!KEY3)
- {
- delay_10ms(50);
- if(!KEY3)
- {
- DS1302_Table[5]++;
- Write_DS1302Init(0,0,0,0,DS1302_Table[4],DS1302_Table[5],0);
- }
- }
- if(!KEY5)
- {
- delay_10ms(50);
-
- if(!KEY5)
- {
- delay_10ms(50);
- if(!KEY5)
- {
- if(C_flag==2)
- {
- //0123456789abcdef
- LcdShowString(8,32," Register Card! ");
- }
- if(C_flag==1)
- {
- //0123456789abcdef
- LcdShowString(8,32," Clean Card! ");
- }
- BEEP=0;delay_10ms(200);BEEP=1;
- LcdShowString(8,32,"Please Swipecard");
- C_flag =0;
- while(!KEY5);
- }
-
-
- }
-
- }
- }
-
- }
- //系统初始化
- void InitializeSystem()
- {
- PcdReset();
- PcdAntennaOff();
- PcdAntennaOn();
- M500PcdConfigISOType( 'A' );
-
- }
- void Auto_Reader(void)
- {
- if(PcdRequest(0x52,Temp)==0)
- {
- if(PcdAnticoll(UID)==0)
- {
- BEEP=0;delay_10ms(20);BEEP=1;
- Table[0]=UID[0]/100+0x30;
- Table[1]=UID[0]/10%10+0x30;
- Table[2]=UID[0]%10+0x30;
- //LcdShowString(8,32,"Num: ");
- //LcdShowString(8,32,Table);
- Count = UID[0];
- if((Count==Count1)||(Count==Count2)||(Count==Count3)||(Count==Count4)||(Count==Count5))
- {
-
- LcdShowString(8,48," 刷卡成功!");
- Green_LED = 0;
- JQZ=0;
- UartWrite("刷卡成功,请进入!\r\n\r\n\r\n",20);
- delay_10ms(200);
- JQZ=1;
- Green_LED = 1;
- LcdShowString(8,48," ");
- C_flag=1;
-
-
-
- }
- else
- {
- LcdShowString(8,48," 刷卡失败!");
- UartWrite("刷卡失败,请重刷!\r\n\r\n\r\n",20);
- RED_LED = 0;
- delay_10ms(200);
- RED_LED = 1;
- LcdShowString(8,48," ");
- C_flag=2;
- }
- delay_10ms(200);
- LcdShowString(8,32,"Please Swipecard");
- }
- }
- }
-
- void iccardcode()
- {
- unsigned char cmd;
- unsigned char status;
-
- cmd = RevBuffer[0];
- switch(cmd)
- {
- case 1: // Halt the card //终止卡的操作
- status= PcdHalt();;
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 2: // Request,Anticoll,Select,return CardType(2 bytes)+CardSerialNo(4 bytes)
- // 寻卡,防冲突,选择卡 返回卡类型(2 bytes)+ 卡系列号(4 bytes)
- status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
- if(status!=0)
- {
- status= PcdRequest(RevBuffer[1],&RevBuffer[2]);
- if(status!=0)
- {
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- }
- }
- RevBuffer[0]=3;
- RevBuffer[1]=status;
- break;
-
- case 3: // 防冲突 读卡的系列号 MLastSelectedSnr
- status = PcdAnticoll(&RevBuffer[2]);
- if(status!=0)
- {
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- }
- //memcpy(MLastSelectedSnr,&RevBuffer[2],4);
- RevBuffer[0]=5;
- RevBuffer[1]=status;
- break;
- case 4: // 选择卡 Select Card
- //status=PcdSelect(MLastSelectedSnr);
- if(status!=MI_OK)
- {
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- }
- RevBuffer[0]=3;
- RevBuffer[1]=status;
- break;
- case 5: // Key loading into the MF RC500's EEPROM
- //status = PcdAuthState(RevBuffer[1], RevBuffer[3], DefaultKey, MLastSelectedSnr);// 校验卡密码
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 6:
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 7:
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 8: // Read the mifare card
- // 读卡
- status=PcdRead(RevBuffer[1],&RevBuffer[2]);
- if(status==0)
- {RevBuffer[0]=17;}
- else
- {RevBuffer[0]=1;}
- RevBuffer[1]=status;
- break;
- case 9: // Write the mifare card
- // 写卡 下载密码
- status=PcdWrite(RevBuffer[1],&RevBuffer[2]);
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 10:
- PcdValue(RevBuffer[1],RevBuffer[2],&RevBuffer[3]);
- RevBuffer[0]=1;
- RevBuffer[1]=status;
- break;
- case 12: // 参数设置
- PcdBakValue(RevBuffer[1], RevBuffer[2]);
- RevBuffer[0]=1; //contact
- RevBuffer[1]=0;
- break;
- }
- }
- void Display_LCD2(uchar Dis_Hour,uchar Dis_Min,uchar Dis_Sec)
- {
- uchar Dis_Table[8]="18:40:33";
- Dis_Table[0] =' ';
- Dis_Table[1] =' ';
- Dis_Table[2] =' ';
- Dis_Table[3] =' ';
- Dis_Table[4] = Dis_Hour/10+0x30;
- Dis_Table[5] = Dis_Hour%10+0x30;
- Dis_Table[6] =':';
- Dis_Table[7] = Dis_Min/10+0x30;
- Dis_Table[8] = Dis_Min%10+0x30;
- Dis_Table[9] =':';
- Dis_Table[10] = Dis_Sec/10+0x30;
- Dis_Table[11] = Dis_Sec%10+0x30;
-
- LcdShowString(8,16,Dis_Table);
- }
- /********************************************************************
- * 名称 : Run_DS1302(void)
- * 功能 : 读出DS1302中的数据,并进行显示
- * 输入 : 无
- * 输出 : 无
- ***********************************************************************/
- void Run_DS1302(void)
- {
- uchar sec, min, hour, day, month, week, year;
- v_W1302(0x8f, 0);
- sec = bcdtodec(uc_R1302(0x81)); //读出DS1302中的秒
- v_W1302(0x8f, 0);
- min = bcdtodec(uc_R1302(0x83)); //读出DS1302中的分
- v_W1302(0x8f, 0);
- hour = bcdtodec(uc_R1302(0x85)); //读出DS1302中的小时
- v_W1302(0x8f, 0);
- day = bcdtodec(uc_R1302(0x87)); //读出DS1302中的日
- v_W1302(0x8f, 0);
- month = bcdtodec(uc_R1302(0x89)); //读出DS1302中的月
- v_W1302(0x8f, 0);
- week = bcdtodec(uc_R1302(0x8b)); //读出DS1302中的星期
- v_W1302(0x8f, 0);
- year = bcdtodec(uc_R1302(0x8d)); //读出DS1302中的年
- DS1302_Table[0]=year;
- DS1302_Table[1]=month;
- DS1302_Table[2]=day;
- DS1302_Table[3]=week;
- DS1302_Table[4]=hour;
- DS1302_Table[5]=min;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码 所有资料51hei提供下载:
程序V0.2.rar
(203.75 KB, 下载次数: 386)
newPCBV0.1.rar
(3.36 MB, 下载次数: 163)
MyDesigner.rar
(38.17 KB, 下载次数: 198)
|