资源描述
#include "1302.h"
void write_ds1302_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
T_IO=dat&0x01;
T_CLK=1;
T_CLK=0;
dat=dat>>1;
}
}
uchar read_ds1302_byte()
{
uchar i;
for(i=0;i<8;i++)
{
ACC=ACC>>1;
ACC7=T_IO;
T_CLK=1;
T_CLK=0;
}
return (ACC);
}
void write_ds1302_dat(uchar addr,uchar dat)
{
T_EN=0;
T_CLK=0;
T_EN=1;
write_ds1302_byte(addr);
write_ds1302_byte(dat);
T_CLK=1;
T_EN=0;
}
uchar read_ds1302_data(uchar addr)
{
uchar date;
T_EN=0;
T_CLK=0;
T_EN=1;
write_ds1302_byte(addr);
date=read_ds1302_byte();
T_EN=0;
T_CLK=0;
return (date);
}
void set_real_time(uchar *pclock)
{
uchar i,addr=0x80;
EA=0;
write_ds1302_dat(0x8e,0x00);
for(i=0;i<7;i++)
{
write_ds1302_dat(addr,*pclock);
pclock++;
addr+=2;
}
// write_ds1302_dat(0x8e,0x80);
EA=1;
}
void get_real_time(uchar Curtime[])
{
uchar j;
uchar address=0x81;
EA=0;
for(j=0;j<7;j++)
{
Curtime[j]=read_ds1302_data(address);
address+=2;
}
EA=1;
}
#ifndef __1302_H__
#define __1302_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit T_IO=P2^5;
sbit T_CLK=P2^4;
sbit T_EN=P1^0;
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
void write_ds1302_byte(uchar dat);
uchar read_ds1302_byte();
void write_ds1302_dat(uchar addr,uchar dat);
uchar read_ds1302_data(uchar addr);
void set_real_time(uchar *pclock);
void get_real_time(uchar Curtime[]);
#endif
#include "delay.h"
#include "1602.h"
void lcd_busy_wait() /*LCD1602 忙等待*/
{
lcd_rs_port = 0;
lcd_rw_port = 1;
lcd_en_port = 1;
lcd_data_port = 0xff;
while (lcd_data_port&0x80);
lcd_en_port = 0;
}
void write_com(uchar command) /*LCD1602 命令字写入*/
{
lcd_busy_wait();
lcd_rs_port = 0;
lcd_rw_port = 0;
lcd_en_port = 0;
lcd_data_port = command;
lcd_en_port = 1;
lcd_en_port = 0;
}
void write_data(uchar dat)
{
lcd_busy_wait();
lcd_rs_port=1;
lcd_rw_port =0;
lcd_en_port=0;
P0=dat;
lcd_en_port=1;
lcd_en_port=0;
}
void wtite_lcd_1602_dat(uchar x_pos,uchar y_pos,uchar dat)
{
x_pos&=0x0f;
y_pos&=0x01;
if(y_pos==0)
{
x_pos=x_pos+0x80;
}
else
{
x_pos=x_pos+0x80+0x40;
}
write_com(x_pos);
lcd_busy_wait();
lcd_rs_port=1;
lcd_rw_port=0;
lcd_en_port=0;
P0=dat;
lcd_en_port=1;
lcd_en_port=0;
}
void lcd_init() /*LCD1602 初始化*/
{
lcd_delay(20);
write_com(0x38);
lcd_delay(100);
write_com(0x38);
lcd_delay(50);
write_com(0x38);
lcd_delay(10);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
lcd_data_port = 0xff; /*释放数据端口*/
}
#ifndef __1602_H__
#define __1602_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit lcd_rs_port=P3^5;
sbit lcd_rw_port=P3^6;
sbit lcd_en_port=P3^4;
#define lcd_data_port P0
void lcd_busy_wait();
void write_com(uchar command);
void write_data(uchar dat);
void wtite_lcd_1602_dat(uchar x_pos,uchar y_pos,uchar dat);
void lcd_init();
#endif
#include "2402.h"
#include "delay.h"
void i2c_start()
{
scl=1;
delay1();
sda=1;
delay1();
sda=0;
delay1();
}
void i2c_stop()
{
sda=0;
delay1();
scl=1;
delay1();
sda=1;
delay1();
}
void i2c_ack()
{
uchar i;
scl=1;
delay1();
while((sda==1)&&(i<250)) i++;
scl=0;
delay1();
}
void i2c_nack()
{
scl=1;
delay1();
sda=1;
scl=0;
delay1();
}
void i2c_write_byte(uchar date)//
{ //
uchar i,temp;
temp=date;
for(i=0;i<8;i++)//
{ //
temp=temp<<1;//
scl=0; //
delay1();; //
sda=CY;//
delay1();//
scl=1;//
} //
scl=0; //
delay1();//
sda=1;//
delay1();//
}//
uchar i2c_read_byte()
{
uchar i,temp=0;
scl=0;
// delay1();;
// sda=1;
delay1();
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=1;
delay1();
temp=temp|sda;
scl=0;
delay1();
}
return (temp);
}
void write_at2404(uchar addr,uchar dat)
{
i2c_start();
i2c_write_byte(0xa0);
i2c_ack();
i2c_write_byte(addr);
i2c_ack();
i2c_write_byte(dat);
i2c_ack();
i2c_stop();
delay3(5000);
}
uchar read_at2402(uchar addr)
{
uchar temp;
i2c_start();
i2c_write_byte(0xa0);
i2c_ack();
i2c_write_byte(addr);
i2c_ack();
i2c_start();
i2c_write_byte(0xa1);
i2c_ack();
temp=i2c_read_byte();
i2c_nack();
i2c_stop();
return (temp);
}
#ifndef __2402_H__
#define __2402_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit scl=P2^1;
sbit sda=P2^0;
void i2c_start();
void i2c_stop();
void i2c_ack();
void i2c_nack();
void i2c_write_byte(uchar);
uchar i2c_read_byte();//
void write_at2404(uchar addr,uchar dat);
uchar read_at2402(uchar addr);
#endif
#include"delay.h"
void delay(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=200;b>0;b--);
}
void lcd_delay(uchar ms)
{
uchar j;
while(ms--){
for(j=0;j<250;j++)
{;}
}
}
void delay1()
{ ; ;}
void delay3(uint q)
{
uint e;
for(e=0;e<q;e++);
}
#ifndef __DELAY_H__
#define __DELAY_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void delay(uchar x);
void lcd_delay(uchar ms);
void delay1();
void delay3(uint m);
#endif
#include "display.h"
void display()
{
P0=0;
dula=1;
dula=0;
P0=0x7f;
wela=1;
wela=0;
}
#ifndef __DISPLAY_H__
#define __DISPLAY_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^7;
void display();
#endif
#include "delay.h"//一般放在最前面 这个前后由调用先后决定着
#include "scan.h"
#include "1602.h"
//extern void write_data(uchar dat);
//extern void write_com(uchar command);
uchar key;
uchar temp,count,aa,bb,cc; /*一般将这些变量定义在C文件中
当主函数需要时用extern引用 */
bit shu_flag,modify_flag,rst;
bit fun_flag; //功能键标志位 没使用
bit down_flag,up_flag,open_flag;
void keyscan()
{
P1=0xfe;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(15);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xee: key=0;shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0xde: key=1;shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0xbe: key=2;shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0x7e: key=3;shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
// beep=0;
delay(500);
}
// beep=1;
// write_data('*');count++;
}
while(temp!=0xf0);
{
temp=P1;
temp=temp&0xf0;
}
}
P1=0xfd;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(15);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{
case 0xed: shu_flag=1;key=4;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break; //aa,bb,cc定时器中使用
case 0xdd: shu_flag=1;key=5;write_data('*'); //每次按键清零
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break; //保证在按键器件不会自动返回
case 0xbd: shu_flag=1;key=6;write_data('*'); //
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0x7d: shu_flag=1;key=7;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
// beep=0;
delay(500); // 松手检测 屏蔽蜂鸣器 噪音污染
}
// beep=1;
// write_data('*');count++;
}
}
P1=0xfb;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(15);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{ //fun_flag 功能键标志位
case 0xeb: key=8; shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0xdb: key=9; shu_flag=1;write_data('*');
count++;if(count>6) count=0;aa=0;bb=0;cc=0;break;
case 0xbb: modify_flag=1;fun_flag=1;aa=0;bb=0;cc=0;break; //修改键
case 0x7b: rst=1;fun_flag=1;aa=0;bb=0;cc=0;break; //返回键
}
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
// beep=0;
delay(500);
}
// beep=1;
}
}
P1=0xf7;
temp=P1;
temp=temp&0xf0;
if(temp!=0xf0)
{
delay(15);
if(temp!=0xf0)
{
temp=P1;
switch(temp)
{ //清除键
case 0xe7: //key=12;shu_flag=1;break;
aa=0;bb=0;cc=0;
switch(count)
{
case 1: write_com(0x80+0x40+5);write_data(' ');write_com(0x80+0x40+5);break;
case 2: write_com(0x80+0x40+6);write_data(' ');write_com(0x80+0x40+6);break;
case 3: write_com(0x80+0x40+7);write_data(' ');write_com(0x80+0x40+7);break;
case 4: write_com(0x80+0x40+8);write_data(' ');write_com(0x80+0x40+8);break;
case 5: write_com(0x80+0x40+9);write_data(' ');write_com(0x80+0x40+9);break;
case 6: write_com(0x80+0x40+0x0a);write_data(' ');write_com(0x80+0x40+0x0a);break;
}
case 0xd7: key=13;up_flag=1;fun_flag=1;aa=0;bb=0;cc=0;break; //开门键
case 0xb7: key=14;down_flag=1;fun_flag=1;aa=0;bb=0;cc=0;break;
case 0x77: key=13;open_flag=1;fun_flag=1;aa=0;bb=0;cc=0;break;
while(temp!=0xf0)
{
temp=P1;
temp=temp&0xf0;
// beep=0;
delay(500);
}
// beep=1;
if(count>0) count--;break;
} //清除数字
}
}
}
#ifndef __SCAN_H__
#define __SCAN_H__
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void keyscan();
#endif
/***********************************************************
名称:电子密码锁
时间:2014年8月2日 16:33:48 WRITE BY:Kengkeng
Today is Valentine's Day
程序功能:
1 :开机1302显示时间,按下key15:开门键 进入输入密码界面
2 :输入密码 输入错误超过三次 电子锁锁死 倒计时60s之后重新设置 蜂鸣器快速响
3 :输入正确 进入菜单页面 两个选择 key13:开门 key10:修改密码
4 :修改已输入密码 可由key12键清除 重新输入
5 :选择key13开门 打开继电器 显示倒计时15s开门 蜂鸣器慢响 提示15s内开门
否则15后关门 关闭继电器 并自动返回时间页面
6 :选择key10修改密码 共两次 两次密码一致时设置成功 否则会一直提示输入密码
7 :修改的密码存入2402中 上电读出
8 :修改密码 无限循环 直到输入正确为止 可以使用key11:返回键 返回
9 :在10s内无任何按键按下时 自动返回时间页面 可重新进入
10:在20s内无任何按键按下时 进入掉电模式 外部中断唤醒
键盘列表:
00 01 02 03
04 05 06 07
08 09 修改 返回
清除 开锁 切换 开门
修改 modify_flag 返回rst 清除key12 //切换down_flag// 开锁up_flag 开门open_flag
//切换的功能跟返回大致相同
***********************************************************/
#include<reg52.h>
#include<intrins.h>
#include "delay.h" //delay.h最好放在最前面
#include "scan.h"
#include "1302.h"
#include "2402.h"
#include "1602.h"
#include "display.h"
#define uchar unsigned char
#define uint unsigned int
extern uchar key;
extern uchar temp,count,aa,bb,cc; /*一般将这些变量定义在C文件中
extern声明 不是定义 当主函数需要时用extern引用 */
extern bit shu_flag,modify_flag,rst;
extern bit fun_flag; //功能键标志位 没使用
extern bit down_flag,up_flag,open_flag;
uchar data lcd1602_line1[]={" 2014/08/02 000"};
uchar data lcd1602_line2[]={" 10:42:50 "};
uchar data time_data_buff[7]={0x50,0x42,0x10,0x02,0x08,0x06,0x14};
uchar code Weeks[][3]={{"SUN"},{"MON"},{"TUE"},{"WED"},{"THU"},{"FRI"},{"SAT"},{"SUN"}};
//二维数组 八行三列
bit mod_flag,rst_flag;
uchar code num_to_char[] = {"0123456789ABCDEF"};
uchar k,s,w;
bit return_flag=0;//切换时间页面标志位
bit sleep_flag;//进入掉电模式标志位
uchar m,l;
bit k_flag=0;
bit b_flag=0; //倒计时标志位
bit flag10; //保护标志位
bit flag3,flag4,flag2,flag1;
/*数字标志位 修改密码标志位 返还标志位 1 2 3 4 保护数据标志位,防重复写入*/
sbit beep=P2^3;
//sbit sda=P2^0; //IO口定义
//sbit scl=P2^1;
uchar code table[]={"Enter password:"};
uchar code table1[]={"Error!try again:"};
uchar code table2[]={"Welcome to China"};
uchar code table4[]={"Set password: "};
uchar code table5[]={"Input again: "};
uchar code table6[]={" Fuck you!!! "};
uchar code table7[]={" Get out!!!! "};
uchar code table8[]={" Set succed "};
uchar code table9[]={"Be patient..."};
uchar code table10[]={" Count down..."};
uchar code table12[]={"Please select "};
uchar code table13[]={"KEY10:For modify"};
uchar code table14[]={"KEY13:For open "};
uchar code table15[]={"Open the door"};
void T0_init()
{
TMOD=0x11;
TH0=(65536-46080)/256;// 由于晶振为11.0592,故所记次数应为46080,计时器每隔50000微秒发起一次中断。
TL0=(65536-46080)%256;//46080的来历,为50000*11.0592/12 50ms
TH1=(65536-46080)/256;
TL1=(65536-46080)%256;
EA=1;
ET0=1;// 定时器进入中断倒计时和进入睡眠
ET1=1;
TR1=1;
EX0=1;//外部中断用来唤醒睡眠
EX1=1;
}
void main(void)
{
uchar a[6],b[6],p[7],i,num;
uchar table3[6];//={1,1,1,1,1,1}; /*可将值赋予数组table3【】 可作变量使用*/
// uchar aa,bb,cc,dd,ee,ff;
lcd_init();
T0_init();
// write_at2404(10,0x00); /*初始化 之后屏蔽掉*/
// write_at2404(11,0x00); //否则每次上电密码都是000000
// write_at2404(12,0x00);
// write_at2404(13,0x00);
// write_at2404(14,0x00);
// write_at2404(15,0x00);
table3[0]=read_at2402(10);
table3[1]=read_at2402(11);
table3[2]=read_at2402(12);
table3[3]=read_at2402(13);
table3[4]=read_at2402(14);
table3[5]=read_at2402(15);
display();
set_real_time(time_data_buff);//设置时间 等效于set_real_time(&time_data_buff【0】)
while(1)
{
while(1)
{
down_flag=0;return_flag=0;
while(sleep_flag==1)
{
ET0=0;
ET1=0;
PCON=0X02;
while(sleep_flag); //0000 0010
}//
keyscan(); //数组p【7】等效于Curtime[7]
get_real_time(p);//读出时间 等效于get_real_time(&p【0】);
lcd1602_line1[3] = num_to_char[p[6]/0x10];
lcd1602_line1[4] = num_to_char[p[6]%0x10]; /*年*/
lcd1602_line1[6] = num_to_char[p[4]/0x10];
lcd1602_line1[7] = num_to_char[p[4]%0x10]; /*月*/
lcd1602_line1[9] = num_to_char[p[3]/0x10];
lcd1602_line1[10] = num_to_char[p[3]%0x10]; /*日*/
for(i=0;i<3;i++) lcd1602_line1[i+13]=Weeks[p[5]&0x07][i]; /*星期*/
lcd1602_line2[4] = num_to_char[p[2]/0x10];
lcd1602_line2[5] = num_to_char[p[2]%0x10]; /*时*/
lcd1602_line2[7] = num_to_char[p[1]/0x10];
lcd1602_line2[8] = num_to_char[p[1]%0x10]; /*分*/
lcd1602_line2[10] = num_to_char[p[0]/0x10];
lcd1602_line2[11] = num_to_char[p[0]%0x10]; /*秒*/
for(i=0;i<16;i++) wtite_lcd_1602_dat(i,0,lcd1602_line1[i]);
for(i=0;i<16;i++) wtite_lcd_1602_dat(i,1,lcd1602_line2[i]);
if(open_flag) break; //按下开门键 跳出while(1)读时间循环
}
/*无论是修改密码还是开门 之后都要对其成功之前或者
失败之前的标志位清零 否则导致二次扫描时不显示*/
while(1) //进入while(1)设置密码 循环
{
open_flag=0; //清零
// count=0;//
keyscan();
if(!flag3) //防止扫描重复写入 flag3
{
write_com(0x01);
write_com(0x0f);
write_com(0x80); //静态显示 定位光标 闪烁
for(i=0;i<15;i++)
write_data(table[i]);
write_com(0xc5);
flag3=1; //必须使用标志位保护起来 否则连续扫描闪烁 导致光标暗淡
}
if(num<=2) //
展开阅读全文