#include <setjmp.h>
#include "ZK.h"
#include "oled.h" //包含液晶函数
#include "eeprom.h"
#include "AS608.h"
#include <intrins.h>
#include <DS1302.h>
#define uchar unsigned char
#define uint unsigned int //宏定义
#define GPIO_KEY P2
#define GLY 10 //管理员
#define ST_up 11 //上调
#define XT_down 12 //下调
#define Sign_out 13 //退出
#define Delete 15 //删除
#define Confirm 14 //确认
#define User 1 //用户
sbit Beep = P1^0;
sbit Lock = P1^1;
sbit FingerPrint_KEY=P3^7;
bit GLY_use = 0; //管理员使能位 :0、关闭管理员,1、开启管理员
bit GLY_dj = 1; //管理员冻结密码使能位:0、冻结密码,1、关闭冻结
bit init_complete=0;//初始化完成标志:0、初始化未完成,1、允许执行程序
bit GLY_Password_ok = 0;//管理员密码输入好标志:0、密码未输好,1、密码已经输好
bit Password_ok = 0;//密码输入好标志:0、密码未输好,1、密码已经输好
bit Password_rd = 0;
bit ZW_GLY = 0;
bit CLose_OLED = 0;
uchar code AT_password[6] = {0,1,0,8,2,9}; //管理员密码 020403
uchar code PW_BUFFER[6] = {0,2,0,4,0,3}; //用户密码
uchar xdata User_Password[16] = {0}; //用户密码缓存
uchar xdata GLY_Password[16] = {0}; //管理员密码缓存
uchar xdata T0RH = 0; //T0重载值的高字节
uchar xdata T0RL = 0; //T0重载值的低字节
uchar code KEY_switch[16]={0xeb,0x77,0x7b,0x7d,0xb7,0xbb,0xbd,0xd7,0xdb,0xdd,0x7e,0xbe,0xde,0xee,0xed,0xe7};//0-15
jmp_buf JMP_BUF;
struct sTime CurTime; //当前日期时间
long OLED_num = 0;
volatile unsigned char xdata AS608_Buff[32];
void GLY_Menu();
void RefreshTime();
void RefreshDate(uchar ops);
void Beep_10ms();
//void soft_reset(void)
//{
// ((void (code *) (void)) 0x3745)();
//}
void JMP()
{
if(setjmp(JMP_BUF)!=0) OLED_Clear();
}
void OPen_T0()
{
TR0 = 1; //启动T0
ET0 = 1; //使能T0中断
}
void Close_T0()
{
TR0 = 0; //启动T0
ET0 = 0; //使能T0中断
}
void CLOSE_OLED_TEST()
{
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
}
uchar code LedChar[]={
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, //定义八个灯的工作状态。
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
void delay(uint xdata t);
uchar keyscan() //带返回值的子函数
{
uchar Key_H,Key_L,Key_Vaul,i;
GPIO_KEY = 0xf0;//1111 0000
if( (GPIO_KEY & 0xf0) != 0xf0)//判断是否有按键按下(按下就为与)
{
delay(10);//软件消抖
if( (GPIO_KEY & 0xf0) != 0xf0)//再次判断是否有按键按下
{
Key_L = GPIO_KEY & 0xf0;// 储存列线值
GPIO_KEY = Key_L | 0x0f;
Key_H = GPIO_KEY & 0x0f;// 储存行线值
Key_Vaul=Key_H+Key_L;
for(Key_H=0;Key_H<16;Key_H++)
if(Key_Vaul==KEY_switch[Key_H])break;
Beep_10ms();
while( (GPIO_KEY & 0x0f) != 0x0f );//松手检测
return (Key_H);//返回键值码
}
}
}
uchar Uart_Receive_Byte()//接收一个字节
{
uchar xdata Byte;
while((!RI)&&(!CLose_OLED));
RI = 0;
Byte = SBUF;
return (Byte);
}
void Uart_Receive_Date(uchar length) //接收缓存
{
uchar xdata i;
for(i=0;i<length;i++)
{
AS608_Buff[i]=Uart_Receive_Byte();
}
}
/* 配置并启动T0*/
void key_int(uint ms)
{
unsigned long tmp; //临时变量
tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 18; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 0; //使能T0中断
TR0 = 0; //启动T0
}
/* 串口配置函数,baud-通信波特率 */
void UART_int(unsigned int baud)
{
SCON = 0x50; //配置串口为模式1
PCON=0x00; //SMOD=0:波特率不加倍
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1为模式2
TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值
TL1 = TH1; //初值等于重载值
PT1 = 1;
IPH = 0X08;
ET1 = 0; //禁止T1中断
// ES = 1; //使能串口中断
TR1 = 0; //启动T1
}
void delay(uint xdata t)//@12MHz
{
uint xdata a,b,c;
for(a=t;a>0;a--)
for(b=10;b>0;b--)
for(c=95;c>0;c--);
}
void Open_ES()//打开串口
{
TR1 = 1; //启动T1
// TR0=0;
// ET0=0;
}
void Close_ES()//关闭串口
{
TR1 = 0; //禁止T1
// TR0=1;
// ET0=1;
}
void Beep_10ms()
{
Beep=0;
delay(50);
Beep=1;
}
/*添加指纹*/
void Add_Fingerprint()
{
uchar data ID[2],i;
uchar data finger_id;
finger_id=byte_read(0x2400);
Add:_nop_();
ZK_QSRZWH();
ZK_GLYMS();
while(1)
{
//指纹iD值显示处理
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(30,5,ID,3,1);
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==ST_up)//上调按键
{
if(finger_id == 0xc8)finger_id = 0;
else
finger_id = finger_id + 1;
}
if(keyscan()==XT_down)if(finger_id>0x00)finger_id = finger_id-1;//下调按键
if(keyscan()==Sign_out)break; //退出
//按确认键开始录入指纹信息
if(keyscan()==Confirm) //确认
{
Open_ES();
ZK_QAYZW();
ZK_GLYMS();
while(1)
{
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==Sign_out)break; //退出
AS608_Send_PS_GetImage(); //获得指纹图像
Uart_Receive_Date(12);//判断接收到的确认码,等于0指纹获取成功
if(AS608_Buff[9]==0)
{
AS608_Buff[9]=1;
delay(500);
AS608_GenChar(0x01);
Uart_Receive_Date(12);
ZK_QAYzZCZW();
ZK_GLYMS();
while(1)
{
AS608_Send_PS_GetImage(); //获得指纹图像
Uart_Receive_Date(12);
//判断接收到的确认码,等于0指纹获取成功
if(AS608_Buff[9]==0)
{
AS608_Buff[9]=1;
delay(500);
ZK_ZWYTJ();
ZK_GLYMS();
//指纹iD值显示处理
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(70,5,ID,3,1);
AS608_GenChar(0x02);
Uart_Receive_Date(12);
AS608_RegMode1();//合并特征生成模板
Uart_Receive_Date(12);
AS608_StoreChar(0x01,finger_id);
Uart_Receive_Date(12);
delay(500);
finger_id=finger_id+1;
Close_ES();
OLED_Clear();
goto Add;
}
}
}
}
}
}
SectorErase(0x2400);
byte_write(0x2400,finger_id);
}
//高速搜索指纹
void HignhSpeedSearch()
{
uchar ID[2],i;
uchar finger_id;
ZK_YZZW();
CLose_OLED=100;
while(1)
{
Open_ES();
AS608_Send_PS_GetImage();//获取指纹图像
Uart_Receive_Date(12);
if(AS608_Buff[9]==0)
{
AS608_Buff[9]=1;
delay(500);
AS608_GenChar(0x01);
Uart_Receive_Date(12);
AS608_HignhSpeedSearch(0x01);//高速搜索0-255指纹
Uart_Receive_Date(16);
if(AS608_Buff[9]==0)
{
AS608_Buff[9]=1;
ZK_ZWZZMYK();
ZK_YHMS();
finger_id=AS608_Buff[11];
if((finger_id==100)||(finger_id==99)||(finger_id==101))
{
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(70,5,ID,3,1);
delay(500);
OLED_Clear();
GLY_Menu();
OLED_Clear();
break;
}
else
{
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(70,5,ID,3,1);
Close_ES();
Lock = 0;
delay(50);
Lock = 1;
delay(500);
OLED_Clear();
break;
}
}
else
{
Close_ES();
ZK_ZWCW();
ZK_YHMS();
delay(500);
OLED_Clear();
break;
}
}
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==Sign_out)break; //退出
}
}
//删除指纹
void DeletChar()
{
uchar data ID[2],i;
uchar data finger_id=0x01;
abb:_nop_();
ZK_QSRZWH();
ZK_GLYMS();
while(1)
{
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(30,5,ID,3,1);
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==ST_up)//上调按键
{
if(finger_id == 0xc8)finger_id = 0;
else finger_id = finger_id + 1;
}
if(keyscan()==XT_down) if(finger_id>0x00)finger_id = finger_id-1;//下调按键
if(keyscan()==Sign_out)break; //退出
//按确认键开始录入指纹信息
if(keyscan()==Confirm) //确认
{
Open_ES();
AS608_DeletChar(finger_id);
Uart_Receive_Date(12);
if(AS608_Buff[9]==0)
{
ZK_ZWYSC();
ZK_GLYMS();
ID[0]=finger_id/100;
ID[1]=finger_id%100/10;
ID[2]=finger_id%100%10;
OLED_Show_Number(70,5,ID,3,1);
Close_ES();
delay(500);
goto abb;
}
}
}
}
/*用户密码初始化:只在程序下入的第一上电运行一次*/
void Password_init()
{
uchar xdata i ;
uchar xdata x;
x=byte_read(0x2201);
if(x!=2)
{
SectorErase(0x0000);
byte_write(0x0001,1);
SectorErase(0x2400);
byte_write(0x2400,0);
SectorErase(0x2000);
for(i=0;i<6;i++)
{
byte_write(0x2001+i,PW_BUFFER[i]);
}
SectorErase(0x2200);
byte_write(0x2201,2);
InitDS1302();
}
}
/*管理员密码输入*/
void GLY_Password_in()
{
uchar xdata i,x;
end:_nop_();
ZK_QSRGLYMM();
ZK_GLYMS();
for(i=0;i<10;)
{
while((GPIO_KEY==0XF0)&&(CLose_OLED==0));
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()<GLY)
{
GLY_Password[i] = keyscan();
OLED_Show_sChar(10*i,6, SChar2 ,1);//显示*
i++;
}
else if(keyscan()==Delete) //退位
{
if(i>0)
{
OLED_Show_sChar(10*i,6, SChar3 ,1);
i--;
}
}
else if(keyscan()==Confirm) //确认
{
if(i>0)
{
if(i==6)
{
GLY_Password_ok = 1;
break;
}
else
{
GLY_Password_ok = 0;
ZK_MMWSCW();
ZK_GLYMS();
delay(500);
OLED_Clear();
goto end;
}
}
}
else if(keyscan()==Sign_out) //退出
{
GLY_Password_ok = 0;
OLED_num = 0;
Close_T0();
break;
}
if(i==9) //密码位数到达最大值自行退出
{
GLY_Password_ok = 0;
ZK_MMWSCW();
ZK_GLYMS();
delay(500);
OLED_Clear();
goto end;
}
}
}
/*用户密码输入*/
void Password_in()
{
uchar i ;
end:_nop_();
ZK_QSRMM();
ZK_YHMS();
for(i=0;i<10;)
{
while((GPIO_KEY==0XF0)&&(CLose_OLED==0));
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()<10)
{
User_Password[i] = keyscan();
OLED_Show_sChar(10*i,5, SChar2 ,1);//显示*
i++;
}
else if(keyscan()==Delete) //退位
{
if(i> 0)
{
OLED_Show_sChar(10*i,5, SChar3 ,1);
i--;
}
}
else if(keyscan()==Confirm) //确认
{
if(i>0)
{
if(i==6)
{
Password_ok = 1;
break;
}
else
{
Password_ok = 0;
ZK_MMWSCW();
ZK_YHMS();
delay(500);
OLED_Clear();
goto end;
}
}
}
else if(keyscan()==Sign_out) //取消
{
Password_ok = 0;
OLED_num = 0;
Close_T0();
break;
}
if(i==9) //密码位数到达最大值自行退出
{
Password_ok = 0;
ZK_MMWSCW();
ZK_YHMS();
delay(500);
OLED_Clear();
goto end;
}
}
}
/*用户密码重置*/
void PassWord_Reset()
{
uchar i;
SectorErase(0x2000);
for(i=0;i<6;i++)
{
byte_write(0x2001+i,PW_BUFFER[i]);
}
SectorErase(0x2200);
byte_write(0x2201,5);
ZK_MMYCZ();
ZK_GLYMS();
delay(500);
}
/*用户密码修改*/
void Use_Password_Change()
{
uchar i;
retry:_nop_();
SectorErase(0x2000);
ZK_QSRXMM();
ZK_GLYMS();
for(i=0;i<10;)
{
while((GPIO_KEY==0XF0)&&(CLose_OLED==0));
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()<10)
{
byte_write(0x2001+i,keyscan());
OLED_Show_sChar(10*i,5, SChar2 ,1);//显示*
i++;
}
else if(keyscan()==Delete)goto retry; //退位
else if(keyscan()==Confirm) //确认
{
if(i>0)
{
if(i==6)
{
ZM_MMXGCG();
ZK_GLYMS();
delay(500);
OLED_Clear();
break;
}
else
{
ZK_MMWSCW();
ZK_GLYMS();
delay(500);
OLED_Clear();
goto retry;
}
}
}
else if(keyscan()==Sign_out)break; //取消
if(i==9) //密码位数到达最大值自行退出
{
Password_ok = 0;
ZK_MMWSCW();
ZK_GLYMS();
delay(500);
OLED_Clear();
goto retry;
}
}
}
/*用户密码冻结*/
void PassWord_DJ()
{
ZK_MMYDJ();
ZK_GLYMS();
SectorErase(0x0000);
byte_write(0x0001,0);
delay(500);
}
/*用户密码解冻*/
void PassWord_JD()
{ ZK_MMYJD();
ZK_GLYMS();
SectorErase(0x0000);
byte_write(0x0001,1);
delay(500);
}
/*管理员菜单(仅有显示屏菜单显示)*/
void GLY_Password_Meun(uchar menu_num,uchar choose )
{
// OLED_Clear();
// ZK_GLYMS();
switch(menu_num)
{
case 1:
OLED_Show_CHinese(2,Chartxt_4,!(choose==1));
OLED_Show_CHinese(4,Chartxt_5,!(choose==2));
OLED_Show_CHinese(6,Chartxt_6,!(choose==3));
break;
case 2:
OLED_Show_CHinese(2,Chartxt_5,!(choose==2));
OLED_Show_CHinese(4,Chartxt_6,!(choose==3));
OLED_Show_CHinese(6,Chartxt_7,!(choose==4));
break;
}
}
/*用户密码的管理菜单(无法修改管理员密码)*/
void GLY_PassWord_Meum()
{
uchar first_num = 1;
uchar choose_2 = 1;
OLED_num =0;
while(1)
{
GLY_PassWord:ZK_GLYMS();
GLY_Password_Meun(first_num,choose_2);//根据first_num和choose的动态刷新显示函数
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==Sign_out)break;
if(keyscan()==ST_up)
{
choose_2--;
if(choose_2==0)choose_2=1;//选项最少不能小于1
if(choose_2<first_num)first_num--;
}
if(keyscan()==XT_down)
{
choose_2++;
if(choose_2==5)choose_2=4;//选项最大不能大于4
if(choose_2>first_num+2)first_num++;
}
if(keyscan()==Confirm)
{
switch(choose_2)
{
case(1): Use_Password_Change();goto GLY_PassWord;
case(2): PassWord_Reset();goto GLY_PassWord;
case(3): PassWord_DJ();goto GLY_PassWord;
case(4): PassWord_JD();goto GLY_PassWord;
}
}
}
}
/*指纹管理菜单*/
void Fingerprint_Meum()
{
uchar choose_1=1;
OLED_num =-200;
Meun:_nop_();
ZK_GLYMS();
while(1)
{
switch(choose_1)
{
case(1):OLED_Show_CHinese(2,Chartxt_8,0);OLED_Show_CHinese(4,Chartxt_9,1);OLED_Show_CHinese(6,Chartxt_10,1);break;
case(2):OLED_Show_CHinese(2,Chartxt_8,1);OLED_Show_CHinese(4,Chartxt_9,0);OLED_Show_CHinese(6,Chartxt_10,1);break;
case(3):OLED_Show_CHinese(2,Chartxt_8,1);OLED_Show_CHinese(4,Chartxt_9,1);OLED_Show_CHinese(6,Chartxt_10,0);break;
}
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==Sign_out)break;
if(keyscan()==ST_up)//上调按键
{
choose_1--;
if(choose_1==0)choose_1=1;//选项最少不能小于1
}
if(keyscan()==XT_down)
{
choose_1++;
if(choose_1==4)choose_1=3;//选项最大不能大于2
}
if(keyscan()==Confirm)
{
switch(choose_1)
{
case(1): Add_Fingerprint();goto Meun;
case(2): DeletChar();goto Meun;
case(3): goto Meun;
}
}
}
}
void bbxx()
{
OLED_Clear();
while(1)
{
OLED_DrawBMP(32, 0,96,8,BMP1);
if(CLose_OLED)
{
CLose_OLED=0;
OLED_Clear();
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==Sign_out)
{
OLED_num = 0;
Close_T0();
OLED_Clear();
// longjmp (JMP_BUF, 1);//退出
break;
}
}
}
/*管理员菜单*/
void GLY_Menu()
{
uchar choose_1=1;
OLED_num =-200;
Meun:_nop_();
ZK_GLYMS();
while(1)
{
switch(choose_1)
{
case(1):OLED_Show_CHinese(2,Chartxt_1,0);OLED_Show_CHinese(4,Chartxt_2,1);OLED_Show_CHinese(6,Chartxt_3,1);break;
case(2):OLED_Show_CHinese(2,Chartxt_1,1);OLED_Show_CHinese(4,Chartxt_2,0);OLED_Show_CHinese(6,Chartxt_3,1);break;
case(3):OLED_Show_CHinese(2,Chartxt_1,1);OLED_Show_CHinese(4,Chartxt_2,1);OLED_Show_CHinese(6,Chartxt_3,0);break;
}
if(CLose_OLED)
{
CLose_OLED=0;
longjmp (JMP_BUF, 1);
// soft_reset();
}
if(keyscan()==ST_up)//上调按键
{
choose_1--;
if(choose_1==0)choose_1=1;//选项最少不能小于1
}
if(keyscan()==XT_down)//下调按键
{
choose_1++;
if(choose_1==4)choose_1=3;//选项最大不能大于2
}
if(keyscan()==Confirm) //确认
{
switch(choose_1)
{
case(1):GLY_PassWord_Meum();goto Meun;
case(2):Fingerprint_Meum(); goto Meun;
case(3):bbxx(); goto Meun;
}
}
if(keyscan()==Sign_out)
{
OLED_num = 0;
Close_T0();
longjmp (JMP_BUF, 1);//退出
}
}
}
/* 获取当前日期时间,并刷新时间和星期的显示 */
void RefreshTime()
{
uchar xdata str_1[8];
uchar xdata str_2[8];
uchar i;
GetRealTime(&CurTime); //获取当前日期时间
str_1[0] = (CurTime.hour>>4);
str_1[1] = (CurTime.hour&0xF);
str_1[2] = 17;
str_1[3] = (CurTime.min>>4);
str_1[4] = (CurTime.min&0xF);
str_1[5] = 17;
str_1[6] = (CurTime.sec>>4);
str_1[7] = (CurTime.sec&0xF);
for(i=0;i<8;i++)str_2[i]=16;
OLED_Show_Number(32,4,str_1,8,1);
OLED_Show_Number(0,4,str_2,4,1);
OLED_Show_Number(96,4,str_2,4,1);
OLED_Show_Number(32,0,str_2,8,1);
OLED_Show_Number(0,2,str_2,4,1);
OLED_Show_Number(96,2,str_2,4,1);
OLED_ShowCHinese(80,6,65,1);
OLED_ShowCHinese(96,6,66,1);
OLED_ShowCHinese(112,6,67+CurTime.week,1);
ZK_SZXS();
}
/* 日期刷新函数,ops-刷新选项:为0时只当日期变化才刷新,非0则立即刷新 */
void RefreshDate(uchar ops)
{
uchar xdata str[]=0;
static uchar backup = 0;
if ((backup!=CurTime.day) || (ops!=0))
{
str[0] = ((CurTime.year>>12) & 0xF); //4位数年份
str[1] = ((CurTime.year>>8) & 0xF);
str[2] = ((CurTime.year>>4) & 0xF);
str[3] = (CurTime.year & 0xF);
str[4] = 16; //分隔符
str[5] = (CurTime.mon >> 4); //月份
str[6] = (CurTime.mon & 0xF);
str[7] = 16; //分隔符
str[8] = (CurTime.day >> 4); //日期
str[9] = (CurTime.day & 0xF) ;
OLED_Show_Number(0,6,str,10,1);
backup = CurTime.day; //刷新上次日期值
}
}
/*总和函数*/
void Subject()
{
uchar i,error=0;
// ZK_HYGLJGKJ();
if(keyscan() ==GLY) //按下A进入管理员模式
{
GLY_PassWord:_nop_();
OPen_T0(); //开启超时计时
GLY_Password_in(); //输密码
if( GLY_Password_ok==1) //密码输好
{
for(i=0;i<6;i++)
if(AT_password[i]!=GLY_Password[i]) //密码比较
error++;
if(error==0) //密码正确
{
ZK_MMZQMYK();
ZK_GLYMS();
Lock = 0;
delay(50);
Lock = 1;
delay(500);
OLED_Clear();
GLY_Menu();
OLED_Clear();
EX0 = 1;
}
else //密码错误
{
error=0;
ZK_MMCW();
……………………