51门禁系统源程序.docx
《51门禁系统源程序.docx》由会员分享,可在线阅读,更多相关《51门禁系统源程序.docx(52页珍藏版)》请在冰豆网上搜索。
51门禁系统源程序
51门禁系统源程序
#include"reg52.h"
#include"main.h"
#include"uart.h"
#include"timer.h"
#include"rc522.h"
#include"ctrl.h"
#include"lcd12864.h"
#include"beep.h"
#include"key.h"
#include"EEPROM.h"
voidinit_all(void)//初始化
{
EA=0;//关总中断
init_timer();//定时器初始化
init_uart();//串口初始化
init_rc522();//RC522初始化
lcd_init();//LCD初始化
EEPROM_READ(0,Card_SN_BUF,4);//EEPROM初始化,取出记录的卡号
EEPROM_READ(7,KEY_BUF,8);//EEPROM初始化,取出记录的密码
send_bytes(Card_SN_BUF,4);
EA=1;//开总中断
}
voidmain(void)//主函数
{
INT8Ukey;
Delay_ms(50);//让硬件稳定
init_all();//执行初始化函数
relay_OFF();//关继电器
LED_BLINK_1();//ledtest
beep1();//beeptest
display(0,0,0);//显示初始化
while
(1)
{
key=key_scan();//按键操作
if(key==12)if(states>0)states--;
elsestates=0;//上一功能
Card_SN_BUF[4]={0xff,0xff,0xff,0xff},//卡号登记缓冲区
KEY_BUF[8]={'0','0','0','0','0','0','0','0'};
INT8UbPass=0;bWarn=0;
voiduart_over(void)//串口数据还原
{
UartCount=0;
UartStart=FALSE;
UartComp=FALSE;
}
voidpass(void)
{
beep1();
Delay_ms(2000);//让卡片离开
LED_BLINK_1();
}
voidwarn(void)
{
LED_BLINK_2();
}
INT8UIC_READ(void)
{
INT8UID_ASC[8],i;
if(PcdRequest(PICC_REQIDL,Card_type)!
=MI_OK)//寻天线区内未进入休眠状态的卡,返回卡片类型2字节
{
if(PcdRequest(PICC_REQIDL,Card_type)!
=MI_OK)//寻天线区内未进入休眠状态的卡,返回卡片类型2字节
{
returnFALSE;
}
}
if(PcdAnticoll(Card_SN)!
=MI_OK)//防冲撞,返回卡的序列号4字节
{
bWarn=1;
returnFALSE;
}
bPass=1;
send_bytes(Card_type,2);
send_bytes(Card_SN,4);
for(i=0;i<4;i++)//卡ID号转化成ASCII
{
if(Card_SN[i]/16>9)ID_ASC[i*2]=Card_SN[i]/16+'7';
elseID_ASC[i*2]=Card_SN[i]/16+'0';
if(Card_SN[i]%16>9)ID_ASC[i*2+1]=Card_SN[i]%16+'7';
elseID_ASC[i*2+1]=Card_SN[i]%16+'0';
}
display2(3,0,"ID:
",4);//显示卡号
display2(3,2,ID_ASC,8);
returnTRUE;
}
voidctrl_process(void)
{
INT8Ui,key_count,key_value=16,table[8]="--------",statesbuf;
if(states!
=statesbuf)//状态改变,清屏
{
display_clear_line
(2);
display_clear_line(3);
statesbuf=states;
}
switch(states)
{
case0:
//IC卡读卡输入
display(1,0,1);
if(IC_READ())
{
if((Card_SN[0]==Card_SN_BUF[0])
&&(Card_SN[1]==Card_SN_BUF[1])
&&(Card_SN[2]==Card_SN_BUF[2])
&&(Card_SN[3]==Card_SN_BUF[3]))
{
relay_ON();//灯开关
display(2,0,5);
}
elsedisplay(2,0,6);
relay_OFF();
}
break;
case1:
display(1,0,2);//密码输入
display2(3,0,table,8);
key_count=0;
while
(1)
{
key_value=key_scan();
if(key_value==12)
{
states--;
return;
}
if(key_value==13)
{
states++;
return;
}
if(key_value>=0&&key_value<=9)//有按键输入
{
table[key_count++]=key_value+'0';
display2(3,0,table,8);
}
if(key_value==11)//退格
{
table[--key_count]='-';
display2(3,0,table,8);
}
if(key_count==8)
{
if(table[0]==KEY_BUF[0]&&
table[1]==KEY_BUF[1]&&
table[2]==KEY_BUF[2]&&
table[3]==KEY_BUF[3]&&
table[4]==KEY_BUF[4]&&
table[5]==KEY_BUF[5]&&
table[6]==KEY_BUF[6]&&
table[7]==KEY_BUF[7])//密吗正确
{
bPass=1;
relay_ON();//灯开关
display(2,0,5);
relay_OFF();
break;
}
else//密码错误
{
relay_OFF();
beep1();
bWarn=1;
display(2,0,6);
break;
}
}
}
break;
case2:
display(1,0,3);//IC卡登记
if(IC_READ())
{
for(i=0;i<4;i++)
Card_SN_BUF[i]=Card_SN[i];
EEPROM_WRITE(0,Card_SN,4);//写入EEPROM
}
break;
case3:
display(1,0,4);//密码设置
display2(3,0,table,8);
key_count=0;
while
(1)
{
key_value=key_scan();
if(key_value==12)
{
states--;
return;
}
if(key_value>=0&&key_value<=9)//有按键输入
{
table[key_count++]=key_value+'0';
display2(3,0,table,8);
}
if(key_value==11)//退格
{
table[--key_count]='-';
display2(3,0,table,8);
}
if(key_count==8&&key_value==15)//按下确定键
{
for(i=0;i<8;i++)
KEY_BUF[i]=table[i];
EEPROM_WRITE(7,KEY_BUF,8);//写入EEPROM
break;
}
}
break;
default:
break;
}
if(bPass)//处理成功
{
bPass=0;
pass();
}
if(bWarn)//处理失败
{
bWarn=0;
warn();
}
}
#include"reg52.h"
#include"intrins.h"
#include"main.h"
#include"rc522.h"
#include"string.h"
voiddelay_ns(unsignedintns)
{
unsignedinti;
for(i=0;i{
nop();
nop();
nop();
}
}
//------------------------------------------
//读SPI数据
//------------------------------------------
unsignedcharSPIReadByte(void)
{
unsignedcharSPICount;//Counterusedtoclockoutthedata
unsignedcharSPIData;
SPIData=0;
for(SPICount=0;SPICount<8;SPICount++)//Preparetoclockinthedatatoberead
{
SPIData<<=1;//Rotatethedata
CLR_SPI_CK;//nop();//nop();//RaisetheclocktoclockthedataoutoftheMAX7456
if(STU_SPI_MISO)
{
SPIData|=0x01;
}
SET_SPI_CK;//nop();//nop();//Droptheclockreadyforthenextbit
}//andloopback
return(SPIData);//Finallyreturnthereaddata
}
//------------------------------------------
//写SPI数据
//------------------------------------------
voidSPIWriteByte(unsignedcharSPIData)
{
unsignedcharSPICount;//Counterusedtoclockoutthedata
for(SPICount=0;SPICount<8;SPICount++)
{
if(SPIData&0x80)
{
SET_SPI_MOSI;
}
else
{
CLR_SPI_MOSI;
}
nop();nop();
CLR_SPI_CK;nop();nop();
SET_SPI_CK;nop();nop();
SPIData<<=1;
}
}
/////////////////////////////////////////////////////////////////////
//功能:
读RC632寄存器
//参数说明:
Address[IN]:
寄存器地址
//返回:
读出的值
/////////////////////////////////////////////////////////////////////
unsignedcharReadRawRC(unsignedcharAddress)
{
unsignedcharucAddr;
unsignedcharucResult=0;
CLR_SPI_CS;
ucAddr=((Address<<1)&0x7E)|0x80;
SPIWriteByte(ucAddr);
ucResult=SPIReadByte();
SET_SPI_CS;
returnucResult;
}
/////////////////////////////////////////////////////////////////////
//功能:
写RC632寄存器
//参数说明:
Address[IN]:
寄存器地址
//value[IN]:
写入的值
/////////////////////////////////////////////////////////////////////
voidWriteRawRC(unsignedcharAddress,unsignedcharvalue)
{
unsignedcharucAddr;
CLR_SPI_CS;
ucAddr=((Address<<1)&0x7E);
SPIWriteByte(ucAddr);
SPIWriteByte(value);
SET_SPI_CS;
}
/////////////////////////////////////////////////////////////////////
//功能:
清RC522寄存器位
//参数说明:
reg[IN]:
寄存器地址
//mask[IN]:
清位值
/////////////////////////////////////////////////////////////////////
voidClearBitMask(unsignedcharreg,unsignedcharmask)
{
chartmp=0x00;
tmp=ReadRawRC(reg);
WriteRawRC(reg,tmp&~mask);//clearbitmask
}
/////////////////////////////////////////////////////////////////////
//功能:
置RC522寄存器位
//参数说明:
reg[IN]:
寄存器地址
//mask[IN]:
置位值
/////////////////////////////////////////////////////////////////////
voidSetBitMask(unsignedcharreg,unsignedcharmask)
{
chartmp=0x00;
tmp=ReadRawRC(reg);
WriteRawRC(reg,tmp|mask);//setbitmask
}
/////////////////////////////////////////////////////////////////////
//用MF522计算CRC16函数
/////////////////////////////////////////////////////////////////////
voidCalulateCRC(unsignedchar*pIndata,unsignedcharlen,unsignedchar*pOutData)
{
unsignedchari,n;
ClearBitMask(DivIrqReg,0x04);
WriteRawRC(CommandReg,PCD_IDLE);
SetBitMask(FIFOLevelReg,0x80);
for(i=0;i{WriteRawRC(FIFODataReg,*(pIndata+i));}
WriteRawRC(CommandReg,PCD_CALCCRC);
i=0xFF;
do
{
n=ReadRawRC(DivIrqReg);
i--;
}
while((i!
=0)&&!
(n&0x04));
pOutData[0]=ReadRawRC(CRCResultRegL);
pOutData[1]=ReadRawRC(CRCResultRegM);
}
/////////////////////////////////////////////////////////////////////
//功能:
通过RC522和ISO14443卡通讯
//参数说明:
Command[IN]:
RC522命令字
//pInData[IN]:
通过RC522发送到卡片的数据
//InLenByte[IN]:
发送数据的字节长度
//pOutData[OUT]:
接收到的卡片返回数据
//*pOutLenBit[OUT]:
返回数据的位长度
/////////////////////////////////////////////////////////////////////
charPcdComMF522(unsignedcharCommand,
unsignedchar*pInData,
unsignedcharInLenByte,
unsignedchar*pOutData,
unsignedint*pOutLenBit)
{
charstatus=MI_ERR;
unsignedcharirqEn=0x00;
unsignedcharwaitFor=0x00;
unsignedcharlastBits;
unsignedcharn;
unsignedinti;
switch(Command)
{
casePCD_AUTHENT:
irqEn=0x12;
waitFor=0x10;
break;
casePCD_TRANSCEIVE:
irqEn=0x77;
waitFor=0x30;
break;
default:
break;
}
WriteRawRC(ComIEnReg,irqEn|0x80);
ClearBitMask(ComIrqReg,0x80);
WriteRawRC(CommandReg,PCD_IDLE);
SetBitMask(FIFOLevelReg,0x80);
for(i=0;i{
WriteRawRC(FIFODataReg,pInData[i]);
}
WriteRawRC(CommandReg,Command);
if(Command==PCD_TRANSCEIVE)
{
SetBitMask(BitFramingReg,0x80);
}
//i=600;//根据时钟频率调整,操作M1卡最大等待时间25ms
i=2000;
do
{
n=ReadRawRC(ComIrqReg);
i--;
}
while((i!
=0)&&!
(n&0x01)&&!
(n&waitFor));
ClearBitMask(BitFramingReg,0x80);
if(i!
=0)
{
if(!
(ReadRawRC(ErrorReg)&0x1B))
{
status=MI_OK;
if(n&irqEn&0x01)
{status=MI_NOTAGERR;}
if(Command==PCD_TRANSCEIVE)
{
n=ReadRawRC(FIFOLevelReg);
lastBits=ReadRawRC(ControlReg)&0x07;
if(lastBits)
{
*pOutLenBit=(n-1)*8+lastBits;
}
else
{
*pOutLenBit=n*8;
}
if(n==0)
{
n=1;
}
if(n>MAXRLEN)
{
n=MAXRLEN;
}
for(i=0;i{
pOutData[i]=ReadRawRC(FIFODataReg);
}
}
}
else
{
status=MI_ERR;