📄 zlg7289.c
字号:
#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned int//定义I/O 接口sbit SDA=P1^1; //24c02数据端sbit SCL=P1^0; //24c02时钟端sbit error=P1^2; //闭锁指示端sbit right=P1^3; //开锁指示端 和开锁输出sbit CS=P1^5; //片选信号,低电平有效sbit CLK=P1^6; //时钟信号,上升沿有效sbit DIO=P1^7; //数据信号,双向sbit KEY_INT=P3^2; //键盘中断请求信号,低电平(负边沿)有效uchar key=0xFF; //0xFF 表示未按键的状态uchar num=0; //输入密码位数uint timer=1200; //定时计数器bit Lock_Flag=0; //开锁状态标志bit Set_Flag=0; //密码设置标志uchar Pword[6]; //内置密码uchar E_Pword[6]; //密码输入存储uchar Display[6]; //显示缓冲存储uchar code table[]={ 0x01,0x4F,0x12,0x06, //0,1,2,3 0x4C,0x24,0x20,0x0F, //4,5,6,7 0x00,0x04,0x08,0x60, //8,9,A,B 0x31,0x42,0x30,0x38, //C,D,E,F 0x7E,0x7F,0x37 //-,灭,H}; /******************函数声明*******************/void Init_Int(void); //外部中断初始化void Init_Timer0(void); //定时器初始化void ShortDelay(); //延时函数 void LongDelay(); //长延时函数void SPI_Write(uchar dat); //SPI写函数uchar SPI_Read(); //SPI读函数void ZLG7289_Write(uchar cmd, uchar dat);//ZLG7289写命令函数void ZLG7289_Disp(uchar x,uchar dat); //ZLG7289显示函数uchar Keyin(); //ZLG7289读键盘函数void ZLG7289_Init(void); //ZLG7289初始化函数void Compare_Pword(void); //密码比较函数void Enter_Password(void); //密码输入函数void Set_Password(void); //密码设置函数void start_bit(void); //I2C起始位void stop_bit(void); //I2C停止位void mast_ack(void); //I2C应答位bit write_8bit(uchar ch); //I2C写字节函数uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad);//I2C页地址写函数uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad);//I2C页地址读函数/********************主函数*********************/main(){ ZLG7289_Init(); Init_Int(); Init_Timer0(); while(1) { Enter_Password(); //密码输入 Set_Password(); //设置密码 }}/*****************定时初始化函数****************/void Init_Timer0(void){ TMOD=0x01; //设置为工作方式1 TH0=0x3C; //装载初值 TL0=0x0B0; EA=1; //开总中断 ET0=1; //开定时器中断 TR0=1; //启动计时}/****************外部中断初始化*****************/void Init_Int(void){ IT0=1; //负边沿触发中断 EX0=1; //允许外部中断 EA=1;}/**************ZLG7289初始化函数****************/void ZLG7289_Init(void){ CS=1; //I/O 口初始化 CLK=0; DIO=1; KEY_INT=1;}/******************SPI写函数********************/void SPI_Write(uchar dat){ uchar t=8; do { DIO=(bit)(dat&0x80); dat<<=1; CLK=1; ShortDelay(); CLK=0; ShortDelay(); } while(--t!=0);}/******************SPI读函数********************/uchar SPI_Read(){ uchar dat; uchar t=8; DIO=1; //切换到输入状态 do { CLK=1; ShortDelay(); dat<<=1; if(DIO)dat++; CLK=0; ShortDelay(); } while(--t!=0); return dat;}/***************ZLG7289写命令函数****************/void ZLG7289_Write(uchar cmd, uchar dat){ uchar sav=IE; IE&=0xFA; //关闭外部中断 CS=0; LongDelay(); SPI_Write(cmd); LongDelay(); SPI_Write(dat); CS=1; LongDelay(); IE=sav; //恢复IE}/***************ZLG7289显示函数*****************/void ZLG7289_Disp(uchar x,uchar dat){ uchar d1,d2; d1=0x90; //非译码方式 x&=0x07; //显示控制位 d1|=x; d2=table[dat]&0x7F; //显示内容 ZLG7289_Write(d1,d2);}/**************ZLG7289读键盘函数****************/uchar Keyin(){ uchar presskey; CS=0; LongDelay(); SPI_Write(0x15); LongDelay(); presskey=SPI_Read(); CS=1; LongDelay(); return presskey;}/*****************密码输入函数******************/void Enter_Password(void){ uchar i; if(Lock_Flag==0) { if(num<6) //若按键数字键输入小于6次 { if(key<10) //按键为数字键 { key=0xff; E_Pword[num]=key; ZLG7289_Disp(num++,16); //对应显示为"-" timer=1200; } if(key==11) //按键为取消键 { key=0xff; for(i=0;i<6;i++) { ZLG7289_Disp(i,17); //显示为空 num=0; //输入密码计数清零 } timer=1200; } } else { if(key==11) //按键为取消键 { key=0xff; for(i=0;i<6;i++) { ZLG7289_Disp(i,17); //显示为空 num=0; //输入密码计数清零 } timer=1200; } if(key==0x10) //确认键按下 { key=0xff; Compare_Pword(); timer=1200; } } }}/*****************密码比较函数******************/void Compare_Pword(void){ uchar i; while(page_rd(0,6,Pword)==0); //在2402中读取密码 for(i=0;i<6;i++) //比较6位密码 { if(E_Pword[i]!=Pword[i])break; //有1位密码不同时 密码错误 无需再比较 } if(i==6) { Lock_Flag=1; //开锁状态置位 right=1; error=0; //当密码正确时,开锁 for(i=0;i<6;i++) { ZLG7289_Disp(i,0); //显示为"000000" num=0; //输入密码计数清零 } } else { right=0; error=1; //当密码错误时,闭锁 for(i=0;i<6;i++) { ZLG7289_Disp(i,15); //显示为"EEEEEE" num=0; //输入密码计数清零 } }}/*****************密码设置函数******************/void Set_Password(void){ uchar i; if((Lock_Flag==1)&(key==12)) // { key=0xff; Set_Flag=1; timer=1200; } if(Set_Flag==1) //设置密码 { key=0xff; if(num<6) //6位新密码没有输入 { if(key<10) //按键为数字键 { key=0xff; E_Pword[num]=key; ZLG7289_Disp(num++,16); //对应显示为"-" timer=1200; } if(key==11) //按键为取消键 { key=0xff; for(i=0;i<6;i++) { ZLG7289_Disp(i,17); //显示为空 num=0; //输入密码计数清零 } timer=1200; } } else { if(key==11) //按键为取消键 { key=0xff; for(i=0;i<6;i++) { E_Pword[i]=0; ZLG7289_Disp(i,17); //显示为空 num=0; //输入密码计数清零 } timer=1200; } if(key==0x10) //按下确认键 { for(i=0;i<6;i++) { key=0xff; Pword[i]=E_Pword[i]; while(page_wr(0,6,Pword)==0); //新密码写入24lc02 Set_Flag=0; //新密码设置完成 for(i=0;i<6;i++) { ZLG7289_Disp(i,18); //显示为"HHHHHH" num=0; //输入密码计数清零 } timer=1200; } } } }}/*******************I2C起始位******************/void start_bit(void){ SCL=1;_nop_(); SDA=1;_nop_(); SDA=0;_nop_(); SCL=0;_nop_();}/*******************I2C停止位******************/void stop_bit(void){ SDA=0;_nop_(); SCL=1;_nop_(); SDA=1;_nop_();}/*******************I2C应答位******************/void mast_ack(void){ SCL=0;_nop_(); SDA=0;_nop_(); SCL=1;_nop_(); SCL=0;_nop_(); SDA=1;_nop_();}/*****************I2C写字节函数****************/bit write_8bit(uchar ch){ uchar i=8; bit fan_w; SCL=0;_nop_(); while(i--) { SDA=(bit)(ch&0x80); //取字节的最高位 _nop_(); ch<<=1; //字节左移一位 SCL=1;_nop_(); //上升沿锁存数据 SCL=0;_nop_(); } SDA=1;_nop_(); SCL=1;_nop_(); fan_w=SDA; //读应答信号 SCL=0;_nop_(); return(fan_w); //返回应答信号}/*****************I2C页地址写函数****************/uchar page_wr(uint firstw_ad,uint counter,uchar *firstr_ad){ uchar data *ufirstr_ad; ufirstr_ad=firstr_ad; start_bit(); //写开始位 if(write_8bit(0xA0)!=0) { stop_bit(); return(0); } //写命令 if(write_8bit(firstw_ad)!=0) { stop_bit(); return(0); } //写首地址 while(counter--) //写字节数减1 { if(write_8bit(*ufirstr_ad)!=0) { stop_bit(); return(0); } //写1字节 ufirstr_ad++; //地址加1 } stop_bit(); //写停止位 return(1);}/*****************I2C页地址读函数****************/uchar page_rd(uint firstrd_ad,uint count,uchar *firstwr_ad){ uchar j=8; uchar data *ufirstwr_ad; ufirstwr_ad=firstwr_ad; start_bit(); //写开始位 if(write_8bit(0xA0)!=0) { stop_bit(); return(0); } //写命令 if(write_8bit(firstrd_ad)!=0) { stop_bit(); return(0); } //写首地址 start_bit(); //写开始位 if(write_8bit(0xA1)!=0) { stop_bit(); return(0); } //读命令 while(count--) //读字节数减1 { uchar i=8; while(i--) { (*ufirstwr_ad)<<=1; //读对应地址的数据左移 SCL=1;_nop_(); //上升沿 if(SDA) (*ufirstwr_ad)|=0x01; //数据端为1时 存1 SCL=0;_nop_(); } ufirstwr_ad++; //地址加1 mast_ack(); //应答信号 } while(j--) { (*ufirstwr_ad)<<=1; SCL=0;_nop_();_nop_();SCL=1; if(SDA) (*ufirstwr_ad)|=0x01; } stop_bit(); //写停止位 return(1);}/****************定时中断服务函数****************/void Timer0(void) interrupt 1{ uchar i; TH0=0x3C; //重载初值 TL0=0x0B0; if(timer--==0) { Lock_Flag=0; Set_Flag=0; right=0; error=1; //闭锁 for(i=0;i<6;i++) { ZLG7289_Disp(i,17); //显示为空 num=0; //输入密码计数清零 } }}/*******************键盘中断********************/void INT0_DEAL() interrupt 0{ key=Keyin(); //读入按键键值}/******************短延时函数*******************/void ShortDelay() { uchar t=8; while(--t!=0);}/*******************长延时函数*******************/void LongDelay() { uchar t=40; while (--t!=0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -