AT24C02.C
#include <reg51.h>
#include "AT24C02.h"
sbit AT24C02_SDA = P3^6; //定义数据线
sbit AT24C02_SCL = P3^7; //定义时钟线
{ uchar i;
for(i=0; i<200; i--);
}
void I2C_Start()
{ AT24C02_SDA = 1; delay();
AT24C02_SCL = 1; delay();
AT24C02_SDA = 0; delay();
AT24C02_SCL = 0;
} //钳位I2C总线,准备发送数据
void I2C_Stop()
{ AT24C02_SDA = 0; delay();
AT24C02_SCL = 1; delay();
AT24C02_SDA = 1; delay();
}
void Ack()
{ AT24C02_SDA = 0; delay();
AT24C02_SCL = 1; delay();
AT24C02_SCL = 0; delay();
AT24C02_SDA = 1; delay();
}
void NoAck()
{ AT24C02_SDA = 1; delay();
AT24C02_SCL = 1; delay();
AT24C02_SCL = 0; delay();
}
uchar Test_Ack()
{ uchar flag;
AT24C02_SDA=1;//读入数据
delay();
if(AT24C02_SDA==1)
flag=0x01;
else flag=0x00;
AT24C02_SCL=0; delay();
AT24C02_SCL=1; delay();
AT24C02_SCL=0;
return(flag);
}
void SendData(uchar buffer)
{ uchar BitCnt=8;//一字节8位
uchar temp=0;
do
{ temp=buffer;
AT24C02_SCL=0; delay();
if((temp&0x80)==0) //判断最高位是0还是1
AT24C02_SDA=0;
else AT24C02_SDA=1; delay();
AT24C02_SCL=1;
temp=buffer<<1; //将buffer中的数据左移一位
buffer=temp;
BitCnt--;
}
while(BitCnt);
AT24C02_SCL=0;
AT24C02_SDA=1;
}
uchar ReceiveData()
{ uint BitCnt=8;
uchar temp=0;
uchar ucReceData;
AT24C02_SDA=1; //读入数据
do { AT24C02_SCL=0; delay();
AT24C02_SCL=1; delay();
if(AT24C02_SDA==1) ucReceData=ucReceData|0x01;//低位置1
else ucReceData=ucReceData&0x0fe;//低位清0
if(BitCnt-1)
{ temp=ucReceData<<1;//数据左移一位
ucReceData=temp;
}
BitCnt--;
}
while(BitCnt);
AT24C02_SCL=0;
return(ucReceData);
}
uchar WriteNByte(uchar sla,uchar suba,uchar *s,uchar n)
{ uchar i;
uchar flag;
I2C_Start(); //启动I2C
SendData(sla); //发送器件地址
flag = Test_Ack();
if(flag != 0x00)
{ return 0;
}
SendData(suba); //发送器件内部寄存器地址
flag = Test_Ack();
if(flag != 0x00)
{ return 0;
}
for(i=0; i<n; i++) //写入n字节数据
{ SendData(s);
flag = Test_Ack();
if(flag != 0x0 return 0;
} }
I2C_Stop();
return 1;
}
uchar ReadNByte(uchar sla,uchar suba,uchar *p,uchar n)
{ uchar i;
uchar flag; //测试n是否为有效值
if(n > 8)
{ return 0;
}
I2C_Start(); //启动I2C
SendData(sla); //发送器件地址
flag = Test_Ack();
if(flag != 0x00)
{ return 0;
}
SendData(suba); //发送器件内部地址
flag = Test_Ack();
if(flag != 0x00)
{ return 0;
}
I2C_Start();
SendData(sla+1);
flag = Test_Ack();
if(flag != 0x00){ return 0;
}
for(i=0; i<n-1; i++) //读取字节数据
{ p = ReceiveData(); //读取数据
Ack();
}
p[n-1] = ReceiveData();
NoAck();
I2C_Stop();
return 1;
}
KEY.H
#include"reg51.h"
#include"key.h"
#include "AT24C02.h"
#include"LCD_1602.h"
#define uchar unsigned char
#define uint unsigned int
#define Key_in P1=0x0f
#define Key_pin P1
sbit OUT2=P3^1;
sbit OUT1=P3^0;
uchar code key_scan_tap[4]={0x1f,0x2f,0x4f,0x8f};
uchar code Led_dsp_tap[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code key_code_tap[16]= { 0x1e,0x1d,0x1b,0x17,
0x2e,0x2d,0x2b,0x27,
0x4e,0x4d,0x4b,0x47,
0x8e,0x8d,0x8b,0x87
};
uchar new_key;
uchar old_key;
uchar key_cont;
uchar key;
uchar input_cont;
uchar input_cont2;
uchar input_step;
uchar err_cont[8]; //各用户密码输入数错计数器
uchar ID_stop_delay[8]; //用于保存各用户出错锁键盘时间
uchar ID_keep_buf[8]={10,10,10,10,10,10,10,7}; //用户ID缓冲区
uchar ID;
uchar input_password[4]={0};
uchar input_password2[4]={0};
uchar input_password3[4]={0};
uchar password[4];
uchar keep_password[8][4];
uchar OUT1_delay;
uint moto_run_cont;
uchar run_fx;
uchar moto_cont;
uchar POWER;
struct key_flag
{ unsigned password_in:1;
unsigned keep:1;
unsigned open:1;
unsigned redly_keep:1;
unsigned call_open:1;
unsigned ID_OK:1;
unsigned control_en:1;
unsigned control_input:1;
}
key_flag;
extern uchar sec;
extern uchar beef_cont;
extern uchar dsp_buf[1];
void moto_control(uchar cont,uchar fx)
{ moto_run_cont=cont*8;
run_fx=fx;
void key_control(void)
{ uchar i; //以下为存物操作
if(key==15)
{ for(i=0;i<7;i++)
ID_keep_buf=10;
if(WriteNByte(0xa0,40,ID_keep_buf,7)==1)
{ beef_cont=0x81;
dsp_buf[0]=0xff;
sec=3;
OUT2=0;
}
else beef_cont=3;
}
if(key==14)
{ POWER=POWER^0x01;
WRITE_ML(0x01); // 清显示
if(POWER==1)
{ lcd_dsp(0,4,"Lockers",7);
}
input_cont2=0;
key_flag.ID_OK=0;
key_flag.open=0;
key_flag.call_open=0;
input_step=0;
input_cont=0;
key_flag.keep=0;
key_flag.redly_keep=0;
}
if(POWER==1)
{ if(key_flag.control_en==0)
{ if((key_flag.keep==1)&&(ID!=8))
{ if(key<=9)
{ beef_cont=1;
sec=0;
if((input_cont<4)&&(input_step==0))
{ input_password[input_cont]=key;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
for(i=0;i<=input_cont;i++) lcd_dsp(1,9+i,"*",1);
input_cont++;
}
else if((input_cont<4)&&(input_step==1))
{ input_password2[input_cont]=key;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
for(i=0;i<=input_cont;i++) lcd_dsp(1,9+i,"*",1);
input_cont++;
} }
else if(key==13) //取消键
{ beef_cont=1;
sec=0;
if((input_cont>0)&&(input_step==0))
{ input_cont-input_password[input_cont]=0;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
if(input_cont>0)
{ for(i=0;i<=input_cont-1;i++)
lcd_dsp(1,9+i,"*",1); } }
else if((input_cont>0)&&(input_step==1))
{
input_password2[input_cont]=0;
input_cont--;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
if(input_cont>0)
{
for(i=0;i<=input_cont-1;i++)
lcd_dsp(1,9+i,"*",1);
} } }
else if(key==10)
{
if((input_cont==4)&&(input_step==0))
{ input_step=1;
input_cont=0; }
else if((input_cont==4)&&(input_step==1))
{
for(i=0;i<4;i++)
{ if(input_password2==input_password)
{ ; }
else //密码核对匹配
{
beef_cont=0x03;
input_step=0;
input_cont=0;
i=5;
} }
if(i==4) //密码核对成功
{
input_step=0;
input_cont=0;
key_flag.keep=0;
key_flag.redly_keep=0;
for(i=0;i<4;i++)
keep_password[ID]=input_password2; //保存用户密码
ID_keep_buf[ID]=ID;
if(WriteNByte(0xa0,40,ID_keep_buf,7)==1)
{
beef_cont=0x81;
for(i=0;i<60;i++)
delay();
if(WriteNByte(0xa0,ID*4,input_password2,4)==1)
{ beef_cont=0x81;
dsp_buf[0]=dsp_buf[0]&Led_dsp_tap[ID];//指示对应柜已占用
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(1,0,"successfully",12);
sec=5;
moto_control(8,1);
if(ID==1)
{
OUT2=1;
} } } } } }
else if(key_flag.keep==0)
{ if(key==11)
{ input_cont2=0;
key_flag.ID_OK=0;
key_flag.open=0;
key_flag.call_open=0;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
sec=0;
for(i=0;i<6;i++)
{ if(ID_keep_buf==10)
{ ID=i;
i=6;
key_flag.redly_keep=1;
}
else
{ ID=8;
} } }
else if(key==10)
{
beef_cont=1;
if(key_flag.redly_keep==1)
{
key_flag.keep=1;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"save",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
} } }
//取物
if(key_flag.open==1){
if(key<=9)
{ beef_cont=1;
sec=0;
if((input_cont2<4)&&(err_cont[ID]<3)){
input_password3[input_cont2]=key;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"open",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
for(i=0;i<=input_cont2;i++)
lcd_dsp(1,9+i,"*",1);
input_cont2++;
} }
else if(key==13) //取消键
{ beef_cont=1;
sec=0;
if((input_cont2>0)&&(input_step==0))
{ input_cont2--;
input_password3[input_cont2]=0;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"open",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
if(input_cont2>0)
{
for(i=0;i<=input_cont2-1;i++)
lcd_dsp(1,9+i,"*",1);
} } }
else if(key==10){
if(input_cont2==4){
for(i=0;i<4;i++) {
if(keep_password[ID]==input_password3){
; }
else {
i=5;
} }
if(i==4)
{
ID_keep_buf[ID]=10;
input_cont2=0;
key_flag.ID_OK=0;
key_flag.open=0;
key_flag.call_open=0;
if(WriteNByte(0xa0,40,ID_keep_buf,7)==1)
beef_cont=0x81;
err_cont[ID]=0;
if(ID<6) dsp_buf[0]=dsp_buf[0]|(Led_dsp_tap[ID]^0xff);
if(ID==6)
{ key_flag.control_en=1 ;
}
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"open",4);
lcd_dsp(1,0,"successfully",12);
sec=5;
moto_control(8,0);
if(ID==0){
OUT1_delay=5; }
else if(ID==1)
{ OUT2=0;
} }
else
{ err_cont[ID]++;
if(err_cont[ID]>=3)
{ input_cont2=0;
key_flag.ID_OK=0;
key_flag.open=0;
key_flag.call_open=0;
ID_stop_delay[ID]=30;
}
else
{ input_cont2=0; }
beef_cont=3;
WRITE_ML(0x01); // 清显示
lcd_dsp(1,0,"Password Error",14);
sec=0;
}
input_cont2=0;
} } }
else {
if(key==12){ beef_cont=1;
key_flag.call_open=1;
input_step=0;
input_cont=0;
key_flag.keep=0;
key_flag.redly_keep=0;
key_flag.ID_OK=0;
key_flag.open=0;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"open",4);
lcd_dsp(0,8,"on:",3);
sec=0;
}
else if(key<8){
beef_cont=1;
sec=0;
if(key_flag.call_open==1)
{ ID=key;
if((ID<=7)&&(ID_keep_buf[ID]==ID)&&(ID_stop_delay[ID]==0))
{ key_flag.ID_OK=1;
}}}
else if(key==10)
{
if(key_flag.ID_OK==1)
{
key_flag.open=1;
WRITE_ML(0x01);// 清显示
lcd_dsp(0,0,"open",4);
lcd_dsp(0,8,"on:",3);
lcd_no_write(0,11,ID,1);
lcd_dsp(1,0,"passwrod",8);
}}}}
else { if(key<6)
{ ID=key;
beef_cont=1;
if(ID_keep_buf[ID]==ID)
{ key_flag.control_input=1;
}}
else if((key==10)&&(key_flag.control_input==1))
{
beef_cont=1;
key_flag.control_en=0;
ID_keep_buf[ID]=10;
dsp_buf[0]=dsp_buf[0]|(Led_dsp_tap[ID]^0xff);
}}}}
void key_scan(void)
{ uchar i,j;
uchar key_buf; //暂存键值变量
Key_in; //让读键引脚P10~P13为高电平
old_key=new_key; //保存上次键值
new_key=Key_pin&0x0f;//保存当前键值
if(old_key==new_key) //如果键状态没有发生变化,
{ if(key_cont<100) key_cont++; //消抖动计数器加1
if(key_cont==5) //消抖动成功,表示确实有键按下,或松键
{ //以下进行循环扫描
for(i=0;i<4;i++){
Key_pin=key_scan_tap; //逐行扫描
if((Key_pin&0x0f)!=new_key){ //逐行判断 key_buf=(key_scan_tap&0xf0)|new_key;//得到键值
for(j=0;j<16;j++){
if(key_code_tap[j]==key_buf) // 查内码
{
key=j;//查得内码
key_control(); //调键值管理函数
j=17;
}
i=4;
}}}}
else{
key_cont=0;
}}
LCD1602.C
#include"reg51.h"
#include"LCD_1602.h"
#define uchar unsigned char
#define uint unsigned int
sbit RW=P3^2;
sbit RS=P3^3;
sbit E_LCD=P3^1;
sbit BUSY=P2^7;
char code LCD_TAP[10]={"0123456789"};
void delay_1602(unsigned int i) //延时函数
{ while(i--); }
void PAN_BUSY(void) //判忙子程序
{
P2=0xFF;
RS=0;
RW=1;
E_LCD=0;
delay_1602(1);
E_LCD=1;
while(BUSY==1){; }}
void WRITE_ML(uchar m) //写命令子程序
{ P2=m;
RS=0;
RW=0;
E_LCD=0;
PAN_BUSY();
E_LCD=1;
}
void WRITE_DAT(uchar dat) //写数据子程序
{ P2=dat;
RS=1;
RW=0;
E_LCD=0;
PAN_BUSY();
E_LCD=1;
}
void lcd_dsp(uchar l,uchar h,char a[],uchar n)
{
uchar i;
if(l==0){
WRITE_ML(0x80+h);
for(i=0;i<n;i++)
WRITE_DAT(a);
}
else if(l==1){
WRITE_ML(0xc0+h);
for(i=0;i<n;i++)
WRITE_DAT(a);
} }
void lcd_no_write(uchar l,uchar h,uchar cont,uchar n)
{
uchar i;
if(l==0)
{
WRITE_ML(0x80+h);
for(i=0;i<n;i++)
WRITE_DAT(LCD_TAP[cont]) ;
}
else if(l==1){
WRITE_ML(0xc0+h);
for(i=0;i<n;i++) WRITE_DAT(LCD_TAP[cont]);
} }
void LCD_1602_init(void)
{ delay_1602(100);
WRITE_ML(0x01); // 清显示
WRITE_ML(0x38); // 8位点阵 允许双行显示
WRITE_ML(0x0a); // 开显示
WRITE_ML(0x80); //第一行显示
delay_1602(100);
WRITE_ML(0x01); // 清显示
WRITE_ML(0x38); // 8位点阵 允许双行显示
WRITE_ML(0x0C); // 开显示
WRITE_ML(0x80);
}
//main程序
#include"reg51.h"
#include"key.h"
//#include"dsp.h"
#include "AT24C02.h"
#include"LCD_1602.h"
#define uchar unsigned char
#define uint unsigned int
#define THO_int 0xff
#define TL0_int 24
#define TMOD_int 0x01
#define TCON_int 0x10
sbit BUZ =P3^0;
uint beef_delay;
uchar beef_cont;
uchar timecont_4ms;
uchar timecont_10ms;
uchar timecont_1s;
uchar time_1000ms;
extern uint moto_run_cont;
extern uchar run_fx;
extern uchar moto_cont;
uchar code Led_dsp_tap2[6]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
uchar code Led_tap[6]={0x01,0x02,0x04,0x08,0x10,0x20};
uchar code moto_tap[8]={0x20,0x60,0x40,0x50,0x10,0x90,0x80,0xa0};
extern uchar err_cont[8];
extern uchar ID_stop_delay[8];
uchar dsp_buf[1];
extern uchar password[4];
extern uchar ID_keep_buf[8];
extern uchar keep_password[8][4];
extern uchar password[4];
extern uchar OUT1_delay;
uchar sec;
extern uchar POWER;
uchar SYS_clock;
struct flag
{ unsigned beef_en:1;
unsigned dsp_control_en:1;
unsigned out_time_en:1;
}
flag1; //蜂鸣器管理
void beef_control(void)
{
if(beef_delay==0)
{
if(flag1.beef_en==1){ flag1.beef_en=0; //停止响蜂鸣器
beef_delay=20; //蜂鸣器间隔时间
}
else{
if(beef_cont&0x0f)//如果响蜂鸣次数还没有结束
{ beef_cont--;
beef_delay=10; //响蜂鸣时间
if(beef_cont&0x80) beef_delay=80;
flag1.beef_en=1;//开启响蜂鸣器
} } } }
void out_time(void)
{
if(flag1.out_time_en==1)
{
flag1.out_time_en=0;
if(sec){
sec--;
if(sec==0) {
WRITE_ML(0x01);// 清显示
lcd_dsp(0,4,"Lockers",7);
} } } }
void T0_int(void)
{ TMOD=TMOD_int;
TCON=TCON_int;
TL0=TL0_int;
TH0=THO_int;
ET0=1;
EA=1;
}
//单片机初始化
void MCU_init(void)
{ P1=0xff;
P2=0xff;
P3=0xff;
} //响1声蜂鸣器
//定时器中断
void timer0_(void)interrupt 1 using 1 //定时器溢出周期为100us已加入16t
{
uchar temp,i,P3_buf;
TR0=0;//
TL0=TL0_int;
TH0=THO_int;
TR0=1;
if(flag1.beef_en){ BUZ=!BUZ; }
else BUZ=1;
timecont_4ms++;
if(timecont_4ms>=16)
{
SYS_clock=1;
timecont_4ms=0;
if(moto_run_cont)
{
moto_run_cont--;
moto_cont++;
if(moto_cont>=8){ moto_cont=0; }
P3_buf=P3&0x0f;
if(run_fx)
P3=P3_buf|moto_tap[7-moto_cont];
else
P3=P3_buf|moto_tap[moto_cont];
}
else { P3=P3&0x0f; }
if(beef_delay)
beef_delay--;
temp=dsp_buf[0];
for(i=0;i<6;i++)
{
if(temp&0x01)
P0=P0|Led_tap;
else
P0=P0&Led_dsp_tap2;
temp=temp>>1;
}
time_1000ms++;
if(time_1000ms>=250)
{ time_1000ms=0;
if(OUT1_delay){ OUT1_delay--;
if(OUT1_delay==0);
} } }
timecont_10ms++;
if(timecont_10ms>=40){
timecont_10ms=0;
timecont_1s++;
if((timecont_1s>=100)&&(POWER)){
timecont_1s=0;
flag1.out_time_en=1;
if(ID_stop_delay[0]>0){
ID_stop_delay[0]--;
if(ID_stop_delay[0]==0)
{
err_cont[0]=0;
} }
if(ID_stop_delay[1]>0){
ID_stop_delay[1]--;
if(ID_stop_delay[1]==0)
{
err_cont[1]=0;
} }
if(ID_stop_delay[2]>0){
ID_stop_delay[2]--;
if(ID_stop_delay[2]==0)
{
err_cont[2]=0;
} }
if(ID_stop_delay[3]>0){
ID_stop_delay[3]--;
if(ID_stop_delay[3]==0)
{
err_cont[3]=0;
} }
if(ID_stop_delay[4]>0){
ID_stop_delay[4]--;
if(ID_stop_delay[4]==0)
{
err_cont[4]=0;
} }
if(ID_stop_delay[5]>0){
ID_stop_delay[5]--;
if(ID_stop_delay[5]==0)
{
err_cont[5]=0;
} }
if(ID_stop_delay[6]>0){
ID_stop_delay[6]--;
if(ID_stop_delay[6]==0)
{
err_cont[6]=0;
} } } } }
void main(void)
{
uchar i;
POWER=1;
dsp_buf[0]=0xff;
MCU_init();
T0_int();
for(i=0;i<7;i++) ID_keep_buf=10;
if(ReadNByte(0xa0,0,password,4)==1)
for(i=0;i<4;i++) keep_password[0]=password;
if(ReadNByte(0xa0,4,password,4)==1)
for(i=0;i<4;i++) keep_password[1]=password;
if(ReadNByte(0xa0,8,password,4)==1)
for(i=0;i<4;i++) keep_password[2]=password;
if(ReadNByte(0xa0,12,password,4)==1)
for(i=0;i<4;i++) keep_password[3]=password;
if(ReadNByte(0xa0,16,password,4)==1)
for(i=0;i<4;i++) keep_password[4]=password;
if(ReadNByte(0xa0,20,password,4)==1)
for(i=0;i<4;i++) keep_password[5]=password;
if(ReadNByte(0xa0,24,password,4)==1)
for(i=0;i<4;i++) keep_password[6]=password;
if(ReadNByte(0xa0,40,ID_keep_buf,7)==1)
beef_cont=3;
for(i=0;i<6;i++)
{ if(ID_keep_buf==i)
dsp_buf[0]=dsp_buf[0]&Led_dsp_tap2;
if(ID_keep_buf[1]==1){; }
}
LCD_1602_init();
WRITE_ML(0x01); // 清显示
lcd_dsp(0,4,"Lockers",7);
for(;;) {
if(SYS_clock)
{ SYS_clock=0;
key_scan();
out_time();
beef_control();
}
}
}