//主函数
#include <reg52.h> //用52头文件编程
#include <iic.h> //iic头文件
sfr P4=0xc0; //定义P4管脚
sbit C1=P3^0; //矩阵按键相关
sbit C2=P3^1;
sbit C3=P3^2;
sbit C4=P3^3;
sbit R1=P3^4;
sbit R2=P3^5;
sbit R3=P4^2;
sbit R4=P4^4;
unsigned char s16=0; //按键s16输入按键
unsigned char s12=0; //按键s12密码修改按键
unsigned char s8=0; //按键s8清除按键
unsigned char a1; //修改密码时的参数
unsigned char a2;
unsigned char a3;
unsigned char a4;
unsigned char a5;
unsigned char a6;
unsigned char b1=0; //
unsigned char b2=0; //输入完成的标志
unsigned char b3=0; //密码输入正确的标志
unsigned char b4=0; //密码输入错误的标志
unsigned char b5=0; //输入密码达到6位时的标志
unsigned char b6=0; //密码输入正确时,修改密码的标志
unsigned char c1=8; //读取上次存储密码第一位
unsigned char c2=8; //读取上次存储密码第二位
unsigned char c3=8; //读取上次存储密码第三位
unsigned char c4=8; //读取上次存储密码第四位
unsigned char c5=8; //读取上次存储密码第五位
unsigned char c6=8; //读取上次存储密码第六位
unsigned char c7; //首次上电的密码存储相关
unsigned char moshi=0; //显示的模式
unsigned char count_1; //中断计数
unsigned long mima=888888;
unsigned long mima_1=21; //密码第一位
unsigned long mima_2=21; //密码第二位
unsigned long mima_3=21; //密码第三位
unsigned long mima_4=21; //密码第四位
unsigned long mima_5=21; //密码第五位
unsigned long mima_6=21; //密码第六位
unsigned long mima_7=0; //密码错误时显示 原数
unsigned char num; //按键代表的数
unsigned char i; //选择第几位密码输入
unsigned char dat; //AT24C02写入的数据
unsigned char smg_buff[8]; //数码管缓存
unsigned char code SMG_Duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,
0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x7f,0x8c,0x86,0xc8,0xff};
//数码管段选0 1 2 3 4 5 6 7 8 9 a b c d e f - . P E N 关闭
void Read_mima();
void Delay(unsigned int t) //延时函数
{
while(t--);
}
void Init_system() //系统初始化函数
{
P2=(P2 & 0x1f)|0x80; //关闭LED灯
P0=0xff;
P2=(P2 & 0x1f)|0xa0; //关闭继电器和蜂鸣器
P0=0x00;
P2=0x00;
}
/
#include "reg52.h"
#include "intrins.h"
#define DELAY_TIME 5
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
sbit SDA = P2^1;
sbit SCL = P2^0;
void IIC_Delay(unsigned char i)
{
do{_nop_();}
while(i--);
}
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
IIC_Delay(DELAY_TIME);
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//发送应答
void IIC_SendAck(bit ackbit)
{
SCL = 0;
SDA = ackbit; // 0应答 1非应答
IIC_Delay(DELAY_TIME);
SCL = 1;
IIC_Delay(DELAY_TIME);
SCL = 0;
SDA = 1;
IIC_Delay(DELAY_TIME);
}
//等待应答
bit IIC_WaitAck(void)
{
bit ackbit;
SCL = 1;
IIC_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
IIC_Delay(DELAY_TIME);
return ackbit;
}
//通过iic发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++)
{
SCL = 0;
IIC_Delay(DELAY_TIME);
if(byt & 0x80) SDA = 1;
else SDA = 0;
IIC_Delay(DELAY_TIME);
SCL = 1;
byt <<= 1;
IIC_Delay(DELAY_TIME);
}
SCL = 0;
}
//从iic上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char i, da;
for(i=0; i<8; i++)
{
SCL = 1;
IIC_Delay(DELAY_TIME);
da <<= 1;
if(SDA) da |= 1;
SCL = 0;
IIC_Delay(DELAY_TIME);
}
return da;
}
#ifndef _IIC_H
#define _IIC_H
void IIC_Start(void);
void IIC_Stop(void);
bit IIC_WaitAck(void);
void IIC_SendAck(bit ackbit);
void IIC_SendByte(unsigned char byt);
unsigned char IIC_RecByte(void);
#endif
总结一下:我认为关键是首次写入的时候密码为888888,再次断电的时候仍让能用上次保存的密码而不是原始密码。因为AT24C02拥有掉电不丢失的特性,所以我认为不能每次从新上电都是原始密码888888。我的解决方法是在主函数里判断了AT24C02的第8个地址是否大于0,如果大于0那么就写入初始密码888888,新的开发版的第八个地址的数据基本上都是大于0的,如果没有初始化成功,需要修改两个地方。又不懂的地方欢迎留言。